Loading...
Searching...
No Matches
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-2025 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
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
33// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
34
35template<class T>
37{
38 if constexpr (std::is_same_v<char, std::remove_cv_t<T>>)
39 {
40 // Char data has a compound type:
41 os << word("List<char>");
42
43 if (this->size())
44 {
45 // Non-zero size: write as binary, so has leading newline separator.
46 os << *this;
47 }
48 else
49 {
50 // Zero-sized binary - Write size only
51 // Note that char data is always binary I/O only
52 os << token::SPACE << label(0);
53 }
54 }
55 else
56 {
57 const word tag("List<" + word(pTraits<T>::typeName) + '>');
59 {
60 os << tag << token::SPACE;
61 }
62
63 if (size())
64 {
65 os << *this;
66 }
67 else if (os.format() == IOstreamOption::BINARY)
68 {
69 // Zero-sized binary - Write size only
70 os << label(0);
71 }
72 else
73 {
74 // Zero-sized ASCII - Write size and delimiters
75 os << label(0) << token::BEGIN_LIST << token::END_LIST;
76 }
77 }
78}
79
80
81// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
82
83template<class T>
84void Foam::UList<T>::writeEntry(const word& keyword, Ostream& os) const
85{
86 if (keyword.size())
87 {
88 os.writeKeyword(keyword);
89 }
90 writeEntry(os);
91 os.endEntry();
92}
93
94
95template<class T>
97(
98 Ostream& os,
99 const label shortLen
100) const
101{
102 const UList<T>& list = *this;
103
104 const label len = list.size();
105
106 if constexpr (std::is_same_v<char, std::remove_cv_t<T>>)
107 {
108 // Special treatment for char data (binary I/O only)
109
110 const auto oldFmt = os.format(IOstreamOption::BINARY);
111 os << nl << len << nl;
112
113 if (len)
114 {
115 // write(...) includes surrounding start/end delimiters
116 os.write(list.cdata_bytes(), list.size_bytes());
117 }
118
119 os.format(oldFmt);
120 }
121 else
122 {
124 {
125 // Binary and contiguous
126
127 os << nl << len << nl;
128
129 if (len)
130 {
131 // write(...) includes surrounding start/end delimiters
132 os.write(list.cdata_bytes(), list.size_bytes());
133 }
134 }
135 else if (is_contiguous_v<T> && len > 1 && list.uniform())
136 {
137 // Two or more entries, and all entries have identical values.
138 os << len << token::BEGIN_BLOCK << list[0] << token::END_BLOCK;
139 }
140 else if
141 (
142 (len <= 1 || !shortLen)
143 ||
144 (
145 (len <= shortLen)
146 && (is_contiguous_v<T> || Foam::ListPolicy::no_linebreak<T>::value)
147 )
148 )
149 {
150 // Single-line output
151
152 // Size and start delimiter
153 os << len << token::BEGIN_LIST;
154
155 auto iter = list.cbegin();
156 const auto last = list.cend();
157
158 // Contents
159 if (iter != last)
160 {
161 os << *iter;
162
163 for (++iter; (iter != last); (void)++iter)
164 {
165 os << token::SPACE << *iter;
166 }
167 }
168
169 // End delimiter
170 os << token::END_LIST;
171 }
172 else
173 {
174 // Multi-line output
175
176 // Size and start delimiter
177 os << nl << len << nl << token::BEGIN_LIST;
178
179 auto iter = list.cbegin();
180 const auto last = list.cend();
181
182 // Contents
183 for (/*nil*/; (iter != last); (void)++iter)
184 {
185 os << nl << *iter;
186 }
187
188 // End delimiter
189 os << nl << token::END_LIST << nl;
190 }
191 }
193 os.check(FUNCTION_NAME);
194 return os;
195}
196
197
198template<class T>
200{
201 UList<T>& list = *this;
202
203 // The target list length - must match with sizes read
204 const label len = list.size();
205
207
208 token tok(is);
209
210 is.fatalCheck("UList<T>::readList(Istream&) : reading first token");
211
212 if (tok.isCompound())
213 {
214 // Compound: simply transfer contents
215
216 List<T> elems;
217 elems.transfer
218 (
220 );
221
222 const label inputLen = elems.size();
223
224 // List lengths must match
225 if (inputLen != len)
226 {
228 << "incorrect length for UList. Read "
229 << inputLen << " expected " << len
230 << exit(FatalIOError);
231 }
232
233 std::move(elems.begin(), elems.end(), list.begin());
234 }
235 else if (tok.isLabel())
236 {
237 // Label: could be int(..), int{...} or just a plain '0'
238
239 const label inputLen = tok.labelToken();
240
241 // List lengths must match
242 if (inputLen != len)
243 {
245 << "incorrect length for UList. Read "
246 << inputLen << " expected " << len
247 << exit(FatalIOError);
248 }
249
250 else if constexpr (std::is_same_v<char, std::remove_cv_t<T>>)
251 {
252 // Special treatment for char data (binary I/O only)
253 const auto oldFmt = is.format(IOstreamOption::BINARY);
254
255 if (len)
256 {
257 // read(...) includes surrounding start/end delimiters
258 is.read(list.data_bytes(), list.size_bytes());
259
260 is.fatalCheck
261 (
262 "UList<char>::readList(Istream&) : [binary block]"
263 );
264 }
265
266 is.format(oldFmt);
267 }
268 else
269 {
270 if (is.format() == IOstreamOption::BINARY && is_contiguous_v<T>)
271 {
272 // Binary and contiguous
273
274 if (len)
275 {
276 Detail::readContiguous<T>
277 (
278 is,
279 list.data_bytes(),
280 list.size_bytes()
281 );
282
283 is.fatalCheck
284 (
285 "UList<T>::readList(Istream&) : [binary block]"
286 );
287 }
288 }
289 else
290 {
291 // Begin of contents marker
292 const char delimiter = is.readBeginList("List");
293
294 if (len)
295 {
296 if (delimiter == token::BEGIN_LIST)
297 {
298 for (label i=0; i<len; ++i)
299 {
300 is >> list[i];
301
302 is.fatalCheck
303 (
304 "UList<T>::readList(Istream&) : "
305 "reading entry"
306 );
307 }
308 }
309 else
310 {
311 // Uniform content (delimiter == token::BEGIN_BLOCK)
312
313 T elem;
314 is >> elem;
315
316 is.fatalCheck
317 (
318 "UList<T>::readList(Istream&) : "
319 "reading the single entry"
320 );
321
322 // Fill with the value
323 this->fill_uniform(elem);
324 }
325 }
326
327 // End of contents marker
328 is.readEndList("List");
329 }
330 }
331 }
332 else if (tok.isPunctuation(token::BEGIN_LIST))
333 {
334 // "(...)" : read into list, handling size-mismatch after
335
336 is >> tok;
338
339 label inputLen = 0;
340
341 while (!tok.isPunctuation(token::END_LIST))
342 {
343 is.putBack(tok);
344 if (inputLen < len)
345 {
346 is >> list[inputLen];
347 }
348 else
349 {
350 // Read and discard
351 T dummy;
352 is >> dummy;
353 }
354 ++inputLen;
355
356 is.fatalCheck
357 (
358 "UList<T>::readList(Istream&) : "
359 "reading entry"
360 );
361
362 is >> tok;
364 }
365
366 // List lengths must match
367 if (inputLen != len)
368 {
370 << "incorrect length for UList. Read "
371 << inputLen << " expected " << len
372 << exit(FatalIOError);
373 }
374 }
375 else
376 {
378 << "incorrect first token, expected <int> or '(', found "
379 << tok.info() << nl
380 << exit(FatalIOError);
381 }
382
383 return is;
384}
385
386
387// ************************************************************************* //
streamFormat format() const noexcept
Get the current stream format.
bool fatalCheck(const char *operation) const
Check IOstream status for given operation.
Definition IOstream.C:51
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition Istream.H:60
char readEndList(const char *funcName)
End read of list data, ends with ')' or '}'.
Definition Istream.C:192
char readBeginList(const char *funcName)
Begin read of list data, starts with '(' or '{'.
Definition Istream.C:171
void putBack(const token &tok)
Put back a token (copy). Only a single put back is permitted.
Definition Istream.C:71
virtual Istream & read(token &)=0
Return next token from stream.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition List.H:72
void transfer(List< T > &list)
Transfer the contents of the argument List into this list and annul the argument list.
Definition List.C:347
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition Ostream.H:59
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition UList.H:89
void fill_uniform(const T &val)
Assign all entries to the given value.
Definition UListI.H:46
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition UListI.H:410
char * data_bytes() noexcept
Return pointer to the underlying array serving as data storage,.
Definition UListI.H:288
UList(const UList< T > &) noexcept=default
Copy construct, shallow copy.
iterator end() noexcept
Return an iterator to end traversing the UList.
Definition UListI.H:454
const_iterator cend() const noexcept
Return const_iterator to end traversing the constant UList.
Definition UListI.H:468
const_iterator cbegin() const noexcept
Return const_iterator to begin traversing the constant UList.
Definition UListI.H:424
bool uniform() const
True if all entries have identical values, and list is non-empty.
Definition UListI.H:217
const char * cdata_bytes() const noexcept
Return pointer to the underlying array serving as data storage,.
Definition UListI.H:281
void writeEntry(Ostream &os) const
Write the UList with its compound type.
Definition UListIO.C:29
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
Ostream & writeList(Ostream &os, const label shortLen=0) const
Write List, with line-breaks in ASCII when length exceeds shortLen.
Definition UListIO.C:90
Istream & readList(Istream &is)
Read List contents from Istream.
Definition UListIO.C:192
std::streamsize size_bytes() const noexcept
Number of contiguous bytes for the List data.
Definition UListI.H:295
A traits class, which is primarily used for primitives and vector-space.
Definition pTraits.H:64
static bool isCompound(const word &compoundType)
True if a known (registered) compound type.
Definition token.C:104
A token holds an item read from Istream.
Definition token.H:70
bool isPunctuation() const noexcept
Token is PUNCTUATION.
Definition tokenI.H:650
@ BEGIN_BLOCK
Begin block [isseparator].
Definition token.H:178
@ END_BLOCK
End block [isseparator].
Definition token.H:179
@ BEGIN_LIST
Begin list [isseparator].
Definition token.H:174
@ END_LIST
End list [isseparator].
Definition token.H:175
@ SPACE
Space [isspace].
Definition token.H:144
bool isLabel() const noexcept
Integral token is convertible to Foam::label.
Definition tokenI.H:843
label labelToken() const
Return integer type as label value or Error.
Definition tokenI.H:869
compound & transferCompoundToken(const Istream *is=nullptr)
Return reference to compound and mark internally as released.
Definition token.C:157
bool isCompound() const noexcept
Token is COMPOUND.
Definition tokenI.H:1096
InfoProxy< token > info() const noexcept
Return info proxy, for printing token information to a stream.
Definition token.H:1253
A class for handling words, derived from Foam::string.
Definition word.H:66
const volScalarField & T
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition error.H:629
OBJstream os(runTime.globalPath()/outputName)
#define FUNCTION_NAME
void readContiguous(Istream &is, char *data, std::streamsize byteCount)
Read binary block of contiguous data, possibly with conversion.
Definition Istream.H:322
IOerror FatalIOError
Error stream (stdout output on all processes), with additional 'FOAM FATAL IO ERROR' header text and ...
constexpr bool is_contiguous_v
The is_contiguous value of Type (after stripping of qualifiers).
Definition contiguous.H:77
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition errorManip.H:125
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
Can suppress additional line breaks separate ASCII data content when the data elements are primitives...
Definition ListPolicy.H:74