PackedListIO.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) 2018-2021 OpenCFD Ltd.
9-------------------------------------------------------------------------------
10License
11 This file is part of OpenFOAM.
12
13 OpenFOAM is free software: you can redistribute it and/or modify it
14 under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25
26\*---------------------------------------------------------------------------*/
27
28#include "PackedList.H"
29#include "IOstreams.H"
30
31// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
32
33template<unsigned Width>
35{
36 os << *this;
37}
38
39
40// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
41
42template<unsigned Width>
44(
45 Ostream& os,
46 bool debugOutput
47) const
48{
49 os << token::BEGIN_LIST << nl;
50
51 const label nblocks = debugOutput ? blocks_.size() : num_blocks(size());
52 for (label blocki = 0; blocki < nblocks; ++blocki)
53 {
54 BitOps::print(os, blocks_[blocki], '.') << nl;
55 }
56
57 os << token::END_LIST << nl;
58
59 return os;
60}
61
62
63template<unsigned Width>
65{
66 PackedList<Width>& list = *this;
67
68 // Anull list
69 list.clear();
70
72
73 token tok(is);
74
75 is.fatalCheck("PackedList::readList(Istream&) : reading first token");
76
77 if (tok.isLabel())
78 {
79 const label len = tok.labelToken();
80
81 // Set list length to that read
82 list.resize(len);
83
84 if (is.format() == IOstream::BINARY)
85 {
86 // Binary (always contiguous)
87
88 if (len)
89 {
90 // NOTE: independent of WM_LABEL_SIZE
91 is.read(list.data_bytes(), list.size_bytes());
92
93 is.fatalCheck
94 (
95 "PackedList::readList(Istream&) : "
96 "reading the binary block"
97 );
98 }
99 }
100 else
101 {
102 // Begin of contents marker
103 const char delimiter = is.readBeginList("PackedList");
104
105 if (len)
106 {
107 if (delimiter == token::BEGIN_LIST)
108 {
109 for (label i=0; i<len; ++i)
110 {
111 list.set(i, list.readValue(is));
112
113 is.fatalCheck
114 (
115 "PackedList::readList(Istream&) : "
116 "reading entry"
117 );
118 }
119 }
120 else // token::BEGIN_BLOCK
121 {
122 // Assign for all entries
123 list = list.readValue(is);
124
125 is.fatalCheck
126 (
127 "PackedList::readList(Istream&) : "
128 "reading the single entry"
129 );
130 }
131 }
132
133 // End of contents marker
134 is.readEndList("PackedList");
135 }
136 }
137 else if (tok.isPunctuation(token::BEGIN_LIST))
138 {
139 is >> tok;
141
142 while (!tok.isPunctuation(token::END_LIST))
143 {
144 is.putBack(tok);
145 list.append(list.readValue(is));
146
147 is >> tok;
149 }
150 }
151 else if (tok.isPunctuation(token::BEGIN_BLOCK))
152 {
153 is >> tok;
155
156 while (!tok.isPunctuation(token::END_BLOCK))
157 {
158 is.putBack(tok);
159 list.setPair(is);
160
161 is >> tok;
163 }
164 }
165 else
166 {
168 << "incorrect first token, expected <int>, '(' or '{', found "
169 << tok.info() << nl
170 << exit(FatalIOError);
171 }
172
173 return is;
174}
175
176
177template<unsigned Width>
179(
180 Ostream& os,
181 const label shortLen
182) const
183{
184 const PackedList<Width>& list = *this;
185 const label len = list.size();
186
187 if (os.format() == IOstream::BINARY)
188 {
189 // Binary (always contiguous)
190
191 os << nl << len << nl;
192
193 if (len)
194 {
195 // write(...) includes surrounding start/end delimiters
196 os.write(list.cdata_bytes(), list.size_bytes());
197 }
198 }
199 else if (len > 1 && list.uniform())
200 {
201 // Two or more entries, and all entries have identical values.
202 os << len << token::BEGIN_BLOCK << list[0] << token::END_BLOCK;
203 }
204 else if (!shortLen || len <= shortLen)
205 {
206 // Single-line output
207
208 // Size and start delimiter
209 os << len << token::BEGIN_LIST;
210
211 // Contents
212 for (label i=0; i < len; ++i)
213 {
214 if (i) os << token::SPACE;
215 os << label(list.get(i));
216 }
217
218 // End delimiter
219 os << token::END_LIST;
220 }
221 else
222 {
223 // Multi-line output
224
225 // Size and start delimiter
226 os << nl << len << nl << token::BEGIN_LIST << nl;
227
228 // Contents
229 for (label i=0; i < len; ++i)
230 {
231 os << label(list.get(i)) << nl;
232 }
233
234 // End delimiter
235 os << token::END_LIST << nl;
236 }
237
238 return os;
239}
240
241
242template<unsigned Width>
244(
245 const word& keyword,
246 Ostream& os
247) const
248{
249 if (keyword.size())
250 {
251 os.writeKeyword(keyword);
252 }
253 writeEntry(os);
254 os << token::END_STATEMENT << endl;
255}
256
257
258// * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * * //
259
260template<unsigned Width>
262{
263 return list.readList(is);
264}
265
266
267template<unsigned Width>
268Foam::Ostream& Foam::operator<<
269(
270 Ostream& os,
271 const InfoProxy<PackedList<Width>>& iproxy
272)
273{
274 const PackedList<Width>& list = iproxy.t_;
275
276 os << "PackedList<" << Width
277 << "> size=" << list.size() << "/" << list.capacity()
278 << " (limits: max=" << PackedList<Width>::max_value
279 << ", elem_per_block=" << PackedList<Width>::elem_per_block
280 << ")"
281 << nl;
282
283 return os;
284}
285
286
287// ************************************************************************* //
Useful combination of include files which define Sin, Sout and Serr and the use of IO streams general...
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
virtual Istream & read(token &)=0
Return next token from stream.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:62
A dynamic list of packed unsigned integers, with the number of bits per item specified by the <Width>...
Definition: PackedList.H:129
static unsigned int readValue(Istream &is)
Read a list entry (allows for specialization)
Definition: PackedListI.H:41
char * data_bytes() noexcept
A pointer to the raw storage, reinterpreted as byte data.
Definition: PackedListI.H:582
void resize(const label numElem, const unsigned int val=0u)
Reset addressable list size, does not shrink the allocated size.
Definition: PackedListI.H:409
Ostream & printBits(Ostream &os, bool debugOutput=false) const
Print bit patterns, optionally with extra debug.
Definition: PackedListIO.C:44
label size() const noexcept
Number of entries.
Definition: PackedListI.H:377
bool set(const label i, unsigned int val=~0u)
Set value at index i, default value set is the max_value.
Definition: PackedListI.H:653
bool uniform() const
True if all entries have identical values, and list is non-empty.
Definition: PackedList.C:93
unsigned int get(const label i) const
Get value at index i or 0 for out-of-range.
Definition: PackedListI.H:630
PackedList< Width > & append(const unsigned int val)
Append a value at the end of the list.
Definition: PackedListI.H:697
const char * cdata_bytes() const noexcept
A const pointer to the raw storage, reinterpreted as byte data.
Definition: PackedListI.H:575
void writeEntry(Ostream &os) const
Write as a dictionary entry.
Definition: PackedListIO.C:34
void setPair(Istream &is)
Read an index/value pair and set accordingly.
Definition: PackedListI.H:58
Ostream & writeList(Ostream &os, const label shortLen=0) const
Write List, with line-breaks in ASCII when length exceeds shortLen.
Definition: PackedListIO.C:179
void clear()
Clear the list, i.e. set addressable size to zero.
Definition: PackedListI.H:512
Istream & readList(Istream &is)
Clear list and read from stream.
Definition: PackedListIO.C:64
std::streamsize size_bytes() const noexcept
Definition: PackedListI.H:589
A token holds an item read from Istream.
Definition: token.H:69
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
A class for handling words, derived from Foam::string.
Definition: word.H:68
#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
Istream & operator>>(Istream &, directionInfo &)
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