Loading...
Searching...
No Matches
ListIO.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) 2018-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 "List.H"
30#include "Istream.H"
31#include "token.H"
32
33// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
34
35template<class T>
37:
38 UList<T>()
39{
40 this->readList(is);
41}
42
43
44// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
45
46template<class T>
47bool Foam::List<T>::readBracketList(Istream& is)
48{
49 List<T>& list = *this;
50
52
53 token tok(is);
54
55 is.fatalCheck
56 (
57 "List<T>::readBracketList(Istream&) : reading first token"
58 );
59
60 if (!tok.isPunctuation(token::BEGIN_LIST))
61 {
62 is.putBack(tok);
63 return false;
64 }
65
66 {
67 // "(...)" : read element-wise.
68 // Uses chunk-wise reading to avoid too many re-allocations
69 // and avoids relocation of contiguous memory until all of the reading
70 // is completed. Chunks are wrapped as unique_ptr to ensure proper
71 // cleanup on failure.
72
73 // The choice of chunk-size is somewhat arbitrary...
74 constexpr label chunkSize = 128;
75 typedef std::unique_ptr<List<T>> chunkType;
76
77 is >> tok;
79
80 if (tok.isPunctuation(token::END_LIST))
81 {
82 // Trivial case, an empty list
83 list.clear();
84 return true;
85 }
86
87 // Use all storage
88 list.resize(list.capacity());
89
90 // Start with a few slots, recover current memory where possible
91 List<chunkType> chunks(16);
92 if (list.empty())
93 {
94 chunks[0] = chunkType(new List<T>(chunkSize));
95 }
96 else
97 {
98 chunks[0] = chunkType(new List<T>(std::move(list)));
99 }
100
101 label nChunks = 1; // Active number of chunks
102 label totalCount = 0; // Total number of elements
103 label localIndex = 0; // Chunk-local index
104
105 while (!tok.isPunctuation(token::END_LIST))
106 {
107 is.putBack(tok);
108
109 if (chunks[nChunks-1]->size() <= localIndex)
110 {
111 // Increase number of slots (doubling)
112 if (nChunks >= chunks.size())
113 {
114 chunks.resize(2*chunks.size());
115 }
116
117 chunks[nChunks] = chunkType(new List<T>(chunkSize));
118 ++nChunks;
119 localIndex = 0;
120 }
121
122 is >> chunks[nChunks-1]->operator[](localIndex);
123 ++localIndex;
124 ++totalCount;
125
126 is.fatalCheck
127 (
128 "List<T>::readBracketList(Istream&) : "
129 "reading entry"
130 );
131
132 is >> tok;
134 }
135
136 // Simple case
137 if (nChunks == 1)
138 {
139 list = std::move(*(chunks[0]));
140 list.resize(totalCount);
141 return true;
142 }
143
144 // Destination
145 list.setCapacity_nocopy(totalCount);
146 list.resize_nocopy(totalCount);
147 auto dest = list.begin();
148
149 for (label chunki = 0; chunki < nChunks; ++chunki)
150 {
151 List<T> currChunk(std::move(*(chunks[chunki])));
152 chunks[chunki].reset(nullptr);
153
154 const label localLen = Foam::min(currChunk.size(), totalCount);
155
156 dest = std::move
157 (
158 currChunk.begin(),
159 currChunk.begin(localLen),
160 dest
161 );
162
163 totalCount -= localLen;
164 }
165 }
166
167 return true;
168}
169
170
171// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
172
173template<class T>
175{
176 List<T>& list = *this;
177
179
180 token tok(is);
181
182 is.fatalCheck("List<T>::readList(Istream&) : reading first token");
183
184 if (tok.isCompound())
185 {
186 // Compound: simply transfer contents
187
188 list.clear(); // Clear old contents
189 list.transfer
190 (
192 );
193 }
194 else if (tok.isLabel())
195 {
196 // Label: could be int(..), int{...} or just a plain '0'
197
198 const label len = tok.labelToken();
199
200 // Resize to length required
201 list.resize_nocopy(len);
202
203 if constexpr (std::is_same_v<char, std::remove_cv_t<T>>)
204 {
205 // Special treatment for char data (binary I/O only)
206 const auto oldFmt = is.format(IOstreamOption::BINARY);
207
208 if (len)
209 {
210 // read(...) includes surrounding start/end delimiters
211 is.read(list.data_bytes(), list.size_bytes());
212
213 is.fatalCheck
214 (
215 "List<char>::readList(Istream&) : [binary block]"
216 );
217 }
218
219 is.format(oldFmt);
220 }
221 else
222 {
224 {
225 // Binary and contiguous
226
227 if (len)
228 {
230 (
231 is,
232 list.data_bytes(),
233 list.size_bytes()
234 );
235
236 is.fatalCheck
237 (
238 "List<T>::readList(Istream&) : [binary block]"
239 );
240 }
241 }
242 else
243 {
244 // Begin of contents marker
245 const char delimiter = is.readBeginList("List");
246
247 if (len)
248 {
249 if (delimiter == token::BEGIN_LIST)
250 {
251 auto iter = list.begin();
252 const auto last = list.end();
253
254 // Contents
255 for (/*nil*/; (iter != last); (void)++iter)
256 {
257 is >> *iter;
258
259 is.fatalCheck
260 (
261 "List<T>::readList(Istream&) : "
262 "reading entry"
263 );
264 }
265 }
266 else
267 {
268 // Uniform content (delimiter == token::BEGIN_BLOCK)
269
270 T elem;
271 is >> elem;
272
273 is.fatalCheck
274 (
275 "List<T>::readList(Istream&) : "
276 "reading the single entry"
277 );
278
279 // Fill with the value
281 }
282 }
283
284 // End of contents marker
285 is.readEndList("List");
286 }
287 }
288 }
289 else if (tok.isPunctuation(token::BEGIN_LIST))
290 {
291 // "(...)" : read as bracketed list
292 is.putBack(tok);
293 this->readBracketList(is);
294 }
295 else
296 {
297 list.clear(); // Clear old contents
298
300 << "incorrect first token, expected <int> or '(', found "
301 << tok.info() << nl
302 << exit(FatalIOError);
303 }
304
305 return is;
306}
307
308
309// ************************************************************************* //
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
void resize_nocopy(const label len)
Adjust allocated size of list without necessarily.
Definition ListI.H:171
constexpr List() noexcept
Default construct.
Definition ListI.H:108
void resize(const label len)
Adjust allocated size of list.
Definition ListI.H:153
void clear()
Clear the list, i.e. set size to zero.
Definition ListI.H:133
Istream & readList(Istream &is)
Read List from Istream, discarding contents of existing List.
Definition ListIO.C:167
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.
bool empty() const noexcept
True if List is empty (ie, size() is zero).
Definition UList.H:701
iterator end() noexcept
Return an iterator to end traversing the UList.
Definition UListI.H:454
label capacity() const noexcept
Size of the underlying storage.
Definition UList.H:711
std::streamsize size_bytes() const noexcept
Number of contiguous bytes for the List data.
Definition UListI.H:295
T & last()
Access last element of the list, position [size()-1].
Definition UList.H:971
UList< T > & operator=(const UList< T > &)=delete
No copy assignment (default: shallow copy).
A token holds an item read from Istream.
Definition token.H:70
bool isPunctuation() const noexcept
Token is PUNCTUATION.
Definition tokenI.H:650
@ BEGIN_LIST
Begin list [isseparator].
Definition token.H:174
@ END_LIST
End list [isseparator].
Definition token.H:175
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
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition error.H:629
#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
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition hashSets.C:26
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