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-2019 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
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 
33 template<unsigned Width>
35 {
36  os << *this;
37 }
38 
39 
40 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
41 
42 template<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 
63 template<unsigned Width>
65 {
66  PackedList<Width>& list = *this;
67 
68  list.clear();
70 
71  token firstTok(is);
72  is.fatalCheck
73  (
74  "PackedList::read(Istream&) : "
75  "reading first token"
76  );
77 
78  if (firstTok.isLabel())
79  {
80  const label len = firstTok.labelToken();
81 
82  // Set list length to that read
83  list.resize(len);
84 
85  // Read list contents depending on data format
86  if (is.format() == IOstream::ASCII)
87  {
88  // Read beginning of contents
89  const char delimiter = is.readBeginList("PackedList");
90 
91  if (len)
92  {
93  if (delimiter == token::BEGIN_LIST)
94  {
95  for (label i=0; i<len; ++i)
96  {
97  list[i] = list.readValue(is);
98 
99  is.fatalCheck
100  (
101  "PackedList::read(Istream&) : "
102  "reading entry"
103  );
104  }
105  }
106  else
107  {
108  // Assign for all entries
109  list = list.readValue(is);
110 
111  is.fatalCheck
112  (
113  "PackedList::read(Istream&) : "
114  "reading the single entry"
115  );
116  }
117  }
118 
119  // Read end of contents
120  is.readEndList("PackedList");
121  }
122  else
123  {
124  // NOTE: binary content should be independent of WM_LABEL_SIZE
125 
126  if (len)
127  {
128  is.read
129  (
130  reinterpret_cast<char*>(list.storage().data()),
131  list.byteSize()
132  );
133 
134  is.fatalCheck
135  (
136  "PackedList::read(Istream&) : "
137  "reading the binary block"
138  );
139  }
140  }
141  }
142  else if (firstTok.isPunctuation())
143  {
144  if (firstTok.pToken() == token::BEGIN_LIST)
145  {
146  token nextTok(is);
148 
149  while
150  (
151  !( nextTok.isPunctuation()
152  && nextTok.pToken() == token::END_LIST
153  )
154  )
155  {
156  is.putBack(nextTok);
157  list.append(list.readValue(is));
158 
159  is >> nextTok;
161  }
162  }
163  else if (firstTok.pToken() == token::BEGIN_BLOCK)
164  {
165  token nextTok(is);
167 
168  while
169  (
170  !( nextTok.isPunctuation()
171  && nextTok.pToken() == token::END_BLOCK
172  )
173  )
174  {
175  is.putBack(nextTok);
176  list.setPair(is);
177 
178  is >> nextTok;
180  }
181  }
182  else
183  {
185  << "incorrect first token, expected '(', found "
186  << firstTok.info()
187  << exit(FatalIOError);
188  }
189  }
190  else
191  {
193  << "incorrect first token, expected <int>, '(' or '{', found "
194  << firstTok.info()
195  << exit(FatalIOError);
196  }
197 
198  return is;
199 }
200 
201 
202 template<unsigned Width>
204 (
205  Ostream& os,
206  const label shortLen
207 ) const
208 {
209  const PackedList<Width>& list = *this;
210  const label len = list.size();
211 
212  // Write list contents depending on data format
213  if (os.format() == IOstream::ASCII)
214  {
215  if (len > 1 && list.uniform())
216  {
217  // Two or more entries, and all have identical values.
218  os << len << token::BEGIN_BLOCK << list[0] << token::END_BLOCK;
219  }
220  else if (!shortLen || len <= shortLen)
221  {
222  // Shorter list, or line-breaks suppressed
223  os << len << token::BEGIN_LIST;
224  for (label i=0; i < len; ++i)
225  {
226  if (i) os << token::SPACE;
227  os << list[i];
228  }
229  os << token::END_LIST;
230  }
231  else
232  {
233  // Longer list
234  os << nl << len << nl << token::BEGIN_LIST << nl;
235  for (label i=0; i < len; ++i)
236  {
237  os << list[i] << nl;
238  }
239  os << token::END_LIST << nl;
240  }
241  }
242  else
243  {
244  // Contents are binary and contiguous
245  os << nl << len << nl;
246 
247  if (len)
248  {
249  // write(...) includes surrounding start/end delimiters
250  os.write
251  (
252  reinterpret_cast<const char*>(list.storage().cdata()),
253  list.byteSize()
254  );
255  }
256  }
257 
258  return os;
259 }
260 
261 
262 template<unsigned Width>
264 (
265  const word& keyword,
266  Ostream& os
267 ) const
268 {
269  if (keyword.size())
270  {
271  os.writeKeyword(keyword);
272  }
273  writeEntry(os);
274  os << token::END_STATEMENT << endl;
275 }
276 
277 
278 // * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * * //
279 
280 template<unsigned Width>
282 {
283  return list.read(is);
284 }
285 
286 
287 template<unsigned Width>
288 Foam::Ostream& Foam::operator<<
289 (
290  Ostream& os,
291  const InfoProxy<PackedList<Width>>& iproxy
292 )
293 {
294  const PackedList<Width>& list = iproxy.t_;
295 
296  os << "PackedList<" << Width
297  << "> size=" << list.size() << "/" << list.capacity()
298  << " (limits: max=" << PackedList<Width>::max_value
299  << ", elem_per_block=" << PackedList<Width>::elem_per_block
300  << ")"
301  << nl;
302 
303  return os;
304 }
305 
306 
307 // ************************************************************************* //
Foam::token::labelToken
label labelToken() const
Return label value.
Definition: tokenI.H:487
IOstreams.H
Useful combination of include files which define Sin, Sout and Serr and the use of IO streams general...
PackedList.H
Foam::token::isLabel
bool isLabel() const noexcept
Token is LABEL.
Definition: tokenI.H:481
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::PackedList::read
Istream & read(Istream &is)
Clear list and read from stream.
Definition: PackedListIO.C:64
Foam::Istream::readBeginList
char readBeginList(const char *funcName)
Begin read of list data, starts with '(' or '{'.
Definition: Istream.C:146
Foam::IOstream::fatalCheck
bool fatalCheck(const char *operation) const
Check IOstream status for given operation.
Definition: IOstream.C:57
Foam::IOstreamOption::format
streamFormat format() const noexcept
Get the current stream format.
Definition: IOstreamOption.H:289
Foam::Istream::readEndList
char readEndList(const char *funcName)
End read of list data, ends with ')' or '}'.
Definition: Istream.C:167
Foam::FatalIOError
IOerror FatalIOError
Foam::operator>>
Istream & operator>>(Istream &, directionInfo &)
Definition: directionInfo.C:230
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
Foam::token
A token holds an item read from Istream.
Definition: token.H:68
Foam::PackedList::resize
void resize(const label nElem, const unsigned int val=0u)
Reset addressable list size, does not shrink the allocated size.
Definition: PackedListI.H:399
Foam::token::pToken
punctuationToken pToken() const
Return punctuation character.
Definition: tokenI.H:459
Foam::PackedList::uniform
bool uniform() const
True if all entries have identical values, and list is non-empty.
Definition: PackedList.C:93
Foam::PackedList::printBits
Ostream & printBits(Ostream &os, bool debugOutput=false) const
Print bit patterns, optionally with extra debug.
Definition: PackedListIO.C:44
Foam::token::info
InfoProxy< token > info() const
Return info proxy for printing token information to a stream.
Definition: token.H:551
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
Foam::token::isPunctuation
bool isPunctuation() const noexcept
Token is PUNCTUATION.
Definition: tokenI.H:453
Foam::PackedList::writeList
Ostream & writeList(Ostream &os, const label shortLen=0) const
Write List, with line-breaks in ASCII when length exceeds shortLen.
Definition: PackedListIO.C:204
Foam::PackedList::byteSize
std::streamsize byteSize() const
Definition: PackedListI.H:551
Foam::Ostream::write
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
Foam::Ostream::writeKeyword
virtual Ostream & writeKeyword(const keyType &kw)
Write the keyword followed by an appropriate indentation.
Definition: Ostream.C:57
Foam::PackedList::append
PackedList< Width > & append(const unsigned int val)
Append a value at the end of the list.
Definition: PackedListI.H:652
Foam::PackedList::setPair
void setPair(Istream &is)
Read an index/value pair and set accordingly.
Definition: PackedListI.H:58
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::PackedList::writeEntry
void writeEntry(Ostream &os) const
Write as a dictionary entry.
Definition: PackedListIO.C:34
Foam::nl
constexpr char nl
Definition: Ostream.H:385
Foam::PackedList
A dynamic list of packed unsigned integers, with the number of bits per item specified by the <Width>...
Definition: PackedList.H:108
Foam::Istream::putBack
void putBack(const token &tok)
Put back token.
Definition: Istream.C:53
Foam::PackedList::size
label size() const noexcept
Number of entries.
Definition: PackedListI.H:377
Foam::BitOps::print
Ostream & print(Ostream &os, UIntType value, char off='0', char on='1')
Print 0/1 bits in the (unsigned) integral type.
Definition: BitOps.H:199
Foam::PackedList::storage
const List< unsigned int > & storage() const
Return the underlying storage blocks.
Definition: PackedListI.H:537
FUNCTION_NAME
#define FUNCTION_NAME
Definition: messageStream.H:270
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:401
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::PackedList::clear
void clear()
Clear the list, i.e. set addressable size to zero.
Definition: PackedListI.H:502
Foam::PackedList::readValue
static unsigned int readValue(Istream &is)
Read a list entry (allows for specialization)
Definition: PackedListI.H:41
Foam::Istream::read
virtual Istream & read(token &)=0
Return next token from stream.