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-2023 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.front().lineNumber();
291 
292  if (toks.front().lineNumber() < toks.back().lineNumber())
293  {
294  os << '-' << toks.back().lineNumber();
295  }
296  }
297  os << ", ";
298 
300 }
301 
302 
303 std::string Foam::ITstream::toString() const
304 {
305  const tokenList& toks = *this;
306  const label nToks = toks.size();
307 
308  if (nToks == 1 && toks.front().isStringType())
309  {
310  // Already a string-type (WORD, STRING, ...). Just copy.
311  return toks.front().stringToken();
312  }
313 
314  OStringStream buf;
315  buf.precision(16); // Some reasonably high precision
316  bool addSpace = false; // Separate from previous token with a space
317  for (const token& tok : toks)
318  {
319  if (addSpace) buf << token::SPACE;
320  addSpace = true;
321  buf << tok;
322  }
323 
324  return buf.str();
325 }
326 
327 
328 const Foam::token& Foam::ITstream::peek() const
329 {
330  // Use putback token if it exists
331  if (Istream::hasPutback())
332  {
334  }
335 
336  return peekAt(tokenIndex_);
337 }
338 
339 
340 void Foam::ITstream::seek(label pos)
341 {
342  lineNumber_ = 0;
343  const tokenList& toks = *this;
344  const label nToks = toks.size();
345 
346  if (!pos)
347  {
348  // Seek begin (rewind)
349  tokenIndex_ = 0;
350 
351  if (nToks)
352  {
353  lineNumber_ = toks.front().lineNumber();
354  }
355 
356  setOpened();
357  setGood();
358  }
359  else if (pos < 0 || pos >= nToks)
360  {
361  // Seek end or seek is out of range
362  tokenIndex_ = nToks;
363 
364  if (nToks)
365  {
366  lineNumber_ = toks.back().lineNumber();
367  }
368 
369  setEof();
370  }
371  else
372  {
373  // Seek middle (from the beginning)
374  tokenIndex_ = pos;
375 
376  if (nToks)
377  {
378  lineNumber_ = toks[tokenIndex_].lineNumber();
379  }
381  setOpened();
382  setGood();
383  }
384 }
385 
386 
387 void Foam::ITstream::skip(label n)
388 {
389  const tokenList& toks = *this;
390  const label nToks = toks.size();
391 
392  if (n < 0)
393  {
394  // Move backwards
395  while (n++ && tokenIndex_)
396  {
397  --tokenIndex_;
398  }
399 
400  if (tokenIndex_ < nToks)
401  {
402  lineNumber_ = toks[tokenIndex_].lineNumber();
403  setOpened();
404  setGood();
405  }
406  }
407  else if (n > 0)
408  {
409  // Move forward
410  while (n-- && tokenIndex_ < nToks)
411  {
412  ++tokenIndex_;
413  }
414 
415  if (tokenIndex_ < nToks)
416  {
417  lineNumber_ = toks[tokenIndex_].lineNumber();
418  setOpened();
419  setGood();
420  }
421  else
422  {
423  setEof();
424  }
425  }
426 }
427 
428 
430 {
431  // Use putback token if it exists
432  if (Istream::getBack(tok))
433  {
434  lineNumber_ = tok.lineNumber();
435  return *this;
436  }
437 
438  tokenList& toks = *this;
439  const label nToks = toks.size();
440 
441  if (tokenIndex_ < nToks)
442  {
443  tok = toks[tokenIndex_++];
444  lineNumber_ = tok.lineNumber();
445 
446  if (tokenIndex_ == nToks)
447  {
448  setEof();
449  }
450  }
451  else
452  {
453  if (eof())
454  {
456  << "attempt to read beyond EOF"
457  << exit(FatalIOError);
458  setBad();
459  }
460  else
461  {
462  setEof();
463  }
464 
465  tok.reset();
466 
467  if (nToks)
468  {
469  tok.lineNumber(toks.back().lineNumber());
470  }
471  else
472  {
473  tok.lineNumber(this->lineNumber());
474  }
475  }
476 
477  return *this;
478 }
479 
480 
482 {
484  return *this;
485 }
486 
487 
489 {
491  return *this;
492 }
493 
494 
496 {
498  return *this;
499 }
500 
501 
503 {
505  return *this;
506 }
507 
508 
510 {
512  return *this;
513 }
514 
515 
517 {
519  return *this;
520 }
521 
522 
523 Foam::Istream& Foam::ITstream::readRaw(char*, std::streamsize)
524 {
526  return *this;
527 }
528 
529 
530 Foam::Istream& Foam::ITstream::read(char*, std::streamsize)
531 {
533  return *this;
534 }
535 
538 {
539  seek(0);
540 }
541 
542 
543 void Foam::ITstream::push_back(const token& t, const bool lazy)
544 {
545  reserveCapacity(tokenIndex_ + 1, lazy);
546  tokenList& toks = *this;
547 
548  toks[tokenIndex_] = t; // copy append
549  ++tokenIndex_;
550 }
551 
552 
553 void Foam::ITstream::push_back(token&& t, const bool lazy)
554 {
555  reserveCapacity(tokenIndex_ + 1, lazy);
556  tokenList& toks = *this;
557 
558  toks[tokenIndex_] = std::move(t); // move append
559  ++tokenIndex_;
560 }
561 
562 
563 void Foam::ITstream::push_back(const UList<token>& newTokens, const bool lazy)
564 {
565  reserveCapacity(tokenIndex_ + newTokens.size(), lazy);
566  tokenList& toks = *this;
567 
568  for (const token& t : newTokens)
569  {
570  toks[tokenIndex_] = t; // copy append
571  ++tokenIndex_;
572  }
573 }
574 
575 
576 void Foam::ITstream::push_back(List<token>&& newTokens, const bool lazy)
577 {
578  reserveCapacity(tokenIndex_ + newTokens.size(), lazy);
579  tokenList& toks = *this;
580 
581  for (token& t : newTokens)
582  {
583  toks[tokenIndex_] = std::move(t); // move append
584  ++tokenIndex_;
585  }
587  newTokens.clear();
588 }
589 
590 
591 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
592 
593 void Foam::ITstream::operator=(const ITstream& is)
594 {
595  // Self-assignment is a no-op
596  if (this != &is)
597  {
598  Istream::operator=(is);
600  name_ = is.name_;
601  rewind();
602  }
603 }
604 
605 
607 {
608  tokenList::operator=(toks);
609  rewind();
610 }
611 
612 
614 {
615  tokenList::operator=(std::move(toks));
616  rewind();
617 }
618 
619 
620 // ************************************************************************* //
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:116
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:333
bool bad() const noexcept
True if stream is corrupted.
Definition: IOstream.H:305
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
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 List is empty (ie, size() is zero)
Definition: UList.H:632
A token holds an item read from Istream.
Definition: token.H:64
T & front()
Access first element of the list, position [0].
Definition: UListI.H:194
void skip(label n=1)
Move tokenIndex relative to the current position.
Definition: ITstream.C:380
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:485
std::string toString() const
Concatenate tokens into a space-separated std::string. The resulting string may contain quote charact...
Definition: ITstream.C:296
List< token > tokenList
List of token, used for dictionary primitive entry (for example)
Definition: tokenList.H:32
const token & peek() const
Failsafe peek at what the next read would return, including handling of any putback.
Definition: ITstream.C:321
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:47
Space [isspace].
Definition: token.H:128
virtual Istream & readRaw(char *data, std::streamsize count)
Low-level raw binary read.
Definition: ITstream.C:516
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:530
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
label size() const noexcept
The number of elements in the List.
Definition: UList.H:637
OBJstream os(runTime.globalPath()/outputName)
virtual void print(Ostream &os) const
Print stream description to Ostream.
Definition: IOstream.C:67
label lineNumber() const noexcept
Const access to the current stream line number.
Definition: IOstream.H:390
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
T & back()
Access last element of the list, position [size()-1].
Definition: UListI.H:208
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:57
label n
virtual Istream & read(token &tok)
Return next token from stream.
Definition: ITstream.C:422
void push_back(const token &t, const bool lazy)
Copy append a token at the current tokenIndex, incrementing the index.
Definition: ITstream.C:536
ITstream(const ITstream &is)
Copy construct.
Definition: ITstream.C:136
void operator=(const ITstream &is)
Copy assignment, with rewind()
Definition: ITstream.C:586
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 ...