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-2020 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 (
171  IOstreamOption streamOpt,
172  const bool valid
173 ) const
174 {
175  if
176  (
177  streamOpt.format() == IOstream::BINARY
178  && overflows()
179  )
180  {
181  streamOpt.format(IOstream::ASCII);
182 
184  << "Overall number of elements of CompactIOList of size "
185  << this->size() << " overflows the representation of a label"
186  << nl << " Switching to ascii writing" << endl;
187  }
188 
189  if (streamOpt.format() == IOstream::ASCII)
190  {
191  // Change type to be non-compact format type
192  const word oldTypeName(typeName);
193 
194  const_cast<word&>(typeName) = IOList<T>::typeName;
195 
196  bool good = regIOobject::writeObject(streamOpt, valid);
197 
198  // Change type back
199  const_cast<word&>(typeName) = oldTypeName;
200 
201  return good;
202  }
203 
204  return regIOobject::writeObject(streamOpt, valid);
205 }
206 
207 
208 template<class T, class BaseType>
210 {
211  return (os << *this).good();
212 }
213 
214 
215 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
216 
217 template<class T, class BaseType>
219 (
220  const CompactIOList<T, BaseType>& rhs
221 )
222 {
223  List<T>::operator=(rhs);
224 }
225 
226 
227 // * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
228 
229 template<class T, class BaseType>
230 Foam::Istream& Foam::operator>>
231 (
232  Foam::Istream& is,
234 )
235 {
236  // Read compact
237  const labelList start(is);
238  const List<BaseType> elems(is);
239 
240  // Convert
241  L.setSize(start.size()-1);
242 
243  forAll(L, i)
244  {
245  T& subList = L[i];
246 
247  label index = start[i];
248  subList.setSize(start[i+1] - index);
249 
250  forAll(subList, j)
251  {
252  subList[j] = elems[index++];
253  }
254  }
255 
256  return is;
257 }
258 
259 
260 template<class T, class BaseType>
261 Foam::Ostream& Foam::operator<<
262 (
263  Foam::Ostream& os,
265 )
266 {
267  // Keep ascii writing same.
268  if (os.format() == IOstream::ASCII)
269  {
270  os << static_cast<const List<T>&>(L);
271  }
272  else
273  {
274  // Convert to compact format
275  labelList start(L.size()+1);
276 
277  start[0] = 0;
278  for (label i = 1; i < start.size(); i++)
279  {
280  const label prev = start[i-1];
281  start[i] = prev+L[i-1].size();
282 
283  if (start[i] < prev)
284  {
286  << "Overall number of elements " << start[i]
287  << " of CompactIOList of size "
288  << L.size() << " overflows the representation of a label"
289  << endl << "Please recompile with a larger representation"
290  << " for label" << exit(FatalIOError);
291  }
292  }
293 
294  List<BaseType> elems(start[start.size()-1]);
295 
296  label elemI = 0;
297  forAll(L, i)
298  {
299  const T& subList = L[i];
300 
301  forAll(subList, j)
302  {
303  elems[elemI++] = subList[j];
304  }
305  }
306  os << start << elems;
307  }
308 
309  return os;
310 }
311 
312 
313 // ************************************************************************* //
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:67
setSize
points setSize(newPointi)
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:169
L
const vector L(dict.get< vector >("L"))
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::IOstreamOption::format
streamFormat format() const noexcept
Get the current stream format.
Definition: IOstreamOption.H:286
Foam::FatalIOError
IOerror FatalIOError
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
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::IOstreamOption
The IOstreamOption is a simple container for options an IOstream can normally have.
Definition: IOstreamOption.H:63
Foam::CompactIOList::CompactIOList
CompactIOList(const CompactIOList &)=default
Default copy construct.
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:209
os
OBJstream os(runTime.globalPath()/outputName)
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::IOobject::readOpt
readOption readOpt() const noexcept
The read option.
Definition: IOobjectI.H:164
Foam::CompactIOList::writeObject
virtual bool writeObject(IOstreamOption streamOpt, const bool valid) const
Write using stream options. Checks for overflow in binary.
Definition: CompactIOList.C:170
Foam::regIOobject
regIOobject is an abstract class derived from IOobject to handle automatic object registration with t...
Definition: regIOobject.H:73
Foam::nl
constexpr char nl
Definition: Ostream.H:404
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: BitOps.H:63
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::name
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
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:328