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-------------------------------------------------------------------------------
11License
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
36namespace Foam
37{
38
39// Failsafe read-access.
40// Return the token at location, or undefinedToken.
41inline 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.
58static 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
125void 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
293// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
294
296{
297 os << "ITstream : " << name_.c_str() << ", line ";
299 const tokenList& toks = *this;
300
301 if (toks.empty())
302 {
303 os << lineNumber();
305 else
306 {
307 os << toks.first().lineNumber();
308
309 if (toks.first().lineNumber() < toks.last().lineNumber())
311 os << '-' << toks.last().lineNumber();
312 }
313 }
314 os << ", ";
315
317}
318
319
320std::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
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
548{
550 return *this;
551}
552
553
554Foam::Istream& Foam::ITstream::read(char*, std::streamsize)
555{
557 return *this;
558}
559
560
562{
563 seek(0);
564}
565
566
567void 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
577void 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
587void 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
600void 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 {
624 name_ = is.name_;
625 rewind();
626 }
627}
628
629
631{
633 rewind();
634}
635
636
638{
639 tokenList::operator=(std::move(toks));
640 rewind();
641}
642
643
644// ************************************************************************* //
Input/output from string buffers.
label n
Foam::string str() const
Get the string - as Foam::string rather than std::string.
Definition: StringStream.H:88
virtual bool resize()
Resize the ODE solver.
Definition: Euler.C:53
The IOstreamOption is a simple container for options an IOstream can normally have.
bool bad() const noexcept
True if stream is corrupted.
Definition: IOstream.H:251
void setGood() noexcept
Set stream state to be good.
Definition: IOstream.H:147
void setOpened() noexcept
Set stream opened.
Definition: IOstream.H:129
Generic input stream using a standard (STL) stream.
Definition: ISstream.H:58
virtual Istream & read(token &t)
Return next token from stream.
Definition: ISstream.C:530
An input stream of tokens.
Definition: ITstream.H:56
const token & peek() const
Failsafe peek at what the next read would return,.
Definition: ITstream.C:352
std::string toString() const
Definition: ITstream.C:320
const token & peekFirst() const
Failsafe peek at the first token in the list.
Definition: ITstream.C:340
const token & peekLast() const
Failsafe peek at the last token in the list.
Definition: ITstream.C:346
void seek(label pos)
Move tokenIndex to the specified position.
Definition: ITstream.C:364
void skip(label n=1)
Move tokenIndex relative to the current position.
Definition: ITstream.C:411
virtual void rewind()
Rewind the stream so that it may be read again.
Definition: ITstream.C:561
static tokenList parse(const UList< char > &input, IOstreamOption streamOpt=IOstreamOption())
Definition: ITstream.C:82
virtual Istream & readRaw(char *data, std::streamsize count)
Low-level raw binary read.
Definition: ITstream.C:547
void operator=(const ITstream &is)
Copy assignment, with rewind()
Definition: ITstream.C:617
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:64
bool getBack(token &tok)
Get the put-back token if there is one.
Definition: Istream.C:92
const token & peekBack() const noexcept
Examine putback token without removing it.
Definition: Istream.C:49
bool hasPutback() const noexcept
True if putback token is in use.
Definition: Istream.H:79
T & newElmt(const label i)
Definition: ListI.H:153
void operator=(const UList< token > &a)
Assignment to UList operator. Takes linear time.
Definition: List.C:480
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:139
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:116
Output to string buffer, using a OSstream. Always UNCOMPRESSED.
Definition: StringStream.H:231
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:62
virtual bool read()
Re-read model coefficients if they have changed.
Similar to IStringStream but using an externally managed buffer for its input. This allows the input ...
Definition: UIListStream.H:205
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: UList.H:94
T & first()
Return the first element of the list.
Definition: UListI.H:202
bool empty() const noexcept
True if the UList is empty (ie, size() is zero)
Definition: UListI.H:427
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
T & last()
Return the last element of the list.
Definition: UListI.H:216
void operator=(const ObukhovLength &)=delete
No copy assignment.
scalar print()
Print to screen.
A token holds an item read from Istream.
Definition: token.H:69
label lineNumber() const noexcept
The line number for the token.
Definition: tokenI.H:391
bool good() const noexcept
True if token is not UNDEFINED or ERROR.
Definition: tokenI.H:405
void reset()
Reset token to UNDEFINED and clear any allocated storage.
Definition: tokenI.H:257
static const token undefinedToken
An undefined token.
Definition: token.H:294
bool append() const noexcept
True if output format uses an append mode.
A class for handling words, derived from Foam::string.
Definition: word.H:68
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:63
#define NotImplemented
Issue a FatalErrorIn for a function not currently implemented.
Definition: error.H:517
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:473
OBJstream os(runTime.globalPath()/outputName)
Namespace for OpenFOAM.
dimensionedScalar pos(const dimensionedScalar &ds)
static label parseStream(ISstream &is, tokenList &tokens)
Definition: ITstream.C:58
static Istream & input(Istream &is, IntRange< T > &range)
Definition: IntRanges.C:55
double doubleScalar
A typedef for double.
Definition: scalarFwd.H:48
static const token & peekTokenAt(const UList< token > &list, const label i)
Definition: ITstream.C:42
float floatScalar
A typedef for float.
Definition: scalarFwd.H:45
IOerror FatalIOError
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
word format(conversionProperties.get< word >("format"))