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