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-2022 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_.append(c);
121 }
122 
123 
124 inline void Foam::UOPstreamBase::putString(const std::string& str)
125 {
126  const size_t len = str.size();
127  writeToBuffer(len);
128  writeToBuffer(str.data(), len, 1); // no-op when len == 0
129 }
130 
131 
132 // * * * * * * * * * * * * * * * * Constructor * * * * * * * * * * * * * * * //
133 
135 (
136  const commsTypes commsType,
137  const int toProcNo,
138  DynamicList<char>& sendBuf,
139  const int tag,
140  const label comm,
141  const bool sendAtDestruct,
143 )
144 :
145  UPstream(commsType),
146  Ostream(fmt),
147  toProcNo_(toProcNo),
148  sendBuf_(sendBuf),
149  tag_(tag),
150  comm_(comm),
151  sendAtDestruct_(sendAtDestruct)
152 {
153  setOpened();
154  setGood();
155 }
156 
157 
158 Foam::UOPstreamBase::UOPstreamBase(const int toProcNo, PstreamBuffers& buffers)
159 :
160  UPstream(buffers.commsType()),
161  Ostream(buffers.format()),
162  toProcNo_(toProcNo),
163  sendBuf_(buffers.sendBuf_[toProcNo]),
164  tag_(buffers.tag()),
165  comm_(buffers.comm()),
166  sendAtDestruct_(buffers.commsType() != UPstream::commsTypes::nonBlocking)
167 {
169  setGood();
170 }
171 
172 
173 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
176 {}
177 
178 
179 // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
180 
181 bool Foam::UOPstreamBase::write(const token& tok)
182 {
183  // Direct token handling only for some types
184 
185  switch (tok.type())
186  {
187  case token::tokenType::FLAG :
188  {
189  putChar(token::tokenType::FLAG);
190  putChar(tok.flagToken());
191 
192  return true;
193  }
194 
195  // The word-variants
196  case token::tokenType::WORD :
197  case token::tokenType::DIRECTIVE :
198  {
199  putChar(tok.type());
200  putString(tok.wordToken());
201 
202  return true;
203  }
204 
205  // The string-variants
206  case token::tokenType::STRING :
207  case token::tokenType::EXPRESSION :
208  case token::tokenType::VARIABLE :
209  case token::tokenType::VERBATIM :
210  {
211  putChar(tok.type());
212  putString(tok.stringToken());
213 
214  return true;
215  }
216 
217  default:
218  break;
219  }
220 
221  return false;
222 }
223 
224 
226 {
227  if (!isspace(c))
228  {
229  putChar(c);
230  }
231 
232  return *this;
233 }
234 
235 
237 {
238  const word nonWhiteChars(string::validate<word>(str));
239 
240  if (nonWhiteChars.size() == 1)
241  {
242  return write(nonWhiteChars[0]);
243  }
244  else if (nonWhiteChars.size())
245  {
246  return write(nonWhiteChars);
247  }
248 
249  return *this;
250 }
251 
252 
254 {
255  putChar(token::tokenType::WORD);
256  putString(str);
257 
258  return *this;
259 }
260 
261 
262 Foam::Ostream& Foam::UOPstreamBase::write(const string& str)
263 {
264  putChar(token::tokenType::STRING);
265  putString(str);
266 
267  return *this;
268 }
269 
270 
272 (
273  const std::string& str,
274  const bool quoted
275 )
276 {
277  if (quoted)
278  {
279  putChar(token::tokenType::STRING);
280  }
281  else
282  {
283  putChar(token::tokenType::WORD);
284  }
285  putString(str);
286 
287  return *this;
288 }
289 
290 
291 Foam::Ostream& Foam::UOPstreamBase::write(const int32_t val)
292 {
293  putChar(token::tokenType::LABEL);
294  writeToBuffer(val);
295  return *this;
296 }
297 
298 
299 Foam::Ostream& Foam::UOPstreamBase::write(const int64_t val)
300 {
301  putChar(token::tokenType::LABEL);
302  writeToBuffer(val);
303  return *this;
304 }
305 
306 
308 {
309  putChar(token::tokenType::FLOAT);
310  writeToBuffer(val);
311  return *this;
312 }
313 
314 
315 Foam::Ostream& Foam::UOPstreamBase::write(const double val)
316 {
317  putChar(token::tokenType::DOUBLE);
318  writeToBuffer(val);
319  return *this;
320 }
321 
322 
324 (
325  const char* data,
326  std::streamsize count
327 )
328 {
329  if (format() != BINARY)
330  {
332  << "stream format not binary"
334  }
335 
336  // Align on word boundary (64-bit)
337  writeToBuffer(data, count, 8);
338 
339  return *this;
340 }
341 
342 
344 (
345  const char* data,
346  std::streamsize count
347 )
348 {
349  // No check for format() == BINARY since this is either done in the
350  // beginRawWrite() method, or the caller knows what they are doing.
351 
352  // Previously aligned and sizes reserved via beginRawWrite()
353  writeToBuffer(data, count, 1);
354 
355  return *this;
356 }
357 
358 
359 bool Foam::UOPstreamBase::beginRawWrite(std::streamsize count)
360 {
361  if (format() != BINARY)
362  {
364  << "stream format not binary"
366  }
367 
368  // Align on word boundary (64-bit)
369  // - as per write(const char*, streamsize)
370  prepareBuffer(count, 8);
371 
372  return true;
373 }
374 
375 
376 // Not needed yet
385 
386 
388 {
389  sendBuf_.clear(); // Overwrite into buffer
390  setOpened();
391  setGood();
392 }
393 
394 
396 {
397  os << "Writing from processor " << toProcNo_
398  << " to processor " << myProcNo() << " in communicator " << comm_
399  << " and tag " << tag_ << Foam::endl;
400 }
401 
402 
403 // ************************************************************************* //
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:118
static label byteAlign(const label pos, const size_t align)
Definition: UIPstreamBase.C:55
System signed integer.
virtual bool write(const token &tok)
Write token to stream or otherwise handle it.
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:578
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:624
A token holds an item read from Istream.
Definition: token.H:64
void resize(const label len)
Alter addressable list size, allocating new space if required while recovering old content...
Definition: DynamicListI.H:346
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:487
tokenType type() const noexcept
Return the token type.
Definition: tokenI.H:304
UOPstreamBase(const 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...
int flagToken() const
Return flag bitmask value.
Definition: tokenI.H:440
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
virtual bool beginRawWrite(std::streamsize count)
Begin marker for low-level raw binary output.
void print(Ostream &os) const
Print stream description to Ostream.
static Istream & input(Istream &is, IntRange< T > &range)
Definition: IntRanges.C:48
virtual Ostream & writeQuoted(const std::string &str, const bool quoted=true)
Write std::string surrounded by quotes.
DynamicList< char > & sendBuf_
Definition: UOPstream.H:103
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:326
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:55
OBJstream os(runTime.globalPath()/outputName)
Database for solution data, solver performance and other reduced data.
Definition: data.H:51
Buffers for inter-processor communications streams (UOPstream, UIPstream).
const string & stringToken() const
Return const reference to the string contents.
Definition: tokenI.H:682
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
virtual ~UOPstreamBase()
Destructor.
word format(conversionProperties.get< word >("format"))
virtual Ostream & writeRaw(const char *data, std::streamsize count)
Low-level raw binary output.
const dimensionedScalar c
Speed of light in a vacuum.
bool isspace(char c) noexcept
Test for whitespace (C-locale)
Definition: char.H:71
streamFormat
Data format (ascii | binary)
void setOpened() noexcept
Set stream opened.
Definition: IOstream.H:143
void setGood() noexcept
Set stream state to be good.
Definition: IOstream.H:167
Inter-processor communications stream.
Definition: UPstream.H:54
Namespace for OpenFOAM.