OSpanStream.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) 2016-2024 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::OSpanStream
28 
29 Description
30  Similar to OStringStream but using an externally managed buffer for
31  its output.
32 
33  This allows the output buffer to be reused and can make it easier when
34  writing out data. It is the user's responsibility to ensure proper
35  synchronization in the sizes. Provided that the external buffer is large
36  enough that overflow does not occur, the following usage pattern
37  works.
38 
39  \code
40  DynamicList<char> buffer(4096); // allocate some large buffer
41 
42  {
43  OSpanStream os(buffer);
44  os << "content1" << " and more content";
45  buffer.resize(os.size()); // synchronize sizes
46  }
47 
48  something.write(buffer, buffer.size());
49  \endcode
50 
51  Although the OSpanStream is quite lightweight, there may be cases
52  where it is preferable to reuse the stream as well.
53  \code
54  DynamicList<char> buffer(4096); // allocate some large buffer
55 
56  OSpanStream os(buffer);
57  os << "content1" << " and more content";
58  buffer.resize(os.size()); // synchronize sizes
59 
60  something.write(buffer, buffer.size());
61 
62  os.rewind();
63  os << "content2";
64  buffer.resize(os.size()); // synchronize sizes
65 
66  something.write(buffer, buffer.size());
67 
68  // or simply using the output size directly (without sync)
69  os.rewind();
70  os << "content3";
71 
72  something.write(buffer, os.size());
73  \endcode
74 
75 See Also
76  Foam::ICharStream
77  Foam::ISpanStream
78  Foam::OCharStream
79 
80 \*---------------------------------------------------------------------------*/
81 
82 #ifndef Foam_OSpanStream_H
83 #define Foam_OSpanStream_H
84 
85 #include "memoryStreamBuffer.H"
86 #include "OSstream.H"
87 
88 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
89 
90 namespace Foam
91 {
92 
93 // Forward Declarations
94 class ospanstream;
95 class OSpanStream;
96 
97 // Older names (prior to 2023-08)
99 
100 
101 /*---------------------------------------------------------------------------*\
102  Class ospanstream Declaration
103 \*---------------------------------------------------------------------------*/
104 
105 //- Similar to std::ostringstream, but with an externally managed output buffer
106 //- which makes it most similar to std::ospanstream (C++23)
107 class ospanstream
108 :
109  virtual public std::ios,
110  protected Foam::memorybuf::out_base,
111  public std::ostream
112 {
114  typedef std::ostream stream_type;
115 
116 public:
117 
118  // Constructors
119 
120  //- Default construct - empty
121  ospanstream()
122  :
123  buffer_type(),
124  stream_type(static_cast<buffer_type*>(this))
125  {}
126 
127  //- Construct for character array and number of bytes
128  ospanstream(char* buffer, size_t nbytes)
129  :
130  buffer_type(buffer, nbytes),
131  stream_type(static_cast<buffer_type*>(this))
132  {}
133 
134 
135  // Member Functions
136 
137  //- The current output position within the buffer (tellp)
138  std::streampos output_pos() const
139  {
140  return buffer_type::span_tellp();
141  }
142 
143  //- The number of bytes outputted
144  std::streamsize count() const
145  {
146  return buffer_type::size_bytes();
147  }
148 
149  //- The put buffer capacity
150  std::streamsize capacity() const
151  {
153  }
154 
155  //- Span of the current output characters (is modifiable!)
156  UList<char> list() const
157  {
158  return UList<char>
159  (
161  label(buffer_type::size_bytes())
162  );
163  }
164 
165  //- A string_view (c++17) or span view (older c++) of buffer contents
166  auto view() const -> decltype(buffer_type::view())
167  {
168  return buffer_type::view();
169  }
170 
171  //- For ostringstream compatibility, return the buffer as string copy.
172  // Use sparingly - it creates a full copy!!
173  std::string str() const
174  {
175  return std::string
176  (
179  );
180  }
181 
182  //- Rewind the stream, clearing any old errors
183  void rewind()
184  {
185  buffer_type::pubseekpos(0, std::ios_base::out);
186  stream_type::clear(); // Clear any old errors
187  }
188 
189  //- Reset the put buffer area
190  void reset(char* buffer, size_t nbytes)
191  {
192  buffer_type::resetp(buffer, nbytes);
193  stream_type::clear(); // Clear any old errors
194  }
195 
196  //- Reset the put buffer area to use the data area from a string
197  void reset(std::string& s)
198  {
199  s.resize(s.capacity());
200  buffer_type::resetp(&s[0], s.size());
201  stream_type::clear(); // Clear any old errors
202  }
203 
204  //- Some information about the output buffer position/capacity
205  void debug_info(Ostream& os) const
206  {
207  os << "put=" << output_pos() << '/' << capacity();
208  }
209 };
210 
211 
212 /*---------------------------------------------------------------------------*\
213  Class OSpanStream Declaration
214 \*---------------------------------------------------------------------------*/
216 class OSpanStream
217 :
218  public Foam::Detail::StreamAllocator<Foam::ospanstream>,
219  public Foam::OSstream
220 {
221  typedef
223  allocator_type;
224 
225 public:
226 
227  // Constructors
228 
229  //- Default construct (empty output)
230  explicit OSpanStream
231  (
232  IOstreamOption streamOpt = IOstreamOption()
233  )
234  :
235  allocator_type(),
236  OSstream(stream_, "output", streamOpt.format(), streamOpt.version())
237  {}
238 
239  //- Use data area from string content
240  explicit OSpanStream
241  (
242  std::string& buffer,
243  IOstreamOption streamOpt = IOstreamOption()
244  )
245  :
246  OSpanStream(streamOpt)
247  {
248  stream_.reset(buffer);
249  }
250 
251  //- Construct using specified buffer and number of bytes
253  (
254  char* buffer,
255  size_t nbytes,
256  IOstreamOption streamOpt = IOstreamOption()
257  )
258  :
259  OSpanStream(streamOpt)
260  {
261  stream_.reset(buffer, nbytes);
262  }
263 
264  //- Construct using data area from a List and its inherent storage size
265  explicit OSpanStream
266  (
267  ::Foam::UList<char>& buffer,
268  IOstreamOption streamOpt = IOstreamOption()
269  )
270  :
271  OSpanStream(buffer.data(), buffer.size(), streamOpt)
272  {}
273 
274  //- Construct using full data area from DynamicList
275  template<int SizeMin>
276  explicit OSpanStream
277  (
280  )
281  :
282  OSpanStream(buffer.data(), buffer.capacity(), streamOpt)
283  {
284  buffer.resize(buffer.capacity()); // Uses entire space
285  }
286 
287 
288  // Member Functions
289 
290  //- Position of the put buffer
291  std::streampos tellp() const { return stream_.output_pos(); }
292 
293  //- The current output position within the buffer (tellp)
294  std::streampos output_pos() const { return stream_.output_pos(); }
295 
296  //- The number of bytes outputted
297  std::streamsize count() const { return stream_.count(); }
298 
299  //- The current output size. Same as count(), output_pos(), tellp().
300  label size() const { return label(stream_.count()); }
301 
302  //- The put buffer capacity
303  std::streamsize capacity() const { return stream_.capacity(); }
304 
305  //- Span of the current output characters (is modifiable!)
306  UList<char> list() const { return stream_.list(); }
308  //- A string_view (c++17) or span view (older c++) of buffer contents
309  auto view() const -> decltype(stream_.view())
310  {
311  return stream_.view();
312  }
313 
314  //- For OStringStream compatibility, return buffer as string copy.
315  // Use sparingly - it creates a full copy!!
316  auto str() const -> decltype(stream_.str())
317  {
318  return stream_.str();
319  }
320 
321  //- Reset the put area
322  void reset(char* buffer, size_t nbytes)
323  {
324  stream_.reset(buffer, nbytes);
325  syncState();
326  }
327 
328  //- Reset the put buffer area to use the data area from a string
329  void reset(std::string& s)
330  {
331  stream_.reset(s);
332  syncState();
333  }
334 
335  //- Rewind the stream, clearing any old errors
336  virtual void rewind()
337  {
339  syncState();
340  }
341 
342  //- Print stream description to Ostream
343  virtual void print(Ostream& os) const override;
344 };
345 
346 
347 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
349 } // End namespace Foam
350 
351 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
352 
353 #endif
354 
355 // ************************************************************************* //
label size() const
The current output size. Same as count(), output_pos(), tellp().
Definition: OSpanStream.H:338
auto str() const -> decltype(stream_.str())
For OStringStream compatibility, return buffer as string copy.
Definition: OSpanStream.H:363
Generic output stream using a standard (STL) stream.
Definition: OSstream.H:50
A wrapper to hold a std::stream type for OpenFOAM wrapped streams. This is necessary since the OpenFO...
Definition: IOstream.H:600
std::streamsize span_capacity() const
The put buffer capacity.
void syncState()
Set stream state to match that of the std::ostream.
Definition: OSstream.H:182
void resize(const label len)
Alter addressable list size, allocating new space if required while recovering old content...
Definition: DynamicListI.H:353
std::streampos output_pos() const
The current output position within the buffer (tellp)
Definition: OSpanStream.H:328
std::streamsize capacity() const
The put buffer capacity.
Definition: OSpanStream.H:343
A simple container for options an IOstream can normally have.
char * data_bytes() const
The span data (start of output characters)
std::string str() const
For ostringstream compatibility, return the buffer as string copy.
Definition: OSpanStream.H:185
void rewind()
Rewind the stream, clearing any old errors.
Definition: OSpanStream.H:197
OSpanStream UOListStream
Definition: OSpanStream.H:88
virtual void rewind()
Rewind the stream, clearing any old errors.
Definition: OSpanStream.H:389
label capacity() const noexcept
Size of the underlying storage.
Definition: DynamicList.H:225
std::streamsize capacity() const
The put buffer capacity.
Definition: OSpanStream.H:155
constexpr IOstreamOption(streamFormat fmt=streamFormat::ASCII, compressionType comp=compressionType::UNCOMPRESSED) noexcept
Default construct (ASCII, UNCOMPRESSED, currentVersion) or construct with format, compression...
void reset(char *buffer, size_t nbytes)
Reset the put buffer area.
Definition: OSpanStream.H:206
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
Definition: DynamicList.H:51
Foam::ospanstream stream_
The std::stream.
Definition: IOstream.H:609
UList< char > list() const
Span of the current output characters (is modifiable!)
Definition: OSpanStream.H:163
std::streampos tellp() const
Position of the put buffer.
Definition: OSpanStream.H:323
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:105
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
void debug_info(Ostream &os) const
Some information about the output buffer position/capacity.
Definition: OSpanStream.H:225
void reset(char *buffer, size_t nbytes)
Reset the put area.
Definition: OSpanStream.H:371
OBJstream os(runTime.globalPath()/outputName)
std::streamsize span_tellp() const
The current buffer put position.
void resetp(char *s, std::streamsize n)
Reset put buffer with character data (can be nullptr) and count.
std::streamsize count() const
The number of bytes outputted.
Definition: OSpanStream.H:333
UList< char > list() const
Span of the current output characters (is modifiable!)
Definition: OSpanStream.H:348
std::streampos output_pos() const
The current output position within the buffer (tellp)
Definition: OSpanStream.H:139
surface1 clear()
auto view() const -> decltype(buffer_type::view())
A string_view (c++17) or span view (older c++) of buffer contents.
Definition: OSpanStream.H:175
OSpanStream(IOstreamOption streamOpt=IOstreamOption())
Default construct (empty output)
Definition: OSpanStream.H:253
versionNumber version() const noexcept
Get the stream version.
stdFoam::span< const char > view() const
std::streamsize size_bytes() const
The span size (size of output buffer)
An output streambuf for memory access.
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))
Similar to std::ostringstream, but with an externally managed output buffer which makes it most simil...
Definition: OSpanStream.H:102
Similar to OStringStream but using an externally managed buffer for its output.
Definition: OSpanStream.H:236
streamFormat format() const noexcept
Get the current stream format.
virtual void print(Ostream &os) const override
Print stream description to Ostream.
Definition: SpanStreams.C:34
std::streamsize count() const
The number of bytes outputted.
Definition: OSpanStream.H:147
Namespace for OpenFOAM.
ospanstream()
Default construct - empty.
Definition: OSpanStream.H:118
auto view() const -> decltype(stream_.view())
A string_view (c++17) or span view (older c++) of buffer contents.
Definition: OSpanStream.H:353