OSstream.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-2016 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 "token.H"
31 #include "OSstream.H"
32 #include <algorithm>
33 
34 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
35 
36 bool Foam::OSstream::write(const token& tok)
37 {
38  // Direct token handling only for some types
39 
40  switch (tok.type())
41  {
42  case token::tokenType::FLAG :
43  {
44  // silently consume the flag
45  return true;
46  }
47 
48  case token::tokenType::DIRECTIVE :
49  {
50  // Token stored with leading '#' sigil - output directly
51  write(tok.wordToken());
52  return true;
53  }
54 
55  case token::tokenType::EXPRESSION :
56  {
57  // Token stored with surrounding '${{ .. }}' - output directly
58  writeQuoted(tok.stringToken(), false);
59  return true;
60  }
61 
62  case token::tokenType::VARIABLE :
63  {
64  // Token stored with leading '$' sigil - output directly
65  writeQuoted(tok.stringToken(), false);
66  return true;
67  }
68 
69  case token::tokenType::VERBATIM :
70  {
71  // Token stored without surrounding '#{ .. #}'. Add on output
72  write(char(token::HASH));
74  writeQuoted(tok.stringToken(), false);
75  write(char(token::HASH));
76  write(char(token::END_BLOCK));
77 
78  return true;
79  }
80 
81  case token::tokenType::CHAR_DATA :
82  {
83  // Character content - written without quotes
84  writeQuoted(tok.stringToken(), false);
85  return true;
86  }
87 
88  default:
89  break;
90  }
91 
92  return false;
93 }
94 
95 
97 {
98  os_ << c;
99  syncState();
100 
101  // Advance line number on newline
102  if (c == token::NL) ++lineNumber_;
103  return *this;
104 }
105 
106 
108 (
109  const char* str,
110  std::streamsize len,
111  const bool quoted
112 )
113 {
114  if (!str || len <= 0) return *this;
115 
116  const char* last = (str + len);
117 
118  if (!quoted)
119  {
120  #if __cplusplus >= 201703L
121  os_ << std::string_view(str, len);
122  #else
123  for (const char* iter = str; iter != last; ++iter)
124  {
125  os_ << *iter;
126  }
127  #endif
128  syncState();
129 
130  // Unquoted, only advance line number on newline
131  lineNumber_ += std::count(str, last, '\n');
132  return *this;
133  }
134 
135 
136  // Output with surrounding quotes and backslash escaping
137  // - functionality like std::quoted (from <iomanip>), while also
138  // counting the newlines.
139 
140  os_ << token::DQUOTE;
141 
142  unsigned backslash = 0;
143  for (auto iter = str; iter != last; ++iter)
144  {
145  const char c = *iter;
146 
147  if (c == '\\')
148  {
149  ++backslash;
150  continue; // Delay output until escaped character is known
151  }
152  else if (c == token::NL)
153  {
154  ++backslash; // Add backslash escape for newline
155  ++lineNumber_; // Advance line number on newline
156  }
157  else if (c == token::DQUOTE)
158  {
159  ++backslash; // Add backslash escape for quote
160  }
161 
162  // output all pending backslashes
163  while (backslash)
164  {
165  os_ << '\\';
166  --backslash;
167  }
168 
169  os_ << c;
170  }
171 
172  // silently drop any trailing backslashes
173  // they would otherwise appear like an escaped end-quote
175 
176  syncState();
177  return *this;
178 }
179 
180 
181 Foam::Ostream& Foam::OSstream::write(const char* str)
182 {
183  if (!str) return *this;
184 
185  const char* last = (str + strlen(str));
186 
187  os_ << str;
188  syncState();
190  // Advance line number on newline
191  lineNumber_ += std::count(str, last, '\n');
192  return *this;
193 }
194 
195 
197 {
198  // Unquoted, and no newlines expected.
199  os_ << str;
200  syncState();
201 
202  return *this;
203 }
204 
206 Foam::Ostream& Foam::OSstream::write(const std::string& str)
207 {
208  return writeQuoted(str.data(), str.size(), true);
209 }
210 
211 
212 Foam::Ostream& Foam::OSstream::write(const int32_t val)
213 {
214  os_ << val;
215  syncState();
216  return *this;
217 }
218 
219 
220 Foam::Ostream& Foam::OSstream::write(const int64_t val)
221 {
222  os_ << val;
223  syncState();
224  return *this;
225 }
226 
227 
228 Foam::Ostream& Foam::OSstream::write(const float val)
229 {
230  os_ << val;
231  syncState();
232  return *this;
233 }
234 
235 
236 Foam::Ostream& Foam::OSstream::write(const double val)
237 {
238  os_ << val;
239  syncState();
240  return *this;
241 }
242 
243 
244 Foam::Ostream& Foam::OSstream::write(const char* data, std::streamsize count)
245 {
246  beginRawWrite(count);
247  writeRaw(data, count);
248  endRawWrite();
249 
250  return *this;
251 }
252 
253 
254 bool Foam::OSstream::beginRawWrite(std::streamsize count)
255 {
257  {
259  << "stream format not binary"
260  << abort(FatalIOError);
261  }
263  os_ << token::BEGIN_LIST;
264  syncState();
265  return os_.good();
266 }
267 
268 
270 {
272  syncState();
273  return os_.good();
274 }
275 
276 
278 (
279  const char* data,
280  std::streamsize count
281 )
282 {
283  // No check for IOstreamOption::BINARY since this is either done in the
284  // beginRawWrite() method, or the caller knows what they are doing.
286  os_.write(data, count);
287  syncState();
288  return *this;
289 }
290 
291 
293 {
294  for (unsigned short i = 0; i < indentLevel_*indentSize_; ++i)
295  {
296  os_ << ' ';
297  }
298  syncState();
299 }
300 
303 {
304  os_.flush();
305 }
306 
307 
309 {
310  write('\n');
311  os_.flush();
312 }
313 
314 
315 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
317 char Foam::OSstream::fill() const
318 {
319  return os_.fill();
320 }
321 
323 char Foam::OSstream::fill(const char fillch)
324 {
325  return os_.fill(fillch);
326 }
327 
329 int Foam::OSstream::width() const
330 {
331  return os_.width();
332 }
333 
335 int Foam::OSstream::width(const int w)
336 {
337  return os_.width(w);
338 }
339 
341 int Foam::OSstream::precision() const
342 {
343  return os_.precision();
344 }
345 
346 
347 int Foam::OSstream::precision(const int p)
348 {
349  return os_.precision(p);
350 }
351 
352 
353 // ************************************************************************* //
Begin block [isseparator].
Definition: token.H:165
virtual Ostream & writeQuoted(const char *str, std::streamsize len, const bool quoted=true) override
Write character/string content, with/without surrounding quotes.
Definition: OSstream.C:101
Double quote.
Definition: token.H:141
const word & wordToken() const
Return const reference to the word contents.
Definition: tokenI.H:729
A token holds an item read from Istream.
Definition: token.H:65
Newline [isspace].
Definition: token.H:130
virtual void endl() override
Add newline and flush stream.
Definition: OSstream.C:301
tokenType type() const noexcept
Return the token type.
Definition: tokenI.H:405
Begin list [isseparator].
Definition: token.H:161
virtual Ostream & writeRaw(const char *data, std::streamsize count) override
Low-level raw binary output.
Definition: OSstream.C:271
void write(vtk::formatter &fmt, const Type &val, const label n=1)
Component-wise write of a value (N times)
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of &#39;true&#39; entries.
Definition: BitOps.H:73
virtual int precision() const override
Get precision of output field.
Definition: OSstream.C:334
A class for handling words, derived from Foam::string.
Definition: word.H:63
virtual bool beginRawWrite(std::streamsize count) override
Begin marker for low-level raw binary output.
Definition: OSstream.C:247
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
End list [isseparator].
Definition: token.H:162
virtual bool endRawWrite() override
End marker for low-level raw binary output.
Definition: OSstream.C:262
errorManip< error > abort(error &err)
Definition: errorManip.H:139
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
virtual bool write(const token &tok) override
Write token to stream or otherwise handle it.
Definition: OSstream.C:29
const string & stringToken() const
Return const reference to the string contents.
Definition: tokenI.H:783
word format(conversionProperties.get< word >("format"))
virtual void indent() override
Add indentation characters.
Definition: OSstream.C:285
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:627
const dimensionedScalar c
Speed of light in a vacuum.
virtual void flush() override
Flush stream.
Definition: OSstream.C:295
virtual int width() const override
Get width of output field.
Definition: OSstream.C:322
virtual char fill() const override
Get the current padding character.
Definition: OSstream.C:310
volScalarField & p
End block [isseparator].
Definition: token.H:166
Hash - directive or start verbatim string.
Definition: token.H:136
IOerror FatalIOError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL IO ERROR&#39; header text and ...