UListIO.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-2016 OpenFOAM Foundation
9  Copyright (C) 2016-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 "UList.H"
30 #include "Ostream.H"
31 #include "token.H"
32 #include "SLList.H"
33 #include "contiguous.H"
34 
35 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
36 
37 template<class T>
39 {
40  if (size())
41  {
42  const word tag = "List<" + word(pTraits<T>::typeName) + '>';
43  if (token::compound::isCompound(tag))
44  {
45  os << tag << token::SPACE;
46  }
47  os << *this;
48  }
49  else if (os.format() == IOstream::ASCII)
50  {
51  // Zero-sized ASCII - Write size and delimiters
52  os << 0 << token::BEGIN_LIST << token::END_LIST;
53  }
54  else
55  {
56  // Zero-sized binary - Write size only
57  os << 0;
58  }
59 }
60 
61 
62 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
63 
64 template<class T>
65 void Foam::UList<T>::writeEntry(const word& keyword, Ostream& os) const
66 {
67  if (keyword.size())
68  {
69  os.writeKeyword(keyword);
70  }
71  writeEntry(os);
72  os << token::END_STATEMENT << endl;
73 }
74 
75 
76 template<class T>
78 (
79  Ostream& os,
80  const label shortLen
81 ) const
82 {
83  const UList<T>& list = *this;
84 
85  const label len = list.size();
86 
87  // Write list contents depending on data format
88  if (os.format() == IOstream::ASCII || !is_contiguous<T>::value)
89  {
90  if (len > 1 && is_contiguous<T>::value && list.uniform())
91  {
92  // Two or more entries, and all entries have identical values.
93  os << len << token::BEGIN_BLOCK << list[0] << token::END_BLOCK;
94  }
95  else if
96  (
97  (len <= 1 || !shortLen)
98  ||
99  (
100  (len <= shortLen)
101  &&
102  (
105  )
106  )
107  )
108  {
109  // Size and start delimiter
110  os << len << token::BEGIN_LIST;
111 
112  // Contents
113  for (label i=0; i < len; ++i)
114  {
115  if (i) os << token::SPACE;
116  os << list[i];
117  }
118 
119  // End delimiter
120  os << token::END_LIST;
121  }
122  else
123  {
124  // Size and start delimiter
125  os << nl << len << nl << token::BEGIN_LIST << nl;
126 
127  // Contents
128  for (label i=0; i < len; ++i)
129  {
130  os << list[i] << nl;
131  }
132 
133  // End delimiter
134  os << token::END_LIST << nl;
135  }
136  }
137  else
138  {
139  // Contents are binary and contiguous
140  os << nl << len << nl;
141 
142  if (len)
143  {
144  // write(...) includes surrounding start/end delimiters
145  os.write
146  (
147  reinterpret_cast<const char*>(list.cdata()),
148  list.byteSize()
149  );
150  }
151  }
152 
153  os.check(FUNCTION_NAME);
154  return os;
155 }
156 
157 
158 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
159 
160 template<class T>
162 {
163  // The target list length - must match with sizes read
164  const label len = list.size();
165 
167 
168  token firstToken(is);
169 
170  is.fatalCheck("operator>>(Istream&, UList<T>&) : reading first token");
171 
172  // Compound: simply transfer contents
173  if (firstToken.isCompound())
174  {
175  List<T> elems;
176  elems.transfer
177  (
179  (
180  firstToken.transferCompoundToken(is)
181  )
182  );
183 
184  const label inputLen = elems.size();
185 
186  // List lengths must match
187  if (inputLen != len)
188  {
190  << "incorrect length for UList. Read "
191  << inputLen << " expected " << len
192  << exit(FatalIOError);
193  }
194 
195  for (label i = 0; i < len; ++i)
196  {
197  list[i] = std::move(elems[i]);
198  }
199 
200  return is;
201  }
202 
203 
204  // Label: could be int(..), int{...} or just a plain '0'
205  if (firstToken.isLabel())
206  {
207  const label inputLen = firstToken.labelToken();
208 
209  // List lengths must match
210  if (inputLen != len)
211  {
213  << "incorrect length for UList. Read "
214  << inputLen << " expected " << len
215  << exit(FatalIOError);
216  }
217 
218  // Read list contents depending on data format
219 
220  if (is.format() == IOstream::ASCII || !is_contiguous<T>::value)
221  {
222  // Read beginning of contents
223  const char delimiter = is.readBeginList("List");
224 
225  if (len)
226  {
227  if (delimiter == token::BEGIN_LIST)
228  {
229  for (label i=0; i<len; ++i)
230  {
231  is >> list[i];
232 
233  is.fatalCheck
234  (
235  "operator>>(Istream&, UList<T>&) : reading entry"
236  );
237  }
238  }
239  else
240  {
241  // Uniform content (delimiter == token::BEGIN_BLOCK)
242 
243  T element;
244  is >> element;
245 
246  is.fatalCheck
247  (
248  "operator>>(Istream&, UList<T>&) : "
249  "reading the single entry"
250  );
251 
252  for (label i=0; i<len; ++i)
253  {
254  list[i] = element; // Copy the value
255  }
256  }
257  }
258 
259  // Read end of contents
260  is.readEndList("List");
261  }
262  else if (len)
263  {
264  // Non-empty, binary, contiguous
265 
266  Detail::readContiguous<T>
267  (
268  is,
269  reinterpret_cast<char*>(list.data()),
270  len*sizeof(T)
271  );
272 
273  is.fatalCheck
274  (
275  "operator>>(Istream&, UList<T>&) : reading the binary block"
276  );
277  }
278 
279  return is;
280  }
281 
282 
283  // "(...)" : read as SLList and transfer contents
284  if (firstToken.isPunctuation())
285  {
286  if (firstToken.pToken() != token::BEGIN_LIST)
287  {
289  << "incorrect first token, expected '(', found "
290  << firstToken.info()
291  << exit(FatalIOError);
292  }
293 
294  is.putBack(firstToken); // Putback the opening bracket
295 
296  SLList<T> sll(is); // Read as singly-linked list
297 
298  // List lengths must match
299  if (sll.size() != len)
300  {
302  << "incorrect length for UList. Read "
303  << sll.size() << " expected " << len
304  << exit(FatalIOError);
305  }
306 
307  // Move assign each list element
308  for (label i = 0; i < len; ++i)
309  {
310  list[i] = std::move(sll.removeHead());
311  }
312 
313  return is;
314  }
315 
316 
318  << "incorrect first token, expected <int> or '(', found "
319  << firstToken.info()
320  << exit(FatalIOError);
321 
322  return is;
323 }
324 
325 
326 // ************************************************************************* //
Foam::UList::writeList
Ostream & writeList(Ostream &os, const label shortLen=0) const
Write List, with line-breaks in ASCII when length exceeds shortLen.
Definition: UListIO.C:78
token.H
Foam::IOstream::fatalCheck
void fatalCheck(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:64
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::token::Compound
A templated class for holding compound tokens.
Definition: token.H:219
Foam::Istream::readBeginList
char readBeginList(const char *funcName)
Begin read of list data, starts with '(' or '{'.
Definition: Istream.C:146
Foam::UList::data
T * data()
Return a pointer to the first data element.
Definition: UListI.H:205
Foam::IOstreamOption::format
streamFormat format() const noexcept
Get the current stream format.
Definition: IOstreamOption.H:273
Foam::Istream::readEndList
char readEndList(const char *funcName)
End read of list data, ends with ')' or '}'.
Definition: Istream.C:167
Foam::FatalIOError
IOerror FatalIOError
Foam::operator>>
Istream & operator>>(Istream &, directionInfo &)
Definition: directionInfo.C:228
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:337
Foam::token
A token holds an item read from Istream.
Definition: token.H:69
Foam::UList::uniform
bool uniform() const
True if all entries have identical values, and list is non-empty.
Definition: UListI.H:146
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::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
Foam::List::transfer
void transfer(List< T > &list)
Definition: List.C:436
Foam::IOstream::check
virtual bool check(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:51
Foam::Ostream::write
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
Foam::Ostream::writeKeyword
virtual Ostream & writeKeyword(const keyType &kw)
Write the keyword followed by an appropriate indentation.
Definition: Ostream.C:57
T
const volScalarField & T
Definition: createFieldRefs.H:2
Foam::UList::writeEntry
void writeEntry(Ostream &os) const
Write the UList with its compound type.
Definition: UListIO.C:38
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Ostream.H
UList.H
Foam::nl
constexpr char nl
Definition: Ostream.H:372
Foam::Detail::ListPolicy::no_linebreak
Definition: ListPolicy.H:76
SLList.H
Non-intrusive singly-linked list.
contiguous.H
Foam::dynamicCast
To & dynamicCast(From &r)
Definition: typeInfo.H:88
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::pTraits
Traits class for primitives.
Definition: pTraits.H:52
Foam::Istream::putBack
void putBack(const token &tok)
Put back token.
Definition: Istream.C:53
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::UList::byteSize
std::streamsize byteSize() const
Definition: UList.C:185
Foam::UList::cdata
const T * cdata() const
Return a const pointer to the first data element.
Definition: UListI.H:198
FUNCTION_NAME
#define FUNCTION_NAME
Definition: messageStream.H:261
Foam::UList::size
void size(const label n) noexcept
Override size to be inconsistent with allocated storage.
Definition: UListI.H:360
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
Foam::is_contiguous
A template class to specify that a data type can be considered as being contiguous in memory.
Definition: contiguous.H:75