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  os_ << std::string_view(str, len);
121  syncState();
122 
123  // Unquoted, only advance line number on newline
124  lineNumber_ += std::count(str, last, '\n');
125  return *this;
126  }
127 
128 
129  // Output with surrounding quotes and backslash escaping
130  // - functionality like std::quoted (from <iomanip>), while also
131  // counting the newlines.
132 
133  os_ << token::DQUOTE;
134 
135  unsigned backslash = 0;
136  for (auto iter = str; iter != last; ++iter)
137  {
138  const char c = *iter;
139 
140  if (c == '\\')
141  {
142  ++backslash;
143  continue; // Delay output until escaped character is known
144  }
145  else if (c == token::NL)
146  {
147  ++backslash; // Add backslash escape for newline
148  ++lineNumber_; // Advance line number on newline
149  }
150  else if (c == token::DQUOTE)
151  {
152  ++backslash; // Add backslash escape for quote
153  }
154 
155  // output all pending backslashes
156  while (backslash)
157  {
158  os_ << '\\';
159  --backslash;
160  }
161 
162  os_ << c;
163  }
164 
165  // silently drop any trailing backslashes
166  // they would otherwise appear like an escaped end-quote
168 
169  syncState();
170  return *this;
171 }
172 
173 
174 Foam::Ostream& Foam::OSstream::write(const char* str)
175 {
176  if (!str) return *this;
177 
178  const char* last = (str + strlen(str));
179 
180  os_ << str;
181  syncState();
183  // Advance line number on newline
184  lineNumber_ += std::count(str, last, '\n');
185  return *this;
186 }
187 
188 
190 {
191  // Unquoted, and no newlines expected.
192  os_ << str;
193  syncState();
194 
195  return *this;
196 }
197 
199 Foam::Ostream& Foam::OSstream::write(const std::string& str)
200 {
201  return writeQuoted(str.data(), str.size(), true);
202 }
203 
204 
205 Foam::Ostream& Foam::OSstream::write(const int32_t val)
206 {
207  os_ << val;
208  syncState();
209  return *this;
210 }
211 
212 
213 Foam::Ostream& Foam::OSstream::write(const int64_t val)
214 {
215  os_ << val;
216  syncState();
217  return *this;
218 }
219 
220 
221 Foam::Ostream& Foam::OSstream::write(const float val)
222 {
223  os_ << val;
224  syncState();
225  return *this;
226 }
227 
228 
229 Foam::Ostream& Foam::OSstream::write(const double val)
230 {
231  os_ << val;
232  syncState();
233  return *this;
234 }
235 
236 
237 Foam::Ostream& Foam::OSstream::write(const char* data, std::streamsize count)
238 {
239  beginRawWrite(count);
240  writeRaw(data, count);
241  endRawWrite();
242 
243  return *this;
244 }
245 
246 
247 bool Foam::OSstream::beginRawWrite(std::streamsize count)
248 {
250  {
252  << "stream format not binary"
253  << abort(FatalIOError);
254  }
256  os_ << token::BEGIN_LIST;
257  syncState();
258  return os_.good();
259 }
260 
261 
263 {
265  syncState();
266  return os_.good();
267 }
268 
269 
271 (
272  const char* data,
273  std::streamsize count
274 )
275 {
276  // No check for IOstreamOption::BINARY since this is either done in the
277  // beginRawWrite() method, or the caller knows what they are doing.
279  os_.write(data, count);
280  syncState();
281  return *this;
282 }
283 
284 
286 {
287  for (unsigned short i = 0; i < indentLevel_*indentSize_; ++i)
288  {
289  os_ << ' ';
290  }
291  syncState();
292 }
293 
296 {
297  os_.flush();
298 }
299 
300 
302 {
303  write('\n');
304  os_.flush();
305 }
306 
307 
308 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
310 char Foam::OSstream::fill() const
311 {
312  return os_.fill();
313 }
314 
316 char Foam::OSstream::fill(const char fillch)
317 {
318  return os_.fill(fillch);
319 }
320 
322 int Foam::OSstream::width() const
323 {
324  return os_.width();
325 }
326 
328 int Foam::OSstream::width(const int w)
329 {
330  return os_.width(w);
331 }
332 
334 int Foam::OSstream::precision() const
335 {
336  return os_.precision();
337 }
338 
339 
340 int Foam::OSstream::precision(const int p)
341 {
342  return os_.precision(p);
343 }
344 
345 
346 // ************************************************************************* //
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:747
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:294
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:264
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:327
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:240
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:255
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:801
word format(conversionProperties.get< word >("format"))
virtual void indent() override
Add indentation characters.
Definition: OSstream.C:278
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:629
const dimensionedScalar c
Speed of light in a vacuum.
virtual void flush() override
Flush stream.
Definition: OSstream.C:288
virtual int width() const override
Get width of output field.
Definition: OSstream.C:315
virtual char fill() const override
Get the current padding character.
Definition: OSstream.C:303
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 ...