OListStream.H
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) 2017-2022 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 Class
27  Foam::OListStream
28 
29 Description
30  An output stream that writes to a List and manages the List storage.
31  Similar to OStringStream but with a List for its storage instead of
32  as string to allow reuse of List contents without copying.
33 
34  The default list size is 512-bytes with a 256-byte block increment.
35  These values can be changed after construction using the reserve() and
36  the setBlockSize() methods.
37 
38 See Also
39  Foam::IListStream
40  Foam::UOListStream
41  Foam::UIListStream
42 
43 \*---------------------------------------------------------------------------*/
44 
45 #ifndef Foam_OListStream_H
46 #define Foam_OListStream_H
47 
48 #include "DynamicList.H"
49 #include "OSstream.H"
50 #include "memoryStreamBuffer.H"
51 
52 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
53 
54 namespace Foam
55 {
56 
57 namespace Detail
58 {
59 
60 /*---------------------------------------------------------------------------*\
61  Class Detail::OListStreamAllocator Declaration
62 \*---------------------------------------------------------------------------*/
63 
64 //- An stream/stream-buffer output allocator with DynamicList-like storage
66 {
67  //- A streambuf adapter with resizing similar to DynamicList
68  class dynbuf
69  :
70  public memorybuf::out
71  {
72  friend class OListStreamAllocator;
73 
74  //- Helper for block size - small list minimum of 64 bytes.
75  constexpr static int min_size(int n)
76  {
77  return stdFoam::max(64, n);
78  }
79 
80  //- Block size when resizing the list
81  int block_ = 256;
82 
83  //- Underlying list storage.
84  // Internally manage like a DynamicList, with its capacity known
85  // from the list size and the addressable size known through the
86  // stream pointers.
87  List<char> storage_;
88 
89 
90  protected:
91 
92  //- Increment capacity directly and adjust buffer pointers to
93  //- correspond with the storage size.
94  inline void minCapacity
95  (
96  const std::streamsize n,
97  const std::streamsize cur = 0
98  )
99  {
100  const auto newEnd = n + cur;
101  if (newEnd > storage_.size())
102  {
103  auto newCapacity =
104  (
105  (storage_.size() + block_)
106  - (storage_.size() % block_)
107  );
108 
109  while (newCapacity < newEnd)
110  {
111  newCapacity += block_;
112  }
113 
114  // Info<<"request:" << newEnd
115  // << " cur cap:" << storage_.size()
116  // << " new cap:" << newCapacity
117  // << " pos:" << cur
118  // << " incr:" << incr << endl;
119 
120  storage_.resize(newCapacity);
121  sync_pbuffer();
122  pbump(cur);
123  }
124  }
125 
126  //- Define new increment
127  inline void setBlockSize(const int i)
128  {
129  const auto prev = block_;
130  block_ = min_size(i);
131 
132  if (block_ > prev)
133  {
134  minCapacity(0, tellp());
135  }
136  }
137 
138  //- Handle overflow
139  virtual int overflow(int c = EOF)
140  {
141  if (c != EOF)
142  {
143  // Need another output block
144  minCapacity(block_, tellp());
145 
146  *(pptr()) = c;
147  pbump(1);
148  }
149  return c;
150  }
151 
152 
153  //- Put sequence of characters
154  virtual std::streamsize xsputn(const char* s, std::streamsize n)
155  {
156  // Enough space so that appends work without problem
157  minCapacity(n, tellp());
158 
159  std::streamsize count = 0;
160  while (count < n && pptr() < epptr())
161  {
162  *(pptr()) = *(s + count++);
163  pbump(1);
164  }
165 
166  return count;
167  }
168 
169  //- Initialize put buffer
170  void init_pbuffer(const std::streamsize n)
171  {
172  sync_pbuffer();
173  minCapacity(n);
174  }
175 
176 
177  public:
178 
179  // Constructors
180 
181  //- Default construct, with initial reserved number of bytes
182  dynbuf(size_t nbytes = 512)
183  :
184  storage_()
185  {
186  init_pbuffer(min_size(nbytes));
187  }
188 
189  //- Move construct from List
190  dynbuf(List<char>&& buffer)
191  :
192  storage_(std::move(buffer))
193  {
194  init_pbuffer(block_);
195  }
196 
197  //- Move construct from DynamicList.
198  template<int SizeMin>
199  dynbuf(DynamicList<char,SizeMin>&& buffer)
200  :
201  storage_(std::move(buffer))
202  {
203  init_pbuffer(block_);
204  }
205 
206 
207  // Member Functions
208 
209  //- Return the current list output capacity
210  inline label capacity() const
211  {
212  return storage_.size();
213  }
214 
215  //- Sync put buffer pointers to agree with list dimensions
216  // Sets put pointer to the begin (rewind).
217  inline void sync_pbuffer()
218  {
219  resetp(storage_.data(), storage_.size());
220  }
221 
222  //- Clear storage
223  inline void clearStorage()
224  {
225  storage_.clear();
226  sync_pbuffer();
227  }
228 
229  //- Shrink storage to addressed storage
230  inline void shrink()
231  {
232  const auto cur = tellp(); // Addressed area
233 
234  storage_.resize(cur);
235  sync_pbuffer();
236  pbump(cur);
237  }
238 
239  //- Transfer list contents to other List
240  inline void swap(List<char>& other)
241  {
242  const auto cur = tellp(); // Addressed area
243 
244  storage_.swap(other);
245  storage_.resize(cur);
246  sync_pbuffer();
247  }
248 
249  //- Transfer list contents to a DynamicList
250  template<int SizeMin>
251  inline void swap(DynamicList<char,SizeMin>& other)
252  {
253  const auto cur = tellp(); // Addressed area
254 
255  storage_.swap(other); // Swap full list
256  other.setCapacity(other.size());
257  other.resize(cur);
258  sync_pbuffer();
259  }
260  };
261 
262 
263 protected:
264 
265  // Protected Data
266 
267  typedef std::ostream stream_type;
268 
269  //- The stream buffer
270  dynbuf buf_;
271 
272  //- The stream
274 
275 
276  // Constructors
277 
278  //- Default construct, with initial reserved number of bytes
279  OListStreamAllocator(size_t nbytes = 512)
280  :
281  buf_(nbytes),
282  stream_(&buf_)
283  {}
284 
285  //- Move construct from List
287  :
288  buf_(std::move(buffer)),
289  stream_(&buf_)
290  {}
291 
292  //- Move construct from DynamicList
293  template<int SizeMin>
295  :
296  buf_(std::move(buffer)),
297  stream_(&buf_)
298  {}
299 
301  // Protected Member Functions
302 
303  void printBufInfo(Ostream& os) const
304  {
305  os << "put=" << buf_.tellp()
306  << "/" << buf_.capacity()
307  << " block=" << buf_.block_;
308  }
309 
310 public:
311 
312  // Member Functions
313 
314  //- Const UList access to the characters written (shallow copy).
315  inline const UList<char> list() const
316  {
317  return buf_.list();
318  }
319 
320  //- Non-const UList access to the characters written (shallow copy).
321  inline UList<char> list()
322  {
323  return buf_.list();
324  }
325 
326  //- The current list output capacity
327  inline label capacity() const
328  {
329  return buf_.capacity();
330  }
331 
332  //- The current output position in the buffer,
333  //- which is also the addressed list size
334  inline label size() const
335  {
336  return buf_.tellp();
337  }
338 
339  //- Reserve output space for at least this amount.
340  inline void reserve(const std::streamsize n)
341  {
342  // Also maintain current position when resizing
343  const auto cur = buf_.tellp();
344  if (n > cur)
345  {
346  buf_.minCapacity(n - cur, cur);
347  }
348  }
349 
350  //- Adjust block size for output
351  inline void setBlockSize(int n)
352  {
353  return buf_.setBlockSize(n);
354  }
355 
356  //- Transfer list contents to other List
357  inline void swap(List<char>& other)
358  {
359  buf_.swap(other);
360  }
361 
362  //- Transfer list contents to a DynamicList
363  template<int SizeMin>
364  inline void swap(DynamicList<char,SizeMin>& other)
365  {
366  buf_.swap(other);
367  }
369  //- Shrink to addressed space, should not affect stream.
370  inline void shrink()
371  {
372  buf_.shrink();
373  }
374 
375  //- Clear storage
377  {
378  buf_.clearStorage();
379  stream_.clear(); // for safety, clear any old errors
380  }
381 
382  //- Move to buffer start, clear errors
383  void rewind()
384  {
385  buf_.pubseekpos(0, std::ios_base::out);
386  stream_.clear(); // for safety, clear any old errors
387  }
388 };
389 
390 } // End namespace Detail
391 
392 
393 /*---------------------------------------------------------------------------*\
394  Class OListStream Declaration
395 \*---------------------------------------------------------------------------*/
396 
397 //- An OSstream attached to a List
398 class OListStream
399 :
401  public OSstream
402 {
403  typedef Detail::OListStreamAllocator allocator_type;
404 
405 public:
407  // Constructors
408 
409  //- Default construct (empty output)
410  explicit OListStream
411  (
412  IOstreamOption streamOpt = IOstreamOption()
413  )
414  :
415  allocator_type(),
416  OSstream(stream_, "output", streamOpt.format(), streamOpt.version())
417  {}
418 
419  //- Construct with initial reserved number of bytes
420  explicit OListStream
421  (
422  size_t nbytes,
424  )
425  :
426  allocator_type(nbytes),
427  OSstream(stream_, "output", streamOpt.format(), streamOpt.version())
428  {}
429 
430  //- Move construct from an existing List
431  explicit OListStream
432  (
433  List<char>&& buffer,
434  IOstreamOption streamOpt = IOstreamOption()
435  )
436  :
437  allocator_type(std::move(buffer)),
438  OSstream(stream_, "output", streamOpt.format(), streamOpt.version())
439  {}
440 
441  //- Move construct from an existing DynamicList
442  template<int SizeMin>
443  explicit OListStream
444  (
445  DynamicList<char,SizeMin>&& buffer,
446  IOstreamOption streamOpt = IOstreamOption()
447  )
448  :
449  allocator_type(std::move(buffer)),
450  OSstream(stream_, "output", streamOpt.format(), streamOpt.version())
451  {}
452 
453 
454  // Member Functions
455 
456  //- Rewind the stream, clearing any old errors
457  virtual void rewind()
458  {
460  setGood(); // resynchronize with internal state
461  }
462 
463  //- Print stream description to Ostream
464  virtual void print(Ostream& os) const;
466 
467  // Additional constructors and methods (as per v2012 and earlier)
468  #ifdef Foam_IOstream_extras
469 
470  //- Default construct (empty output)
471  explicit OListStream
472  (
474  )
475  :
477  {}
478 
479  //- Construct with initial reserved number of bytes
480  explicit OListStream
481  (
482  size_t nbytes,
484  )
485  :
486  OListStream(nbytes, IOstreamOption(fmt))
487  {}
488 
489  //- Move construct from an existing List
491  (
492  List<char>&& buffer,
494  )
495  :
496  OListStream(std::move(buffer), IOstreamOption(fmt))
497  {}
498 
499  //- Move construct from an existing DynamicList
500  template<int SizeMin>
502  (
503  DynamicList<char,SizeMin>&& buffer,
505  )
506  :
507  OListStream(std::move(buffer), IOstreamOption(fmt))
508  {}
509 
510  #endif /* Foam_IOstream_extras */
511 };
512 
513 
514 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
515 
516 } // End namespace Foam
517 
518 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
520 #endif
521 
522 // ************************************************************************* //
Generic output stream using a standard (STL) stream.
Definition: OSstream.H:50
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:118
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:132
T * data() noexcept
Return pointer to the underlying array serving as data storage.
Definition: UListI.H:230
void resize(const label len)
Alter addressable list size, allocating new space if required while recovering old content...
Definition: DynamicListI.H:346
void reserve(const std::streamsize n)
Reserve output space for at least this amount.
Definition: OListStream.H:393
label size() const
The current output position in the buffer, which is also the addressed list size. ...
Definition: OListStream.H:385
void setCapacity(const label len)
Alter the size of the underlying storage.
Definition: DynamicListI.H:296
A simple container for options an IOstream can normally have.
void shrink()
Shrink to addressed space, should not affect stream.
Definition: OListStream.H:431
void swap(UList< T > &list)
Swap content with another UList of the same type in constant time.
Definition: UListI.H:427
constexpr IOstreamOption(streamFormat fmt=streamFormat::ASCII, compressionType comp=compressionType::UNCOMPRESSED) noexcept
Default construct (ASCII, UNCOMPRESSED, currentVersion) or construct with format, compression...
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of &#39;true&#39; entries.
Definition: BitOps.H:73
constexpr const T & max(const T &a, const T &b)
Return the greater of the parameters.
Definition: stdFoam.H:306
OListStream(IOstreamOption streamOpt=IOstreamOption())
Default construct (empty output)
Definition: OListStream.H:480
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
Definition: DynamicList.H:51
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:109
void printBufInfo(Ostream &os) const
Definition: OListStream.H:346
const UList< char > list() const
Const UList access to the characters written (shallow copy).
Definition: OListStream.H:360
void rewind()
Move to buffer start, clear errors.
Definition: OListStream.H:448
An output streambuf for memory access.
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:99
void clearStorage()
Clear storage.
Definition: OListStream.H:439
An OSstream attached to a List.
Definition: OListStream.H:465
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:55
OBJstream os(runTime.globalPath()/outputName)
An stream/stream-buffer output allocator with DynamicList-like storage.
Definition: OListStream.H:60
OListStreamAllocator(size_t nbytes=512)
Default construct, with initial reserved number of bytes.
Definition: OListStream.H:318
dynbuf buf_
The stream buffer.
Definition: OListStream.H:305
const dimensionedScalar c
Speed of light in a vacuum.
label capacity() const
The current list output capacity.
Definition: OListStream.H:376
versionNumber version() const noexcept
Get the stream version.
void swap(List< char > &other)
Transfer list contents to other List.
Definition: OListStream.H:414
streamFormat
Data format (ascii | binary)
label n
stream_type stream_
The stream.
Definition: OListStream.H:310
void setGood() noexcept
Set stream state to be good.
Definition: IOstream.H:167
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
streamFormat format() const noexcept
Get the current stream format.
virtual void rewind()
Rewind the stream, clearing any old errors.
Definition: OListStream.H:534
void setBlockSize(int n)
Adjust block size for output.
Definition: OListStream.H:406
virtual void print(Ostream &os) const
Print stream description to Ostream.
Definition: ListStream.C:43
Namespace for OpenFOAM.