UIPstream.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-2020 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 "UIPstream.H"
31 #include "int.H"
32 #include "token.H"
33 #include <cctype>
34 
35 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
36 
37 namespace Foam
38 {
39 
40 // Convert a single character to a word with length 1
41 inline static Foam::word charToWord(char c)
42 {
43  return Foam::word(std::string(1, c), false);
44 }
45 
46 
47 // Adjust stream format based on the flagMask
48 inline static void processFlags(Istream& is, int flagMask)
49 {
50  if ((flagMask & token::ASCII))
51  {
53  }
54  else if ((flagMask & token::BINARY))
55  {
57  }
58 }
59 
60 } // End anonymous namespace
61 
62 
63 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
64 
65 inline void Foam::UIPstream::checkEof()
66 {
67  if (externalBufPosition_ == messageSize_)
68  {
69  setEof();
70  }
71 }
72 
73 
74 inline void Foam::UIPstream::prepareBuffer(const size_t align)
75 {
76  if (align > 1)
77  {
78  externalBufPosition_ =
79  align + ((externalBufPosition_ - 1) & ~(align - 1));
80  }
81 }
82 
83 
84 template<class T>
85 inline void Foam::UIPstream::readFromBuffer(T& val)
86 {
87  prepareBuffer(sizeof(T));
88 
89  val = reinterpret_cast<T&>(externalBuf_[externalBufPosition_]);
90  externalBufPosition_ += sizeof(T);
91  checkEof();
92 }
93 
94 
95 inline void Foam::UIPstream::readFromBuffer
96 (
97  void* data,
98  const size_t count
99 )
100 {
101  const char* const __restrict__ buf = &externalBuf_[externalBufPosition_];
102  char* const __restrict__ output = reinterpret_cast<char*>(data);
103 
104  for (size_t i = 0; i < count; ++i)
105  {
106  output[i] = buf[i];
107  }
108 
109  externalBufPosition_ += count;
110  checkEof();
111 }
112 
113 
114 inline Foam::Istream& Foam::UIPstream::readStringFromBuffer(std::string& str)
115 {
116  // Use std::string::assign() to copy content, including '\0'.
117  // Stripping (when desired) is the responsibility of the sending side.
118 
119  size_t len;
120  readFromBuffer(len);
121 
122  if (len)
123  {
124  str.assign(&externalBuf_[externalBufPosition_], len);
125  externalBufPosition_ += len;
126  checkEof();
127  }
128  else
129  {
130  str.clear();
131  }
132 
133  return *this;
134 }
135 
136 
137 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
138 
140 {
141  if (clearAtEnd_ && eof())
142  {
143  if (debug)
144  {
145  Pout<< "UIPstream::~UIPstream() : tag:" << tag_
146  << " fromProcNo:" << fromProcNo_
147  << " clearing externalBuf_ of size "
148  << externalBuf_.size()
149  << " messageSize_:" << messageSize_ << endl;
150  }
151  externalBuf_.clearStorage();
152  }
153 }
154 
155 
156 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
157 
159 {
160  // Return the put back token if it exists
161  // - with additional handling for special stream flags
162  if (Istream::getBack(t))
163  {
164  if (t.isFlag())
165  {
166  processFlags(*this, t.flagToken());
167  }
168  else
169  {
170  return *this;
171  }
172  }
173 
174  // Read character, return on error
175  // - with additional handling for special stream flags
176 
177  char c;
178  do
179  {
180  if (!read(c))
181  {
182  t.setBad(); // Error
183  return *this;
184  }
185 
186  if (c == token::FLAG)
187  {
188  char flagVal;
189 
190  if (read(flagVal))
191  {
192  processFlags(*this, flagVal);
193  }
194  else
195  {
196  t.setBad(); // Error
197  return *this;
198  }
199  }
200  }
201  while (c == token::FLAG);
202 
203 
204  // Set the line number of this token to the current stream line number
205  t.lineNumber() = lineNumber();
206 
207  // Analyse input starting with this character.
208  switch (c)
209  {
210  // Punctuation
211  case token::END_STATEMENT :
212  case token::BEGIN_LIST :
213  case token::END_LIST :
214  case token::BEGIN_SQR :
215  case token::END_SQR :
216  case token::BEGIN_BLOCK :
217  case token::END_BLOCK :
218  case token::COLON :
219  case token::COMMA :
220  case token::ASSIGN :
221  case token::ADD :
222  case token::SUBTRACT :
223  case token::MULTIPLY :
224  case token::DIVIDE :
225  {
227  return *this;
228  }
229 
230  // Word/directive
231  case token::tokenType::WORD :
232  case token::tokenType::DIRECTIVE :
233  {
234  word val;
235  if (read(val))
236  {
238  {
239  t = token::compound::New(val, *this).ptr();
240  }
241  else
242  {
243  t = std::move(val);
245  }
246  }
247  else
248  {
249  t.setBad();
250  }
251  return *this;
252  }
253 
254  // String types
255  case token::tokenType::STRING :
256  case token::tokenType::VARIABLE :
257  case token::tokenType::VERBATIM :
258  {
259  string val;
260  if (read(val))
261  {
262  t = std::move(val);
264  }
265  else
266  {
267  t.setBad();
268  }
269  return *this;
270  }
271 
272  // Label
273  case token::tokenType::LABEL :
274  {
275  label val;
276  if (read(val))
277  {
278  t = val;
279  }
280  else
281  {
282  t.setBad();
283  }
284  return *this;
285  }
286 
287  // Float
288  case token::tokenType::FLOAT :
289  {
290  floatScalar val;
291  if (read(val))
292  {
293  t = val;
294  }
295  else
296  {
297  t.setBad();
298  }
299  return *this;
300  }
301 
302  // Double
303  case token::tokenType::DOUBLE :
304  {
305  doubleScalar val;
306  if (read(val))
307  {
308  t = val;
309  }
310  else
311  {
312  t.setBad();
313  }
314  return *this;
315  }
316 
317  // Character (returned as a single character word) or error
318  default:
319  {
320  if (isalpha(c))
321  {
322  t = charToWord(c);
323  return *this;
324  }
325 
326  setBad();
327  t.setBad();
328 
329  return *this;
330  }
331  }
332 }
333 
334 
336 {
337  c = externalBuf_[externalBufPosition_];
338  ++externalBufPosition_;
339  checkEof();
340  return *this;
341 }
342 
343 
345 {
346  return readStringFromBuffer(str);
347 }
348 
349 
351 {
352  return readStringFromBuffer(str);
353 }
354 
355 
357 {
358  readFromBuffer(val);
359  return *this;
360 }
361 
362 
364 {
365  readFromBuffer(val);
366  return *this;
367 }
368 
369 
371 {
372  readFromBuffer(val);
373  return *this;
374 }
375 
376 
378 {
379  beginRawRead();
380  readRaw(data, count);
381  endRawRead();
382 
383  return *this;
384 }
385 
386 
388 {
389  // No check for format() == BINARY since this is either done in the
390  // beginRawRead() method, or the caller knows what they are doing.
391 
392  // Any alignment must have been done prior to this call
393  readFromBuffer(data, count);
394  return *this;
395 }
396 
397 
399 {
400  if (format() != BINARY)
401  {
403  << "stream format not binary"
405  }
406 
407  // Alignment = 8, as per read(const char*, streamsize)
408  prepareBuffer(8);
409 
410  return true;
411 }
412 
413 
415 {
416  externalBufPosition_ = 0;
417 }
418 
419 
421 {
422  os << "Reading from processor " << fromProcNo_
423  << " using communicator " << comm_
424  << " and tag " << tag_
425  << Foam::endl;
426 }
427 
428 
429 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::token::SUBTRACT
Subtract or start of negative number.
Definition: token.H:138
Foam::token::ASSIGN
Assignment/equals [isseparator].
Definition: token.H:136
token.H
Foam::doubleScalar
double doubleScalar
A typedef for double.
Definition: scalarFwd.H:48
Foam::token::COMMA
Comma [isseparator].
Definition: token.H:129
int.H
System signed integer.
Foam::output
static Ostream & output(Ostream &os, const IntRange< T > &range)
Definition: IntRanges.C:66
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
Foam::token::lineNumber
label lineNumber() const noexcept
The line number for the token.
Definition: tokenI.H:387
Foam::floatScalar
float floatScalar
A typedef for float.
Definition: scalarFwd.H:45
Foam::read
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition: int32.H:108
Foam::UIPstream::rewind
void rewind()
Rewind the stream so that it may be read again.
Definition: UIPstream.C:414
Foam::IOstream::setEof
void setEof()
Set stream to have reached eof.
Definition: IOstream.H:348
Foam::IOstreamOption::format
streamFormat format() const noexcept
Get the current stream format.
Definition: IOstreamOption.H:289
Foam::charToWord
static Foam::word charToWord(char c)
Definition: UIPstream.C:41
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:350
Foam::token
A token holds an item read from Istream.
Definition: token.H:68
Foam::Pout
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Foam::UIPstream::read
static label read(const commsTypes commsType, const int fromProcNo, char *buf, const std::streamsize bufSize, const int tag=UPstream::msgType(), const label communicator=0)
Read into given buffer from given processor and return the.
Definition: UIPread.C:81
Foam::token::DIVIDE
Divide [isseparator].
Definition: token.H:140
format
word format(conversionProperties.get< word >("format"))
Foam::token::BINARY
BINARY-mode stream.
Definition: token.H:109
error.H
Foam::token::BEGIN_SQR
Begin dimensions [isseparator].
Definition: token.H:124
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
Foam::token::ASCII
ASCII-mode stream.
Definition: token.H:108
Foam::T
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
Definition: FieldFieldFunctions.C:58
Foam::processFlags
static void processFlags(Istream &is, int flagMask)
Definition: UIPstream.C:48
Foam::token::isFlag
bool isFlag() const noexcept
Token is FLAG.
Definition: tokenI.H:435
Foam::UIPstream::~UIPstream
~UIPstream()
Destructor.
Definition: UIPstream.C:139
Foam::token::END_STATEMENT
End entry [isseparator].
Definition: token.H:121
Foam::token::compound::isCompound
static bool isCompound(const word &name)
Test if name is a known (registered) compound type.
Definition: token.C:80
Foam::UIPstream::print
void print(Ostream &os) const
Print stream description to Ostream.
Definition: UIPstream.C:420
Foam::token::END_BLOCK
End block [isseparator].
Definition: token.H:127
Foam::token::tokenType
tokenType
Enumeration defining the types of token.
Definition: token.H:75
Foam::FatalError
error FatalError
Foam::token::END_SQR
End dimensions [isseparator].
Definition: token.H:125
Foam::token::MULTIPLY
Multiply [isseparator].
Definition: token.H:139
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::token::BEGIN_BLOCK
Begin block [isseparator].
Definition: token.H:126
Foam::UIPstream::readRaw
Istream & readRaw(char *data, std::streamsize count)
Low-level raw binary read.
Definition: UIPstream.C:387
Foam::token::FLAG
stream flag (1-byte bitmask)
Definition: token.H:80
Foam::Istream::getBack
bool getBack(token &tok)
Get the put back token if there is one and return true.
Definition: Istream.C:75
Foam::IOstreamOption::BINARY
"binary"
Definition: IOstreamOption.H:73
Foam::IOstreamOption::ASCII
"ascii" (normal default)
Definition: IOstreamOption.H:72
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:381
Foam::token::COLON
Colon [isseparator].
Definition: token.H:128
Foam::BitOps::count
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
Definition: BitOps.H:77
Foam::token::END_LIST
End list [isseparator].
Definition: token.H:123
Foam::constant::universal::c
const dimensionedScalar c
Speed of light in a vacuum.
Foam::token::flagToken
int flagToken() const
Return flag bitmask value.
Definition: tokenI.H:441
Foam::token::compound::New
static autoPtr< compound > New(const word &type, Istream &is)
Construct compound from Istream.
Definition: token.C:56
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::token::BEGIN_LIST
Begin list [isseparator].
Definition: token.H:122
Foam::UIPstream::beginRawRead
bool beginRawRead()
Start of low-level raw binary read.
Definition: UIPstream.C:398
Foam::token::setType
bool setType(const tokenType tokType) noexcept
Change the token type, for similar types.
Definition: tokenI.H:315
UIPstream.H
Foam::data
Database for solution data, solver performance and other reduced data.
Definition: data.H:55
Foam::token::punctuationToken
punctuationToken
Standard punctuation tokens (a character)
Definition: token.H:114
Foam::token::ADD
Addition [isseparator].
Definition: token.H:137
Foam::token::setBad
void setBad()
Clear token and set to be ERROR.
Definition: tokenI.H:688