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-2021 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  const word tag("List<" + word(pTraits<T>::typeName) + '>');
41  if (token::compound::isCompound(tag))
42  {
43  os << tag << token::SPACE;
44  }
45 
46  if (size())
47  {
48  os << *this;
49  }
50  else if (os.format() == IOstream::ASCII)
51  {
52  // Zero-sized ASCII - Write size and delimiters
53  os << 0 << token::BEGIN_LIST << token::END_LIST;
54  }
55  else
56  {
57  // Zero-sized binary - Write size only
58  os << 0;
59  }
60 }
61 
62 
63 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
64 
65 template<class T>
66 void Foam::UList<T>::writeEntry(const word& keyword, Ostream& os) const
67 {
68  if (keyword.size())
69  {
70  os.writeKeyword(keyword);
71  }
72  writeEntry(os);
73  os << token::END_STATEMENT << endl;
74 }
75 
76 
77 template<class T>
79 (
80  Ostream& os,
81  const label shortLen
82 ) const
83 {
84  const UList<T>& list = *this;
85 
86  const label len = list.size();
87 
88  if (os.format() == IOstream::BINARY && is_contiguous<T>::value)
89  {
90  // Binary and contiguous
91 
92  os << nl << len << nl;
93 
94  if (len)
95  {
96  // write(...) includes surrounding start/end delimiters
97  os.write(list.cdata_bytes(), list.size_bytes());
98  }
99  }
100  else if (len > 1 && is_contiguous<T>::value && list.uniform())
101  {
102  // Two or more entries, and all entries have identical values.
103  os << len << token::BEGIN_BLOCK << list[0] << token::END_BLOCK;
104  }
105  else if
106  (
107  (len <= 1 || !shortLen)
108  ||
109  (
110  (len <= shortLen)
111  &&
112  (
115  )
116  )
117  )
118  {
119  // Single-line output
120 
121  // Size and start delimiter
122  os << len << token::BEGIN_LIST;
123 
124  // Contents
125  for (label i=0; i < len; ++i)
126  {
127  if (i) os << token::SPACE;
128  os << list[i];
129  }
130 
131  // End delimiter
132  os << token::END_LIST;
133  }
134  else
135  {
136  // Multi-line output
137 
138  // Size and start delimiter
139  os << nl << len << nl << token::BEGIN_LIST << nl;
140 
141  // Contents
142  for (label i=0; i < len; ++i)
143  {
144  os << list[i] << nl;
145  }
146 
147  // End delimiter
148  os << token::END_LIST << nl;
149  }
150 
151  os.check(FUNCTION_NAME);
152  return os;
153 }
154 
155 
156 template<class T>
158 {
159  UList<T>& list = *this;
160 
161  // The target list length - must match with sizes read
162  const label len = list.size();
163 
165 
166  token tok(is);
167 
168  is.fatalCheck("UList<T>::readList(Istream&) : reading first token");
169 
170  if (tok.isCompound())
171  {
172  // Compound: simply transfer contents
173 
174  List<T> elems;
175  elems.transfer
176  (
178  (
179  tok.transferCompoundToken(is)
180  )
181  );
182 
183  const label inputLen = elems.size();
184 
185  // List lengths must match
186  if (inputLen != len)
187  {
189  << "incorrect length for UList. Read "
190  << inputLen << " expected " << len
191  << exit(FatalIOError);
192  }
193 
194  for (label i = 0; i < len; ++i)
195  {
196  list[i] = std::move(elems[i]);
197  }
198  }
199  else if (tok.isLabel())
200  {
201  // Label: could be int(..), int{...} or just a plain '0'
202 
203  const label inputLen = tok.labelToken();
204 
205  // List lengths must match
206  if (inputLen != len)
207  {
209  << "incorrect length for UList. Read "
210  << inputLen << " expected " << len
211  << exit(FatalIOError);
212  }
213 
214  if (is.format() == IOstream::BINARY && is_contiguous<T>::value)
215  {
216  // Binary and contiguous
217 
218  if (len)
219  {
220  Detail::readContiguous<T>
221  (
222  is,
223  list.data_bytes(),
224  list.size_bytes()
225  );
226 
227  is.fatalCheck
228  (
229  "UList<T>::readList(Istream&) : "
230  "reading binary block"
231  );
232  }
233  }
234  else
235  {
236  // Begin of contents marker
237  const char delimiter = is.readBeginList("List");
238 
239  if (len)
240  {
241  if (delimiter == token::BEGIN_LIST)
242  {
243  for (label i=0; i<len; ++i)
244  {
245  is >> list[i];
246 
247  is.fatalCheck
248  (
249  "UList<T>::readList(Istream&) : "
250  "reading entry"
251  );
252  }
253  }
254  else
255  {
256  // Uniform content (delimiter == token::BEGIN_BLOCK)
257 
258  T elem;
259  is >> elem;
260 
261  is.fatalCheck
262  (
263  "UList<T>::readList(Istream&) : "
264  "reading the single entry"
265  );
266 
267  for (label i=0; i<len; ++i)
268  {
269  list[i] = elem; // Copy the value
270  }
271  }
272  }
273 
274  // End of contents marker
275  is.readEndList("List");
276  }
277  }
278  else if (tok.isPunctuation(token::BEGIN_LIST))
279  {
280  // "(...)" : read as SLList and transfer contents
281 
282  is.putBack(tok); // Putback the opening bracket
283  SLList<T> sll(is); // Read as singly-linked list
284 
285  // List lengths must match
286  if (sll.size() != len)
287  {
289  << "incorrect length for UList. Read "
290  << sll.size() << " expected " << len
291  << exit(FatalIOError);
292  }
293 
294  // Move assign each list element
295  for (label i = 0; i < len; ++i)
296  {
297  list[i] = std::move(sll.removeHead());
298  }
299  }
300  else
301  {
303  << "incorrect first token, expected <int> or '(', found "
304  << tok.info() << nl
305  << exit(FatalIOError);
306  }
307 
308  return is;
309 }
310 
311 
312 // ************************************************************************* //
Foam::UList::cdata_bytes
const char * cdata_bytes() const noexcept
Return pointer to the underlying array serving as data storage,.
Definition: UListI.H:244
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:79
token.H
Foam::token::labelToken
label labelToken() const
Return label value.
Definition: tokenI.H:513
Foam::token::isLabel
bool isLabel() const noexcept
Token is LABEL.
Definition: tokenI.H:497
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::token::Compound
A templated class for holding compound tokens.
Definition: token.H:246
Foam::Istream::readBeginList
char readBeginList(const char *funcName)
Begin read of list data, starts with '(' or '{'.
Definition: Istream.C:148
Foam::IOstream::fatalCheck
bool fatalCheck(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:64
Foam::IOstreamOption::format
streamFormat format() const noexcept
Get the current stream format.
Definition: IOstreamOption.H:286
Foam::Istream::readEndList
char readEndList(const char *funcName)
End read of list data, ends with ')' or '}'.
Definition: Istream.C:169
Foam::FatalIOError
IOerror FatalIOError
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::token
A token holds an item read from Istream.
Definition: token.H:68
Foam::UList::uniform
bool uniform() const
True if all entries have identical values, and list is non-empty.
Definition: UListI.H:178
Foam::UList::data_bytes
char * data_bytes() noexcept
Return pointer to the underlying array serving as data storage,.
Definition: UListI.H:251
Foam::LList
Template class for non-intrusive linked lists.
Definition: LList.H:54
Foam::token::info
InfoProxy< token > info() const
Return info proxy for printing token information to a stream.
Definition: token.H:586
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:456
Foam::token::isPunctuation
bool isPunctuation() const noexcept
Token is PUNCTUATION.
Definition: tokenI.H:459
Foam::UList::readList
Istream & readList(Istream &is)
Read List contents from Istream.
Definition: UListIO.C:157
os
OBJstream os(runTime.globalPath()/outputName)
T
const volScalarField & T
Definition: createFieldRefs.H:2
Foam::token::transferCompoundToken
compound & transferCompoundToken()
Return reference to compound and mark internally as released.
Definition: token.C:90
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:404
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: BitOps.H:63
Foam::pTraits
A traits class, which is primarily used for primitives.
Definition: pTraits.H:56
Foam::Istream::putBack
void putBack(const token &tok)
Put back a token. Only a single put back is permitted.
Definition: Istream.C:70
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
FUNCTION_NAME
#define FUNCTION_NAME
Definition: messageStream.H:295
Foam::token::isCompound
bool isCompound() const noexcept
Token is COMPOUND.
Definition: tokenI.H:716
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
Foam::UList::size
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::UList::size_bytes
std::streamsize size_bytes() const noexcept
Number of contiguous bytes for the List data.
Definition: UListI.H:258
Foam::LList::removeHead
T removeHead()
Remove and return head.
Definition: LList.H:250
Foam::is_contiguous
A template class to specify that a data type can be considered as being contiguous in memory.
Definition: contiguous.H:75