ITstream.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-2015 OpenFOAM Foundation
9  Copyright (C) 2017-2021 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
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 "error.H"
30 #include "ITstream.H"
31 #include "StringStream.H"
32 #include "UIListStream.H"
33 
34 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
35 
36 namespace Foam
37 {
38 
39 // Failsafe read-access.
40 // Return the token at location, or undefinedToken.
41 inline static const token& peekTokenAt
42 (
43  const UList<token>& list,
44  const label i
45 )
46 {
47  return
48  (
49  i >= 0 && i < list.size()
50  ? list[i]
52  );
53 }
54 
55 
56 // Convert input sequence into a list of tokens.
57 // Return the number of tokens in the resulting list.
58 static label parseStream(ISstream& is, tokenList& tokens)
59 {
60  label nTok = 0;
61 
62  tokens.clear();
63  tokens.resize(64, token());
64 
65  token tok;
66  while (!is.read(tok).bad() && tok.good())
67  {
68  tokens.newElmt(nTok++) = std::move(tok);
69  }
70 
71  tokens.resize(nTok);
72 
73  return nTok;
74 }
75 
76 } // End namespace Foam
77 
78 
79 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
80 
82 (
83  const UList<char>& input,
84  IOstreamOption streamOpt
85 )
86 {
87  UIListStream is(input, streamOpt);
88 
89  tokenList tokens;
90  parseStream(is, tokens);
91  return tokens;
92 }
93 
94 
96 (
97  const std::string& input,
98  IOstreamOption streamOpt
99 )
100 {
101  UIListStream is(input.data(), input.length(), streamOpt);
102 
103  tokenList tokens;
104  parseStream(is, tokens);
105  return tokens;
106 }
107 
108 
110 (
111  const char* input,
112  IOstreamOption streamOpt
113 )
114 {
115  UIListStream is(input, strlen(input), streamOpt);
116 
117  tokenList tokens;
118  parseStream(is, tokens);
119  return tokens;
120 }
121 
122 
123 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
124 
125 void Foam::ITstream::reserveCapacity
126 (
127  const label nElem,
128  const bool lazy
129 )
130 {
131  if (lazy)
132  {
133  // Reserve - leave excess capacity for further appends
134 
135  label n = tokenList::size();
136 
137  if (nElem > n)
138  {
139  if (!n) n = 1; // Avoid dead-lock when starting from zero-sized
140 
141  do
142  {
143  n *= 2;
144  }
145  while (nElem >= n);
146 
148  }
149  }
150  else
151  {
152  // Strict capacity
153  tokenList::resize(nElem);
154  }
155 }
156 
157 
158 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
159 
161 :
162  Istream(static_cast<IOstreamOption>(is)),
163  tokenList(is),
164  name_(is.name_),
165  tokenIndex_(0)
166 {
167  setOpened();
168  setGood();
169 }
170 
171 
173 :
174  Istream(static_cast<IOstreamOption>(is)),
175  tokenList(std::move(static_cast<tokenList&>(is))),
176  name_(std::move(is.name_)),
177  tokenIndex_(0)
178 {
179  setOpened();
180  setGood();
181 }
182 
183 
185 (
186  IOstreamOption streamOpt,
187  const string& name
188 )
189 :
190  Istream(streamOpt.format(), streamOpt.version()),
191  tokenList(),
192  name_(name),
193  tokenIndex_(0)
194 {
195  setOpened();
196  setGood();
197 }
198 
199 
201 (
202  const Foam::zero,
203  const string& name,
204  IOstreamOption streamOpt
205 )
206 :
207  ITstream(streamOpt, name)
208 {}
209 
210 
212 (
213  const string& name,
214  const UList<token>& tokens,
215  IOstreamOption streamOpt
216 )
217 :
218  Istream(streamOpt.format(), streamOpt.version()),
219  tokenList(tokens),
220  name_(name),
221  tokenIndex_(0)
222 {
223  setOpened();
224  setGood();
225 }
226 
227 
229 (
230  const string& name,
231  List<token>&& tokens,
232  IOstreamOption streamOpt
233 )
234 :
235  Istream(streamOpt.format(), streamOpt.version()),
236  tokenList(std::move(tokens)),
237  name_(name),
238  tokenIndex_(0)
239 {
240  setOpened();
241  setGood();
242 }
243 
244 
246 (
247  const UList<char>& input,
248  IOstreamOption streamOpt,
249  const string& name
250 )
251 :
252  ITstream(streamOpt, name)
253 {
254  UIListStream is(input, streamOpt);
255 
256  parseStream(is, static_cast<tokenList&>(*this));
258 }
259 
260 
262 (
263  const std::string& input,
264  IOstreamOption streamOpt,
265  const string& name
266 )
267 :
268  ITstream(streamOpt, name)
269 {
270  UIListStream is(input.data(), input.length(), streamOpt);
271 
272  parseStream(is, static_cast<tokenList&>(*this));
274 }
275 
276 
278 (
279  const char* input,
280  IOstreamOption streamOpt,
281  const string& name
282 )
283 :
284  ITstream(streamOpt, name)
285 {
286  UIListStream is(input, strlen(input), streamOpt);
287 
288  parseStream(is, static_cast<tokenList&>(*this));
290 }
291 
292 
293 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
294 
296 {
297  os << "ITstream : " << name_.c_str() << ", line ";
298 
299  const tokenList& toks = *this;
300 
301  if (toks.empty())
302  {
303  os << lineNumber();
304  }
305  else
306  {
307  os << toks.first().lineNumber();
308 
309  if (toks.first().lineNumber() < toks.last().lineNumber())
310  {
311  os << '-' << toks.last().lineNumber();
312  }
313  }
314  os << ", ";
315 
317 }
318 
319 
320 std::string Foam::ITstream::toString() const
321 {
322  // NOTE: may wish to have special handling if there is a single token
323  // and it is already a string or word
324 
325  OStringStream buf;
326  unsigned i = 0;
327  for (const token& tok : *this)
328  {
329  if (i++)
330  {
331  buf << ' ';
332  }
333  buf << tok;
334  }
335 
336  return buf.str();
337 }
338 
339 
341 {
342  return peekTokenAt(*this, 0);
343 }
344 
345 
347 {
348  return peekTokenAt(*this, tokenList::size()-1);
349 }
350 
351 
353 {
354  // Use putback token if it exists
355  if (Istream::hasPutback())
356  {
357  return Istream::peekBack();
358  }
359 
360  return peekTokenAt(*this, tokenIndex_);
361 }
362 
363 
365 {
366  lineNumber_ = 0;
367  const tokenList& toks = *this;
368  const label nToks = toks.size();
369 
370  if (!pos)
371  {
372  // Seek begin (rewind)
373  tokenIndex_ = 0;
374 
375  if (nToks)
376  {
377  lineNumber_ = toks.first().lineNumber();
378  }
379 
380  setOpened();
381  setGood();
382  }
383  else if (pos < 0 || pos >= nToks)
384  {
385  // Seek end or seek is out of range
386  tokenIndex_ = nToks;
387 
388  if (nToks)
389  {
390  lineNumber_ = toks.last().lineNumber();
391  }
392 
393  setEof();
394  }
395  else
396  {
397  // Seek middle (from the beginning)
398  tokenIndex_ = pos;
399 
400  if (nToks)
401  {
402  lineNumber_ = toks[tokenIndex_].lineNumber();
403  }
404 
405  setOpened();
406  setGood();
407  }
408 }
409 
410 
412 {
413  const tokenList& toks = *this;
414  const label nToks = toks.size();
415 
416  if (n < 0)
417  {
418  // Move backwards
419  while (n++ && tokenIndex_)
420  {
421  --tokenIndex_;
422  }
423 
424  if (tokenIndex_ < nToks)
425  {
426  lineNumber_ = toks[tokenIndex_].lineNumber();
427  setOpened();
428  setGood();
429  }
430  }
431  else if (n > 0)
432  {
433  // Move forward
434  while (n-- && tokenIndex_ < nToks)
435  {
436  ++tokenIndex_;
437  }
438 
439  if (tokenIndex_ < nToks)
440  {
441  lineNumber_ = toks[tokenIndex_].lineNumber();
442  setOpened();
443  setGood();
444  }
445  else
446  {
447  setEof();
448  }
449  }
450 }
451 
452 
454 {
455  // Use putback token if it exists
456  if (Istream::getBack(tok))
457  {
458  lineNumber_ = tok.lineNumber();
459  return *this;
460  }
461 
462  tokenList& toks = *this;
463  const label nToks = toks.size();
464 
465  if (tokenIndex_ < nToks)
466  {
467  tok = toks[tokenIndex_++];
468  lineNumber_ = tok.lineNumber();
469 
470  if (tokenIndex_ == nToks)
471  {
472  setEof();
473  }
474  }
475  else
476  {
477  if (eof())
478  {
480  << "attempt to read beyond EOF"
481  << exit(FatalIOError);
482  setBad();
483  }
484  else
485  {
486  setEof();
487  }
488 
489  tok.reset();
490 
491  if (nToks)
492  {
493  tok.lineNumber(toks.last().lineNumber());
494  }
495  else
496  {
497  tok.lineNumber(this->lineNumber());
498  }
499  }
500 
501  return *this;
502 }
503 
504 
506 {
508  return *this;
509 }
510 
511 
513 {
515  return *this;
516 }
517 
518 
520 {
522  return *this;
523 }
524 
525 
527 {
529  return *this;
530 }
531 
532 
534 {
536  return *this;
537 }
538 
539 
541 {
543  return *this;
544 }
545 
546 
547 Foam::Istream& Foam::ITstream::readRaw(char*, std::streamsize)
548 {
550  return *this;
551 }
552 
553 
554 Foam::Istream& Foam::ITstream::read(char*, std::streamsize)
555 {
557  return *this;
558 }
559 
560 
562 {
563  seek(0);
564 }
565 
566 
567 void Foam::ITstream::append(const token& t, const bool lazy)
568 {
569  reserveCapacity(tokenIndex_ + 1, lazy);
570  tokenList& toks = *this;
571 
572  toks[tokenIndex_] = t; // copy append
573  ++tokenIndex_;
574 }
575 
576 
577 void Foam::ITstream::append(token&& t, const bool lazy)
578 {
579  reserveCapacity(tokenIndex_ + 1, lazy);
580  tokenList& toks = *this;
581 
582  toks[tokenIndex_] = std::move(t); // move append
583  ++tokenIndex_;
584 }
585 
586 
587 void Foam::ITstream::append(const UList<token>& newTokens, const bool lazy)
588 {
589  reserveCapacity(tokenIndex_ + newTokens.size(), lazy);
590  tokenList& toks = *this;
591 
592  for (const token& t : newTokens)
593  {
594  toks[tokenIndex_] = t; // copy append
595  ++tokenIndex_;
596  }
597 }
598 
599 
600 void Foam::ITstream::append(List<token>&& newTokens, const bool lazy)
601 {
602  reserveCapacity(tokenIndex_ + newTokens.size(), lazy);
603  tokenList& toks = *this;
604 
605  for (token& t : newTokens)
606  {
607  toks[tokenIndex_] = std::move(t); // move append
608  ++tokenIndex_;
609  }
610 
611  newTokens.clear();
612 }
613 
614 
615 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
616 
618 {
619  // Self-assignment is a no-op
620  if (this != &is)
621  {
622  Istream::operator=(is);
624  name_ = is.name_;
625  rewind();
626  }
627 }
628 
629 
631 {
632  tokenList::operator=(toks);
633  rewind();
634 }
635 
636 
638 {
639  tokenList::operator=(std::move(toks));
640  rewind();
641 }
642 
643 
644 // ************************************************************************* //
Foam::ITstream::append
void append(const token &t, const bool lazy)
Definition: ITstream.C:567
Foam::UIListStream
Similar to IStringStream but using an externally managed buffer for its input. This allows the input ...
Definition: UIListStream.H:201
Foam::List::newElmt
T & newElmt(const label i)
Definition: ListI.H:153
Foam::doubleScalar
double doubleScalar
A typedef for double.
Definition: scalarFwd.H:48
Foam::ITstream::rewind
virtual void rewind()
Rewind the stream so that it may be read again.
Definition: ITstream.C:561
Foam::ITstream::readRaw
virtual Istream & readRaw(char *data, std::streamsize count)
Low-level raw binary read.
Definition: ITstream.C:547
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
ITstream.H
Foam::List::resize
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:139
Foam::token::lineNumber
label lineNumber() const noexcept
The line number for the token.
Definition: tokenI.H:391
Foam::floatScalar
float floatScalar
A typedef for float.
Definition: scalarFwd.H:45
Foam::IOstream::print
virtual void print(Ostream &os) const
Print stream description to Ostream.
Definition: IOstream.C:80
Foam::IOstreamOption::format
streamFormat format() const noexcept
Get the current stream format.
Definition: IOstreamOption.H:286
Foam::ISstream
Generic input stream using a standard (STL) stream.
Definition: ISstream.H:55
StringStream.H
Input/output from string buffers.
Foam::FatalIOError
IOerror FatalIOError
Foam::token
A token holds an item read from Istream.
Definition: token.H:68
Foam::IOstream::setOpened
void setOpened() noexcept
Set stream opened.
Definition: IOstream.H:129
Foam::ITstream::read
virtual Istream & read(token &tok)
Return next token from stream.
Definition: ITstream.C:453
Foam::ITstream::operator=
void operator=(const ITstream &is)
Copy assignment, with rewind()
Definition: ITstream.C:617
Foam::IOstream::setGood
void setGood() noexcept
Set stream state to be good.
Definition: IOstream.H:147
n
label n
Definition: TABSMDCalcMethod2.H:31
NotImplemented
#define NotImplemented
Issue a FatalErrorIn for a function not currently implemented.
Definition: error.H:517
Foam::ITstream::ITstream
ITstream(const ITstream &is)
Copy construct.
Definition: ITstream.C:160
error.H
Foam::ITstream
An input stream of tokens.
Definition: ITstream.H:52
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
Foam::ITstream::print
void print(Ostream &os) const
Print stream description to Ostream.
Definition: ITstream.C:295
UIListStream.H
Foam::ITstream::peekFirst
const token & peekFirst() const
Failsafe peek at the first token in the list.
Definition: ITstream.C:340
Foam::token::reset
void reset()
Reset token to UNDEFINED and clear any allocated storage.
Definition: tokenI.H:257
Foam::Istream::peekBack
const token & peekBack() const noexcept
Examine putback token without removing it.
Definition: Istream.C:49
Foam::IOstreamOption
The IOstreamOption is a simple container for options an IOstream can normally have.
Definition: IOstreamOption.H:63
Foam::List::operator=
void operator=(const UList< T > &a)
Assignment to UList operator. Takes linear time.
Definition: List.C:498
Foam::IOstreamOption::version
versionNumber version() const noexcept
Get the stream version.
Definition: IOstreamOption.H:338
Foam::token::undefinedToken
static const token undefinedToken
An undefined token.
Definition: token.H:294
os
OBJstream os(runTime.globalPath()/outputName)
Foam::IOstream::bad
bool bad() const noexcept
True if stream is corrupted.
Definition: IOstream.H:251
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::ITstream::seek
void seek(label pos)
Move tokenIndex to the specified position.
Definition: ITstream.C:364
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::tokenList
List< token > tokenList
List of tokens, used for a IOdictionary entry.
Definition: tokenList.H:44
Foam::token::good
bool good() const noexcept
True if token is not UNDEFINED or ERROR.
Definition: tokenI.H:405
Foam::ITstream::skip
void skip(label n=1)
Move tokenIndex relative to the current position.
Definition: ITstream.C:411
Foam::Detail::StringStreamAllocator::str
Foam::string str() const
Get the string - as Foam::string rather than std::string.
Definition: StringStream.H:88
Foam::Istream::getBack
bool getBack(token &tok)
Get the put-back token if there is one.
Definition: Istream.C:92
Foam::Istream::hasPutback
bool hasPutback() const noexcept
True if putback token is in use.
Definition: Istream.H:79
Foam::ITstream::toString
std::string toString() const
Definition: ITstream.C:320
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:63
Foam::OStringStream
Output to string buffer, using a OSstream. Always UNCOMPRESSED.
Definition: StringStream.H:227
Foam::ITstream::peekLast
const token & peekLast() const
Failsafe peek at the last token in the list.
Definition: ITstream.C:346
Foam::UList
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:103
Foam::List::clear
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:116
Foam::input
static Istream & input(Istream &is, IntRange< T > &range)
Definition: IntRanges.C:55
Foam::ISstream::read
virtual Istream & read(token &t)
Return next token from stream.
Definition: ISstream.C:530
Foam::name
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
Foam::peekTokenAt
static const token & peekTokenAt(const UList< token > &list, const label i)
Definition: ITstream.C:42
FatalIOErrorInFunction
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
Foam::parseStream
static label parseStream(ISstream &is, tokenList &tokens)
Definition: ITstream.C:58
Foam::UList::size
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::ITstream::peek
const token & peek() const
Failsafe peek at what the next read would return,.
Definition: ITstream.C:352
Foam::ITstream::parse
static tokenList parse(const UList< char > &input, IOstreamOption streamOpt=IOstreamOption())
Definition: ITstream.C:82
Foam::zero
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:62
Foam::pos
dimensionedScalar pos(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:177