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-2020 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 OListStream_H
46 #define 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 
300 
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  }
368 
369  //- Shrink to addressed space, should not affect stream.
370  inline void shrink()
371  {
372  buf_.shrink();
373  }
374 
375  //- Clear storage
376  void clearStorage()
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 {
404 
405 public:
406 
407  // Constructors
408 
409  //- Default construct (empty output)
410  explicit OListStream
411  (
414  )
415  :
416  allocator_type(),
417  OSstream(stream_, "output", format, version)
418  {}
419 
420  //- Construct with initial reserved number of bytes
421  explicit OListStream
422  (
423  size_t nbytes,
426  )
427  :
428  allocator_type(nbytes),
429  OSstream(stream_, "output", format, version)
430  {}
431 
432  //- Move construct from an existing List
433  explicit OListStream
434  (
435  List<char>&& buffer,
438  )
439  :
440  allocator_type(std::move(buffer)),
441  OSstream(stream_, "output", format, version)
442  {}
443 
444  //- Move construct from an existing DynamicList
445  template<int SizeMin>
446  explicit OListStream
447  (
448  DynamicList<char,SizeMin>&& buffer,
451  )
452  :
453  allocator_type(std::move(buffer)),
454  OSstream(stream_, "output", format, version)
455  {}
456 
457 
458  // Member Functions
459 
460  //- Rewind the stream, clearing any old errors
461  virtual void rewind()
462  {
464  setGood(); // resynchronize with internal state
465  }
466 
467  //- Print stream description to Ostream
468  virtual void print(Ostream& os) const;
469 };
470 
471 
472 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
473 
474 } // End namespace Foam
475 
476 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
477 
478 #endif
479 
480 // ************************************************************************* //
Foam::Detail::OListStreamAllocator::reserve
void reserve(const std::streamsize n)
Reserve output space for at least this amount.
Definition: OListStream.H:339
Foam::Detail::OListStreamAllocator
An stream/stream-buffer output allocator with DynamicList-like storage.
Definition: OListStream.H:64
s
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))
Definition: gmvOutputSpray.H:25
Foam::Detail::OListStreamAllocator::stream_type
std::ostream stream_type
Definition: OListStream.H:266
Foam::DynamicList
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:55
Foam::Detail::OListStreamAllocator::size
label size() const
Definition: OListStream.H:333
Foam::Detail::OListStreamAllocator::printBufInfo
void printBufInfo(Ostream &os) const
Definition: OListStream.H:302
Foam::IOstreamOption::format
streamFormat format() const noexcept
Get the current stream format.
Definition: IOstreamOption.H:289
Foam::IOstreamOption::currentVersion
static const versionNumber currentVersion
The current version number (2.0)
Definition: IOstreamOption.H:168
Foam::OListStream
An OSstream attached to a List.
Definition: OListStream.H:397
Foam::Detail::OListStreamAllocator::OListStreamAllocator
OListStreamAllocator(size_t nbytes=512)
Default construct, with initial reserved number of bytes.
Definition: OListStream.H:278
Foam::Detail::OListStreamAllocator::list
const UList< char > list() const
Const UList access to the characters written (shallow copy).
Definition: OListStream.H:314
Foam::Detail::OListStreamAllocator::setBlockSize
void setBlockSize(int n)
Adjust block size for output.
Definition: OListStream.H:350
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::IOstreamOption::versionNumber
Representation of a major/minor version number.
Definition: IOstreamOption.H:85
Foam::memorybuf::out
An output streambuf for memory access.
Definition: memoryStreamBuffer.H:240
Foam::Detail::OListStreamAllocator::shrink
void shrink()
Shrink to addressed space, should not affect stream.
Definition: OListStream.H:369
Foam::OSstream::OSstream
OSstream(const OSstream &)=default
Copy construct.
Foam::OSstream
Generic output stream using a standard (STL) stream.
Definition: OSstream.H:54
Foam::List::resize
void resize(const label newSize)
Adjust allocated size of list.
Definition: ListI.H:139
Foam::IOstreamOption::version
versionNumber version() const noexcept
Get the stream version.
Definition: IOstreamOption.H:341
stdFoam::max
constexpr const T & max(const T &a, const T &b)
Return the greater of the parameters.
Definition: stdFoam.H:204
Foam::IOstreamOption::streamFormat
streamFormat
Data format (ascii | binary)
Definition: IOstreamOption.H:70
memoryStreamBuffer.H
Foam::Detail::OListStreamAllocator::capacity
label capacity() const
The current list output capacity.
Definition: OListStream.H:326
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::OListStream::rewind
virtual void rewind()
Rewind the stream, clearing any old errors.
Definition: OListStream.H:460
Foam::Detail::OListStreamAllocator::OListStreamAllocator
OListStreamAllocator(DynamicList< char, SizeMin > &&buffer)
Move construct from DynamicList.
Definition: OListStream.H:293
Foam::Detail::OListStreamAllocator::buf_
dynbuf buf_
The stream buffer.
Definition: OListStream.H:269
Foam::DynamicList::setCapacity
void setCapacity(const label nElem)
Alter the size of the underlying storage.
Definition: DynamicListI.H:232
Foam::DynamicList::resize
void resize(const label nElem)
Alter addressable list size.
Definition: DynamicListI.H:328
Foam::IOstreamOption::ASCII
"ascii" (normal default)
Definition: IOstreamOption.H:72
Foam::Detail::OListStreamAllocator::list
UList< char > list()
Non-const UList access to the characters written (shallow copy).
Definition: OListStream.H:320
Foam::IOstream::setGood
void setGood()
Set stream to be good.
Definition: IOstream.H:141
Foam::OListStream::print
virtual void print(Ostream &os) const
Print stream description to Ostream.
Definition: ListStream.C:50
Foam::BitOps::count
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
Definition: BitOps.H:74
Foam::List< char >
Foam::UList
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:103
Foam::Detail::OListStreamAllocator::swap
void swap(DynamicList< char, SizeMin > &other)
Transfer list contents to a DynamicList.
Definition: OListStream.H:363
Foam::List::clear
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:115
Foam::OListStream::OListStream
OListStream(streamFormat format=ASCII, versionNumber version=currentVersion)
Default construct (empty output)
Definition: OListStream.H:410
Foam::Detail::OListStreamAllocator::rewind
void rewind()
Move to buffer start, clear errors.
Definition: OListStream.H:382
Foam::Detail::OListStreamAllocator::stream_
stream_type stream_
The stream.
Definition: OListStream.H:272
Foam::constant::universal::c
const dimensionedScalar c
Speed of light in a vacuum.
DynamicList.H
Foam::Detail::OListStreamAllocator::OListStreamAllocator
OListStreamAllocator(List< char > &&buffer)
Move construct from List.
Definition: OListStream.H:285
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::Detail::OListStreamAllocator::clearStorage
void clearStorage()
Clear storage.
Definition: OListStream.H:375
Foam::Detail::OListStreamAllocator::swap
void swap(List< char > &other)
Transfer list contents to other List.
Definition: OListStream.H:356
OSstream.H