UOPstreamBase.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-2017 OpenFOAM Foundation
9  Copyright (C) 2016-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 "UOPstream.H"
30 #include "int.H"
31 #include "token.H"
32 #include <cctype>
33 
34 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
35 
36 namespace Foam
37 {
38 
39 // Return the position with word boundary alignment
40 inline static label byteAlign(const label pos, const size_t align)
41 {
42  return
43  (
44  (align > 1)
45  ? (align + ((pos - 1) & ~(align - 1)))
46  : pos
47  );
48 }
49 
50 } // End namespace Foam
51 
52 
53 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
54 
55 inline void Foam::UOPstreamBase::prepareBuffer
56 (
57  const size_t count,
58  const size_t align
59 )
60 {
61  if (!count)
62  {
63  return;
64  }
65 
66  // Align for the next output position
67  const label pos = byteAlign(sendBuf_.size(), align);
68 
69  // Extend buffer (as required)
70  sendBuf_.reserve(max(1000, label(pos + count)));
71 
72  // Move to the aligned output position. Fill any gap with nul char.
73  sendBuf_.resize(pos, '\0');
74 }
75 
76 
77 template<class T>
78 inline void Foam::UOPstreamBase::writeToBuffer(const T& val)
79 {
80  writeToBuffer(&val, sizeof(T), sizeof(T));
81 }
82 
83 
84 inline void Foam::UOPstreamBase::writeToBuffer
85 (
86  const void* data,
87  const size_t count,
88  const size_t align
89 )
90 {
91  if (!count)
92  {
93  return;
94  }
95 
96  prepareBuffer(count, align);
97 
98  // The aligned output position
99  const label pos = sendBuf_.size();
100 
101  // Extend the addressable range for direct pointer access
102  sendBuf_.resize(pos + count);
103 
104  char* const __restrict__ buf = (sendBuf_.data() + pos);
105  const char* const __restrict__ input = reinterpret_cast<const char*>(data);
106 
107  for (size_t i = 0; i < count; ++i)
108  {
109  buf[i] = input[i];
110  }
111 }
112 
113 
114 inline void Foam::UOPstreamBase::putChar(const char c)
115 {
116  if (!sendBuf_.capacity())
117  {
118  sendBuf_.setCapacity(1000);
119  }
120  sendBuf_.push_back(c);
121 }
122 
123 
124 inline void Foam::UOPstreamBase::putString
125 (
126  const char* str,
127  const size_t len
128 )
129 {
130  writeToBuffer(len);
131  writeToBuffer(str, len, 1); // no-op when len == 0
132 }
133 
134 
135 inline void Foam::UOPstreamBase::putString(const std::string& str)
136 {
137  putString(str.data(), str.size());
138 }
139 
140 
141 // * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
142 
144 (
145  const UPstream::commsTypes commsType,
146  const int toProcNo,
147  DynamicList<char>& sendBuf,
148  const int tag,
149  const label comm,
150  const bool sendAtDestruct,
152 )
153 :
154  UPstream(commsType),
155  Ostream(fmt),
156  toProcNo_(toProcNo),
157  tag_(tag),
158  comm_(comm),
159  sendAtDestruct_(sendAtDestruct),
160  sendBuf_(sendBuf)
161 {
162  setOpened();
163  setGood();
164 }
165 
166 
167 Foam::UOPstreamBase::UOPstreamBase(const int toProcNo, PstreamBuffers& buffers)
168 :
169  UPstream(buffers.commsType()),
170  Ostream(buffers.format()),
171  toProcNo_(toProcNo),
172  tag_(buffers.tag()),
173  comm_(buffers.comm()),
174  sendAtDestruct_(buffers.commsType() != UPstream::commsTypes::nonBlocking),
175  sendBuf_(buffers.accessSendBuffer(toProcNo))
176 {
177  setOpened();
178  setGood();
179 }
180 
181 
183 (
184  DynamicList<char>& sendBuf,
186 )
187 :
188  UPstream(UPstream::commsTypes::nonBlocking), // placeholder
189  Ostream(fmt),
190  toProcNo_(UPstream::masterNo()), // placeholder
191  tag_(UPstream::msgType()), // placeholder
192  comm_(UPstream::commSelf()), // placeholder
193  sendAtDestruct_(false), // Never sendAtDestruct!!
194  sendBuf_(sendBuf)
195 {
196  sendBuf_.clear(); // Overwrite into buffer
198  setGood();
199 }
200 
201 
202 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
205 {}
206 
207 
208 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
209 
210 bool Foam::UOPstreamBase::write(const token& tok)
211 {
212  // Direct token handling only for some types
213 
214  switch (tok.type())
215  {
216  case token::tokenType::FLAG :
217  {
218  putChar(token::tokenType::FLAG);
219  putChar(tok.flagToken());
220 
221  return true;
222  }
223 
224  // The word-variants
225  case token::tokenType::WORD :
226  case token::tokenType::DIRECTIVE :
227  {
228  putChar(tok.type());
229  putString(tok.wordToken());
230 
231  return true;
232  }
233 
234  // The string-variants
235  case token::tokenType::STRING :
236  case token::tokenType::EXPRESSION :
237  case token::tokenType::VARIABLE :
238  case token::tokenType::VERBATIM :
239  case token::tokenType::CHAR_DATA :
240  {
241  putChar(tok.type());
242  putString(tok.stringToken());
243 
244  return true;
245  }
246 
247  default:
248  break;
249  }
250 
251  return false;
252 }
253 
254 
256 {
257  if (!isspace(c))
258  {
259  putChar(c);
260  }
261 
262  return *this;
263 }
264 
265 
267 (
268  const char* str,
269  std::streamsize len,
270  const bool quoted
271 )
272 {
273  if (quoted)
274  {
275  putChar(token::tokenType::STRING);
276  }
277  else
278  {
279  putChar(token::tokenType::WORD);
280  }
281  putString(str, len);
282 
283  return *this;
284 }
285 
286 
288 {
289  const word nonWhiteChars(string::validate<word>(str));
290 
291  if (nonWhiteChars.size() == 1)
292  {
293  return write(nonWhiteChars[0]);
294  }
295  else if (nonWhiteChars.size())
296  {
297  return write(nonWhiteChars);
298  }
299 
300  return *this;
301 }
302 
303 
305 {
306  putChar(token::tokenType::WORD);
307  putString(str);
308 
309  return *this;
310 }
311 
312 
313 Foam::Ostream& Foam::UOPstreamBase::write(const std::string& str)
314 {
315  putChar(token::tokenType::STRING);
316  putString(str);
317 
318  return *this;
319 }
320 
321 
322 Foam::Ostream& Foam::UOPstreamBase::write(const int32_t val)
323 {
324  putChar(token::tokenType::LABEL);
325  writeToBuffer(val);
326  return *this;
327 }
328 
329 
330 Foam::Ostream& Foam::UOPstreamBase::write(const int64_t val)
331 {
332  putChar(token::tokenType::LABEL);
333  writeToBuffer(val);
334  return *this;
335 }
336 
337 
339 {
340  putChar(token::tokenType::FLOAT);
341  writeToBuffer(val);
342  return *this;
343 }
344 
345 
346 Foam::Ostream& Foam::UOPstreamBase::write(const double val)
347 {
348  putChar(token::tokenType::DOUBLE);
349  writeToBuffer(val);
350  return *this;
351 }
352 
353 
355 (
356  const char* data,
357  std::streamsize count
358 )
359 {
361  {
363  << "stream format not binary"
365  }
366 
367  // Align on word boundary (64-bit)
368  writeToBuffer(data, count, 8);
369 
370  return *this;
371 }
372 
373 
375 (
376  const char* data,
377  std::streamsize count
378 )
379 {
380  // No check for IOstreamOption::BINARY since this is either done in the
381  // beginRawWrite() method, or the caller knows what they are doing.
382 
383  // Previously aligned and sizes reserved via beginRawWrite()
384  writeToBuffer(data, count, 1);
385 
386  return *this;
387 }
388 
389 
390 bool Foam::UOPstreamBase::beginRawWrite(std::streamsize count)
391 {
393  {
395  << "stream format not binary"
397  }
398 
399  // Align on word boundary (64-bit)
400  // - as per write(const char*, streamsize)
401  prepareBuffer(count, 8);
402 
403  return true;
404 }
405 
406 
407 // Not needed yet
416 
417 
419 {
420  sendBuf_.clear(); // Overwrite into buffer
421  setOpened();
422  setGood();
423 }
424 
425 
427 {
428  os << "Writing to processor " << toProcNo_
429  << " from processor " << myProcNo() << " in communicator " << comm_
430  << " and tag " << tag_ << Foam::endl;
431 }
432 
433 
434 // ************************************************************************* //
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
static label byteAlign(const label pos, const size_t align)
Definition: UIPstreamBase.C:55
System signed integer.
commsTypes
Communications types.
Definition: UPstream.H:72
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
virtual Ostream & writeRaw(const char *data, std::streamsize count) override
Low-level raw binary output.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:40
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
void resize(const label len)
Alter addressable list size, allocating new space if required while recovering old content...
Definition: DynamicListI.H:353
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
tokenType type() const noexcept
Return the token type.
Definition: tokenI.H:405
virtual bool beginRawWrite(std::streamsize count) override
Begin marker for low-level raw binary output.
int flagToken() const
Return flag bitmask value.
Definition: tokenI.H:549
dimensionedScalar pos(const dimensionedScalar &ds)
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
UOPstreamBase(const UPstream::commsTypes commsType, const int toProcNo, DynamicList< char > &sendBuf, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm, const bool sendAtDestruct=true, IOstreamOption::streamFormat fmt=IOstreamOption::BINARY)
Construct given process index to write to using the given attached send buffer, optional communicatio...
static Istream & input(Istream &is, IntRange< T > &range)
Definition: IntRanges.C:33
DynamicList< char > & sendBuf_
Reference to the send buffer data.
Definition: UOPstream.H:127
virtual void rewind()
Rewind the send buffer for overwriting.
errorManip< error > abort(error &err)
Definition: errorManip.H:139
void reserve(const label len)
Reserve allocation space for at least this size, allocating new space if required and retaining old c...
Definition: DynamicListI.H:333
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
OBJstream os(runTime.globalPath()/outputName)
void clear() noexcept
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:405
Buffers for inter-processor communications streams (UOPstream, UIPstream).
const string & stringToken() const
Return const reference to the string contents.
Definition: tokenI.H:783
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
virtual Ostream & writeQuoted(const char *str, std::streamsize len, const bool quoted=true) override
Write character/string content, with/without surrounding quotes.
virtual ~UOPstreamBase()
Destructor.
word format(conversionProperties.get< word >("format"))
void print(Ostream &os) const override
Print stream description to Ostream.
const dimensionedScalar c
Speed of light in a vacuum.
bool isspace(char c) noexcept
Test for whitespace (C-locale)
Definition: char.H:69
streamFormat
Data format (ascii | binary)
void setOpened() noexcept
Set stream opened.
Definition: IOstream.H:150
void setGood() noexcept
Set stream state to be good.
Definition: IOstream.H:174
virtual bool write(const token &tok) override
Write token to stream or otherwise handle it.
Inter-processor communications stream.
Definition: UPstream.H:60
Namespace for OpenFOAM.