CompactIOList.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2017 OpenFOAM Foundation
9  Copyright (C) 2015-2019 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "CompactIOList.H"
30 #include "labelList.H"
31 
32 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
33 
34 template<class T, class BaseType>
36 {
37  Istream& is = readStream(word::null);
38 
39  if (headerClassName() == IOList<T>::typeName)
40  {
41  is >> static_cast<List<T>&>(*this);
42  close();
43  }
44  else if (headerClassName() == typeName)
45  {
46  is >> *this;
47  close();
48  }
49  else
50  {
52  << "unexpected class name " << headerClassName()
53  << " expected " << typeName << " or " << IOList<T>::typeName
54  << endl
55  << " while reading object " << name()
56  << exit(FatalIOError);
57  }
58 }
59 
60 
61 template<class T, class BaseType>
63 {
64  label size = 0;
65  forAll(*this, i)
66  {
67  const label oldSize = size;
68  size += this->operator[](i).size();
69  if (size < oldSize)
70  {
71  return true;
72  }
73  }
74  return false;
75 }
76 
77 
78 // * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
79 
80 template<class T, class BaseType>
82 :
83  regIOobject(io)
84 {
85  if
86  (
87  io.readOpt() == IOobject::MUST_READ
88  || (io.readOpt() == IOobject::READ_IF_PRESENT && headerOk())
89  )
90  {
91  readFromStream();
92  }
93 }
94 
95 
96 template<class T, class BaseType>
98 (
99  const IOobject& io,
100  const label len
101 )
102 :
103  regIOobject(io)
104 {
105  if
106  (
107  io.readOpt() == IOobject::MUST_READ
108  || (io.readOpt() == IOobject::READ_IF_PRESENT && headerOk())
109  )
110  {
111  readFromStream();
112  }
113  else
114  {
115  List<T>::setSize(len);
116  }
117 }
118 
119 
120 template<class T, class BaseType>
122 (
123  const IOobject& io,
124  const UList<T>& content
125 )
126 :
127  regIOobject(io)
128 {
129  if
130  (
131  io.readOpt() == IOobject::MUST_READ
132  || (io.readOpt() == IOobject::READ_IF_PRESENT && headerOk())
133  )
134  {
135  readFromStream();
136  }
137  else
138  {
139  List<T>::operator=(content);
140  }
141 }
142 
143 
144 template<class T, class BaseType>
146 (
147  const IOobject& io,
148  List<T>&& content
149 )
150 :
151  regIOobject(io)
152 {
153  List<T>::transfer(content);
154 
155  if
156  (
157  io.readOpt() == IOobject::MUST_READ
158  || (io.readOpt() == IOobject::READ_IF_PRESENT && headerOk())
159  )
160  {
161  readFromStream();
162  }
163 }
164 
165 
166 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
167 
168 template<class T, class BaseType>
170 (
174  const bool valid
175 ) const
176 {
177  bool nonCompact = false;
178 
179  if (fmt == IOstream::ASCII)
180  {
181  nonCompact = true;
182  }
183  else if (overflows())
184  {
185  nonCompact = true;
186 
188  << "Overall number of elements of CompactIOList of size "
189  << this->size() << " overflows the representation of a label"
190  << nl << " Switching to ascii writing" << endl;
191  }
192 
193  if (nonCompact)
194  {
195  // Change to non-compact type
196  const word oldTypeName(typeName);
197 
198  const_cast<word&>(typeName) = IOList<T>::typeName;
199 
200  bool good = regIOobject::writeObject(IOstream::ASCII, ver, cmp, valid);
201 
202  // Change type back
203  const_cast<word&>(typeName) = oldTypeName;
204 
205  return good;
206  }
207 
208  return regIOobject::writeObject(fmt, ver, cmp, valid);
209 }
210 
211 
212 template<class T, class BaseType>
214 {
215  return (os << *this).good();
216 }
217 
218 
219 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
220 
221 template<class T, class BaseType>
223 (
224  const CompactIOList<T, BaseType>& rhs
225 )
226 {
227  List<T>::operator=(rhs);
228 }
229 
230 
231 // * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
232 
233 template<class T, class BaseType>
234 Foam::Istream& Foam::operator>>
235 (
236  Foam::Istream& is,
238 )
239 {
240  // Read compact
241  const labelList start(is);
242  const List<BaseType> elems(is);
243 
244  // Convert
245  L.setSize(start.size()-1);
246 
247  forAll(L, i)
248  {
249  T& subList = L[i];
250 
251  label index = start[i];
252  subList.setSize(start[i+1] - index);
253 
254  forAll(subList, j)
255  {
256  subList[j] = elems[index++];
257  }
258  }
259 
260  return is;
261 }
262 
263 
264 template<class T, class BaseType>
265 Foam::Ostream& Foam::operator<<
266 (
267  Foam::Ostream& os,
269 )
270 {
271  // Keep ascii writing same.
272  if (os.format() == IOstream::ASCII)
273  {
274  os << static_cast<const List<T>&>(L);
275  }
276  else
277  {
278  // Convert to compact format
279  labelList start(L.size()+1);
280 
281  start[0] = 0;
282  for (label i = 1; i < start.size(); i++)
283  {
284  const label prev = start[i-1];
285  start[i] = prev+L[i-1].size();
286 
287  if (start[i] < prev)
288  {
290  << "Overall number of elements " << start[i]
291  << " of CompactIOList of size "
292  << L.size() << " overflows the representation of a label"
293  << endl << "Please recompile with a larger representation"
294  << " for label" << exit(FatalIOError);
295  }
296  }
297 
298  List<BaseType> elems(start[start.size()-1]);
299 
300  label elemI = 0;
301  forAll(L, i)
302  {
303  const T& subList = L[i];
304 
305  forAll(subList, j)
306  {
307  elems[elemI++] = subList[j];
308  }
309  }
310  os << start << elems;
311  }
312 
313  return os;
314 }
315 
316 
317 // ************************************************************************* //
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:74
setSize
points setSize(newPointi)
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:104
L
const vector L(dict.get< vector >("L"))
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::FatalIOError
IOerror FatalIOError
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:337
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:290
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:62
Foam::IOstreamOption::versionNumber
Representation of a major/minor version number.
Definition: IOstreamOption.H:79
labelList.H
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
Foam::name
word name(const complex &c)
Return string representation of complex.
Definition: complex.C:76
Foam::CompactIOList::CompactIOList
CompactIOList(const CompactIOList &)=default
Default copy construct.
Foam::CompactIOList::writeObject
virtual bool writeObject(IOstream::streamFormat, IOstream::versionNumber, IOstream::compressionType, const bool valid) const
Definition: CompactIOList.C:170
Foam::CompactIOList
A List of objects of type <T> with automated input and output using a compact storage....
Definition: CompactIOList.H:55
Foam::CompactIOList::writeData
virtual bool writeData(Ostream &) const
Definition: CompactIOList.C:213
Foam::IOstreamOption::streamFormat
streamFormat
Data format (ascii | binary)
Definition: IOstreamOption.H:64
T
const volScalarField & T
Definition: createFieldRefs.H:2
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::regIOobject
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:67
Foam::nl
constexpr char nl
Definition: Ostream.H:372
CompactIOList.H
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:102
Foam::IOobject::readOpt
readOption readOpt() const
The read option.
Definition: IOobjectI.H:141
Foam::start
label ListType::const_reference const label start
Definition: ListOps.H:408
Foam::UList
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:103
Foam::IOList
A List of objects of type <T> with automated input and output.
Definition: IOList.H:53
Foam::IOstreamOption::compressionType
compressionType
Compression treatment (UNCOMPRESSED | COMPRESSED)
Definition: IOstreamOption.H:71
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:375
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:294