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-------------------------------------------------------------------------------
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#include "SLList.H"
33#include "contiguous.H"
34
35// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
36
37template<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
65template<class T>
66void 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
77template<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 )
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
156template<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 (
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// ************************************************************************* //
Non-intrusive singly-linked list.
streamFormat format() const noexcept
Get the current stream format.
bool fatalCheck(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:64
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:64
char readEndList(const char *funcName)
End read of list data, ends with ')' or '}'.
Definition: Istream.C:169
char readBeginList(const char *funcName)
Begin read of list data, starts with '(' or '{'.
Definition: Istream.C:148
void putBack(const token &tok)
Put back a token. Only a single put back is permitted.
Definition: Istream.C:70
Template class for non-intrusive linked lists.
Definition: LList.H:79
T removeHead()
Remove and return first entry.
Definition: LList.H:265
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:77
void transfer(List< T > &list)
Definition: List.C:447
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:62
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:94
char * data_bytes() noexcept
Return pointer to the underlying array serving as data storage,.
Definition: UListI.H:251
bool uniform() const
True if all entries have identical values, and list is non-empty.
Definition: UListI.H:178
const char * cdata_bytes() const noexcept
Return pointer to the underlying array serving as data storage,.
Definition: UListI.H:244
void writeEntry(Ostream &os) const
Write the UList with its compound type.
Definition: UListIO.C:38
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
Ostream & writeList(Ostream &os, const label shortLen=0) const
Write List, with line-breaks in ASCII when length exceeds shortLen.
Definition: UListIO.C:79
Istream & readList(Istream &is)
Read List contents from Istream.
Definition: UListIO.C:157
std::streamsize size_bytes() const noexcept
Number of contiguous bytes for the List data.
Definition: UListI.H:258
A traits class, which is primarily used for primitives.
Definition: pTraits.H:59
A templated class for holding compound tokens.
Definition: token.H:250
A token holds an item read from Istream.
Definition: token.H:69
compound & transferCompoundToken()
Return reference to compound and mark internally as released.
Definition: token.C:90
bool isPunctuation() const noexcept
Token is PUNCTUATION.
Definition: tokenI.H:459
bool isLabel() const noexcept
Token is LABEL.
Definition: tokenI.H:497
label labelToken() const
Return label value.
Definition: tokenI.H:513
InfoProxy< token > info() const
Return info proxy for printing token information to a stream.
Definition: token.H:586
bool isCompound() const noexcept
Token is COMPOUND.
Definition: tokenI.H:716
A class for handling words, derived from Foam::string.
Definition: word.H:68
const volScalarField & T
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
OBJstream os(runTime.globalPath()/outputName)
#define FUNCTION_NAME
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
IOerror FatalIOError
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
To & dynamicCast(From &r)
Definition: typeInfo.H:88
A template class to specify that a data type can be considered as being contiguous in memory.
Definition: contiguous.H:78