HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
UT_StringStream.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: UT_StringStream.h ( UT Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __UT_StringStream__
12 #define __UT_StringStream__
13 
14 #include "UT_API.h"
15 #include "UT_WorkBuffer.h"
16 
17 #include <iostream>
18 
19 /// An a string buffer based on UT_WorkBuffer. Supports both input and output.
20 /// Provides cleaner semantics than UT_OStrStream, which is based on the
21 /// obsolete std::strstream class. Unlike UT_OStrStream, it is not necessary
22 /// to manage the stream's memory externally, if it was dynamically allocated,
23 /// or add a null byte termination.
24 /// For example, this code:
25 /// @code{.cpp}
26 /// UT_OStrStream os;
27 /// SomeClass::save(os); // write things to os.
28 /// os << std::ends;
29 /// fprintf(stderr, "Buffer: %s", os.str());
30 /// os.rdbuf()->freeze(false);
31 /// @endcode
32 /// Turns into:
33 //// @code{.cpp}
34 /// UT_OStringStream os;
35 /// SomeClass::save(os); // write things to os.
36 /// fprintf(stderr, "Buffer: %s", os.str());
37 /// @endcode
38 /// Note that the explicit requirement for null termination, and the call
39 /// to @c freeze to relinquish the buffer use, are both gone.
40 ///
41 /// However, the downside is that you cannot pass explicit buffers to the
42 /// stream. On the other hand, you should not be using fixed-sized buffers for
43 /// output streams in the first place.
44 /// If an externally used buffer is wanted, there's UT_OStringRefStream, which
45 /// takes a reference to an existing UT_WorkBuffer. The stream will carefully
46 /// maintain null termination, so that the buffer can be accessed at any time.
47 ///
48 /// There's also support for input and input/output buffers, using
49 /// UT_IStringStream/UT_IStringRefStream and UT_StringStream/UT_StringRefStream.
50 
51 namespace
52 {
53  static const std::ios_base::openmode in_out = std::ios_base::out |
54  std::ios_base::in;
55 }
56 
57 /// Base class for the memory storage and stream buffering.
58 template<typename T>
59 class UT_StringStreamBufferBase : public std::streambuf
60 {
61 public:
62  typedef std::ios_base::openmode openmode;
63  typedef std::streamsize streamsize;
64 
66 
67  // Resets the buffer to an empty state. Does not de-allocate existing
68  // memory.
69  void reset()
70  {
71  buffer().clear();
72  init();
73  }
74 
75 protected:
77 
78  void init(bool use_existing = false);
79 
80  // Returns a reference to the current string.
81  const UT_WorkBuffer &str() const;
82 
83  // Updates the underlying buffer with proper termination and length.
84  void updateBufferEnd();
85 
86  // iostream implementation helpers
87  virtual pos_type seekoff(off_type offset,
88  std::ios_base::seekdir dir,
89  openmode mode = in_out);
90  virtual pos_type seekpos(pos_type pos,
91  std::ios_base::openmode mode = in_out);
92 
93  // istream implementation helpers
94  virtual int_type underflow();
95  virtual streamsize xsgetn(char_type *dst, streamsize num);
96  virtual streamsize showmanyc();
97 
98  // ostream implementation helpers
99  virtual int_type overflow(int_type c);
100  virtual streamsize xsputn(const char_type *src, streamsize num);
101 
102  openmode mode() const { return myMode; }
103 
104  void pbump64(exint offset);
105  void gbump64(exint offset);
106 private:
107  template<bool bump_write_ptr>
108  void bump64(exint offset);
109 
110  void updateReadEnd();
111  void writeToBuffer(const char *ptr, exint bytes);
112 
113  // Helpers to realize the CRTP for the static polymorphism we're after.
114  UT_WorkBuffer &buffer() { return static_cast<T *>(this)->buffer(); }
115  const UT_WorkBuffer &buffer() const { return static_cast<const T *>(this)->buffer(); }
116 
117  openmode myMode;
118 };
119 
120 /// ======================================================================
121 
122 /// Specialization of UT_StringStreamBufferBase which owns its own
123 /// UT_WorkBuffer.
125  : public UT_StringStreamBufferBase<UT_StringStreamBuffer>
126 {
128 public:
129  // Start with an empty buffer.
131  : Base(mode)
132  {
133  init();
134  }
135 
136  // Start with an empty string buffer with a given size reservation
137  explicit UT_StringStreamBuffer(exint reserved_size,
138  openmode mode = in_out)
139  : Base(mode)
140  {
141  init(NULL, reserved_size);
142  }
143 
144  // Provide a buffer to populate the existing work buffer with.
146  openmode mode = in_out)
147  : Base(mode)
148  {
149  init(buf.buffer(), buf.length());
150  }
151 
152  // Provide a block of memory to populate the existing work buffer with.
154  exint len = -1,
155  openmode mode = in_out)
156  : Base(mode)
157  {
158  init(buf, len);
159  }
160 
161  const UT_WorkBuffer &str() const { return Base::str(); }
162 
163  // Set the buffer to a new value. Resets all current read/write offsets.
164  void str(const char *buf, exint len = -1)
165  {
166  init(buf, len);
167  }
168 
169 
170  void str(const UT_WorkBuffer &wb)
171  {
172  init(wb.buffer(), wb.length());
173  }
174 
175  /// Swaps the contents of our buffer with the given buffer and resets
176  /// the stream to the swapped-in buffer.
177  void swap(UT_WorkBuffer &buf);
178 
179  /// Steals the contents of the buffer into the UT_String object given and
180  /// resets the stream.
181  void steal(UT_String &str);
182 
183 protected:
185  UT_WorkBuffer &buffer() { return myBuffer; }
186  const UT_WorkBuffer &buffer() const { return myBuffer; }
187  static bool autoTerminate() { return false; }
188 
189 private:
190 
191  void init(const char *buf = NULL, exint len = -1);
192 
193  UT_WorkBuffer myBuffer;
194 };
195 
196 /// An input stream object that owns its own string buffer storage.
197 class UT_IStringStream : public std::istream
198 {
199 public:
200  /// Start with an empty string buffer. Use rdbuf()->swap() to swap in new
201  /// data when required. Otherwise it will simply eof right from the start.
202  explicit UT_IStringStream(openmode m = ios_base::in)
203  : myBuffer(m | ios_base::in),
204  std::istream(&myBuffer)
205  { }
206 
207  /// Populate the input stream with an existing UT_WorkBuffer. The contents
208  /// of the buffer are copied into the internal storage. The input position
209  /// start at the beginning of the buffer.
211  openmode m = ios_base::in)
212  : myBuffer(buf, m | ios_base::in),
213  std::istream(&myBuffer)
214  { }
215 
216  /// Populate the input stream with an existing raw character buffer.
217  /// The contents of the buffer are copied into the internal storage.
218  /// The input position start at the beginning of the buffer.
219  explicit UT_IStringStream(const char *buf, exint len = -1,
220  openmode m = ios_base::in)
221  : myBuffer(buf, len, m | ios_base::in),
222  std::istream(&myBuffer)
223  { }
224 
225  /// Returns the underlying stream buffer object.
226  UT_StringStreamBuffer *rdbuf() const { return SYSconst_cast(&myBuffer); }
227 
228  /// Returns a read-only reference to the underlying UT_WorkBuffer.
229  const UT_WorkBuffer &str() const { return myBuffer.str(); }
230 
231  /// Resets the input stream and clears all existing input data.
232  void reset() { myBuffer.reset(); }
233 private:
234  UT_StringStreamBuffer myBuffer;
235 };
236 
237 /// An output stream object that owns its own string buffer storage.
238 class UT_OStringStream : public std::ostream
239 {
240 public:
241  /// Start with an empty string buffer.
242  explicit UT_OStringStream(openmode m = ios_base::out)
243  : myBuffer(m | ios_base::out),
244  std::ostream(&myBuffer)
245  { }
246 
247  /// Start with an empty string buffer with a given size reservation, if it
248  /// is known in advance how much data will be written out.
249  explicit UT_OStringStream(exint reserved_size,
250  openmode m = ios_base::out)
251  : myBuffer(reserved_size, m | ios_base::out),
252  std::ostream(&myBuffer)
253  { }
254 
255  /// Populate the input stream with an existing UT_WorkBuffer. The contents
256  /// of the buffer are copied into the internal storage and the output
257  /// position set to the end of the buffer.
259  openmode m = ios_base::out)
260  : myBuffer(buf, m | ios_base::out),
261  std::ostream(&myBuffer)
262  { }
263 
264  /// Populate the input stream with an existing raw character buffer.
265  /// The contents of the buffer are copied into the internal storage and
266  /// the output position set to the end of the buffer.
267  explicit UT_OStringStream(const char *buf, exint len = -1,
268  openmode m = ios_base::out)
269  : myBuffer(buf, len, m | ios_base::out),
270  std::ostream(&myBuffer)
271  { }
272 
273  /// Returns the underlying stream buffer object.
274  UT_StringStreamBuffer *rdbuf() const { return SYSconst_cast(&myBuffer); }
275 
276  /// Returns a read-only reference to the underlying UT_WorkBuffer.
277  const UT_WorkBuffer &str() const { return myBuffer.str(); }
278 
279  /// Resets the input stream and clears all existing input data.
280  void reset() { myBuffer.reset(); }
281 private:
282  UT_StringStreamBuffer myBuffer;
283 };
284 
285 /// An bi-directional stream object that owns its own string buffer storage.
286 class UT_StringStream : public std::iostream
287 {
288 public:
289  /// Start with an empty string buffer. Use rdbuf()->swap() to swap in new
290  /// data if required. Otherwise it will simply eof, on read, right from
291  /// the start.
292  explicit UT_StringStream(openmode m = in_out)
293  : myBuffer(m),
294  std::iostream(&myBuffer)
295  { }
296 
297  /// Start with an empty string buffer with a given size reservation, if it
298  /// is known in advance how much data will be written out. The input stream
299  /// will still be empty.
300  explicit UT_StringStream(exint reserved_size,
301  openmode m = in_out)
302  : myBuffer(reserved_size, m),
303  std::iostream(&myBuffer)
304  { }
305 
306  /// Populate the input stream with an existing UT_WorkBuffer. The contents
307  /// of the buffer are copied into the internal storage, the output
308  /// position set to the end of the buffer, and the input position at the
309  /// beginning of the buffer.
311  openmode m = in_out)
312  : myBuffer(buf, m),
313  std::iostream(&myBuffer)
314  { }
315 
316  /// Populate the input stream with an existing raw character buffer.
317  /// The contents of the buffer are copied into the internal storage,
318  /// the output position set to the end of the buffer, and the
319  /// input position at the beginning of the buffer.
320  explicit UT_StringStream(const char *buf, exint len = -1,
321  openmode m = in_out)
322  : myBuffer(buf, len, m),
323  std::iostream(&myBuffer)
324  { }
325 
326  /// Returns the underlying stream buffer object.
327  UT_StringStreamBuffer *rdbuf() const { return SYSconst_cast(&myBuffer); }
328 
329  /// Returns a read-only reference to the underlying UT_WorkBuffer.
330  const UT_WorkBuffer &str() const { return myBuffer.str(); }
331 
332  /// Resets the input stream and clears all existing input data.
333  void reset() { myBuffer.reset(); }
334 private:
335  UT_StringStreamBuffer myBuffer;
336 };
337 
338 /// ======================================================================
339 /// A version of std::streambuf which holds a reference to an external
340 /// UT_WorkBuffer object. It is important that the life cycle of the external
341 /// UT_WorkBuffer fully encloses the life cycle of the UT_StringRefStreamBuffer
342 /// object. Upon destruction of the UT_StringRefStreamBuffer object the
343 /// UT_WorkBuffer object will be guaranteed to be null terminated. While the
344 /// UT_StringRefStream is live, no such guarantee is made. To force a null
345 /// termination, call UT_StringRefStream::sync().
346 /// If the external buffer is changed outside of the stream object, then
347 /// it is necessary to call UT_StringRefStream::sync() so that any references
348 /// to the buffer can be updated. In this case, an output stream will be reset
349 /// to the end of the buffer. The input stream is left to point to the same
350 /// location, unless it now points beyond the end, in which case it gets marked
351 /// as eof.
352 /// Note that there is a difference between ref-buffer and non-ref-buffer
353 /// when writing data after seeking back in the stream. Because the ref-buffer
354 /// auto terminates after the newly written characters, it may terminate
355 /// the string before the end of previously written characters, effectively
356 /// discarding these older characters.
357 
359  : public UT_StringStreamBufferBase<UT_StringRefStreamBuffer>
360 {
362 public:
363  /// Take a reference to an existing UT_WorkBuffer. The output position set
364  /// to the end of the buffer, and the input position at the beginning of
365  /// the buffer.
367  openmode mode = in_out)
368  : Base(mode),
369  myBuffer(buf)
370  {
371  Base::init(true);
372  }
373 
374  /// Returns a read-only reference to the underlying storage.
375  const UT_WorkBuffer &str() const { return Base::str(); }
376 
377 protected:
378  /// std::streambuf helpers.
379  virtual int sync();
380 
382  UT_WorkBuffer &buffer() { return myBuffer; }
383  const UT_WorkBuffer &buffer() const { return myBuffer; }
384  static bool autoTerminate() { return true; }
385 
386 private:
387  UT_WorkBuffer &myBuffer;
388 };
389 
390 /// An input stream object that keeps a reference to an external string
391 /// buffer storage.
392 /// See @c UT_StringRefStreamBuffer for notes on modifying the external buffer
393 /// while doing stream operations on it.
394 class UT_IStringRefStream : public std::istream
395 {
396 public:
397  /// Take a reference to an existing UT_WorkBuffer. The input position at
398  /// the beginning of the buffer.
400  openmode m = ios_base::in)
401  : myBuffer(buf, m | ios_base::in),
402  std::istream(&myBuffer)
403  { }
404 
405  /// Returns the underlying stream buffer object.
406  UT_StringRefStreamBuffer *rdbuf() const { return SYSconst_cast(&myBuffer); }
407 
408  /// Returns a read-only reference to the underlying UT_WorkBuffer.
409  const UT_WorkBuffer &str() const { return myBuffer.str(); }
410 
411  /// Resets the input stream and clears all existing input data.
412  void reset() { myBuffer.reset(); }
413 private:
414  UT_StringRefStreamBuffer myBuffer;
415 };
416 
417 /// An output stream object that keeps a reference to an external string
418 /// buffer storage.
419 /// See @c UT_StringRefStreamBuffer for notes on modifying the external buffer
420 /// while doing stream operations on it.
421 class UT_OStringRefStream : public std::ostream
422 {
423 public:
424  /// Take a reference to an existing UT_WorkBuffer. The output position set
425  /// to the end of the buffer.
427  openmode m = ios_base::out)
428  : myBuffer(buf, m | ios_base::out),
429  std::ostream(&myBuffer)
430  { }
431 
432  /// Returns the underlying stream buffer object.
433  UT_StringRefStreamBuffer *rdbuf() const { return SYSconst_cast(&myBuffer); }
434 
435  /// Returns a read-only reference to the underlying UT_WorkBuffer.
436  const UT_WorkBuffer &str() const { return myBuffer.str(); }
437 
438  /// Resets the input stream and clears all existing output data.
439  void reset() { myBuffer.reset(); }
440 
441 private:
442  UT_StringRefStreamBuffer myBuffer;
443 };
444 
445 /// An bi-directional stream object that keeps a reference to an external
446 /// string buffer storage.
447 /// See @c UT_StringRefStreamBuffer for notes on modifying the external buffer
448 /// while doing stream operations on it.
449 class UT_StringRefStream : public std::iostream
450 {
451 public:
452  /// Take a reference to an existing UT_WorkBuffer. The output position set
453  /// to the end of the buffer, and the input position at the beginning of
454  /// the buffer.
456  openmode m = in_out)
457  : myBuffer(buf, m),
458  std::iostream(&myBuffer)
459  { }
460 
461  /// Returns the underlying stream buffer object.
462  UT_StringRefStreamBuffer *rdbuf() const { return SYSconst_cast(&myBuffer); }
463 
464  /// Returns a read-only reference to the underlying UT_WorkBuffer.
465  const UT_WorkBuffer &str() const { return myBuffer.str(); }
466 
467  /// Resets the input stream and clears all existing data.
468  void reset() { myBuffer.reset(); }
469 private:
470  UT_StringRefStreamBuffer myBuffer;
471 };
472 
473 
474 // Implementation file
475 #include "UT_StringStreamImpl.h"
476 
477 #endif //__UT_StringStream__
const UT_WorkBuffer & str() const
Returns a read-only reference to the underlying UT_WorkBuffer.
UT_StringStream(openmode m=in_out)
void reset()
Resets the input stream and clears all existing data.
void init(bool use_existing=false)
const UT_WorkBuffer & str() const
Returns a read-only reference to the underlying storage.
UT_StringStreamBuffer * rdbuf() const
Returns the underlying stream buffer object.
void reset()
Resets the input stream and clears all existing input data.
const UT_WorkBuffer & str() const
Returns a read-only reference to the underlying UT_WorkBuffer.
void reset()
Resets the input stream and clears all existing output data.
png_voidp ptr
Definition: png.h:2145
SYS_FORCE_INLINE T * SYSconst_cast(const T *foo)
Definition: SYS_Types.h:120
UT_OStringStream(exint reserved_size, openmode m=ios_base::out)
UT_StringRefStreamBuffer * rdbuf() const
Returns the underlying stream buffer object.
UT_StringRefStream(UT_WorkBuffer &buf, openmode m=in_out)
An output stream object that owns its own string buffer storage.
An input stream object that owns its own string buffer storage.
virtual pos_type seekpos(pos_type pos, std::ios_base::openmode mode=in_out)
const UT_WorkBuffer & str() const
Returns a read-only reference to the underlying UT_WorkBuffer.
UT_StringStream(exint reserved_size, openmode m=in_out)
const UT_WorkBuffer & str() const
Returns a read-only reference to the underlying UT_WorkBuffer.
GLuint buffer
Definition: glcorearb.h:659
UT_StringStreamBuffer(const UT_WorkBuffer &buf, openmode mode=in_out)
const UT_WorkBuffer & buffer() const
UT_StringStreamBuffer(const char *buf, exint len=-1, openmode mode=in_out)
virtual streamsize xsputn(const char_type *src, streamsize num)
UT_IStringStream(openmode m=ios_base::in)
void reset()
Resets the input stream and clears all existing input data.
virtual streamsize showmanyc()
UT_StringStream(const UT_WorkBuffer &buf, openmode m=in_out)
UT_IStringStream(const UT_WorkBuffer &buf, openmode m=ios_base::in)
std::streamsize streamsize
virtual pos_type seekoff(off_type offset, std::ios_base::seekdir dir, openmode mode=in_out)
const UT_WorkBuffer & buffer() const
int64 exint
Definition: SYS_Types.h:109
UT_StringRefStreamBuffer(UT_WorkBuffer &buf, openmode mode=in_out)
void str(const UT_WorkBuffer &wb)
UT_OStringStream(const char *buf, exint len=-1, openmode m=ios_base::out)
GLintptr offset
Definition: glcorearb.h:664
An bi-directional stream object that owns its own string buffer storage.
Base class for the memory storage and stream buffering.
======================================================================
UT_IStringStream(const char *buf, exint len=-1, openmode m=ios_base::in)
static bool autoTerminate()
const UT_WorkBuffer & str() const
void reset()
Resets the input stream and clears all existing input data.
void swap(UT_WorkBuffer &buf)
const UT_WorkBuffer & str() const
GLenum mode
Definition: glcorearb.h:98
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glcorearb.h:2539
const UT_WorkBuffer & str() const
Returns a read-only reference to the underlying UT_WorkBuffer.
UT_IStringRefStream(UT_WorkBuffer &buf, openmode m=ios_base::in)
GLenum GLenum dst
Definition: glcorearb.h:1792
UT_OStringStream(openmode m=ios_base::out)
Start with an empty string buffer.
virtual int_type overflow(int_type c)
UT_StringStreamBuffer(openmode mode=in_out)
std::ios_base::openmode openmode
UT_OStringRefStream(UT_WorkBuffer &buf, openmode m=ios_base::out)
virtual streamsize xsgetn(char_type *dst, streamsize num)
UT_StringRefStreamBuffer * rdbuf() const
Returns the underlying stream buffer object.
void reset()
Resets the input stream and clears all existing input data.
UT_StringStreamBuffer * rdbuf() const
Returns the underlying stream buffer object.
void str(const char *buf, exint len=-1)
void steal(UT_String &str)
UT_StringStreamBuffer * rdbuf() const
Returns the underlying stream buffer object.
const char * buffer() const
virtual int sync()
std::streambuf helpers.
png_infop png_uint_32 int num
Definition: png.h:2158
UT_StringStream(const char *buf, exint len=-1, openmode m=in_out)
UT_StringRefStreamBuffer * rdbuf() const
Returns the underlying stream buffer object.
UT_StringStreamBufferBase(openmode mode)
UT_OStringStream(const UT_WorkBuffer &buf, openmode m=ios_base::out)
UT_WorkBuffer & buffer()
const UT_WorkBuffer & str() const
Returns a read-only reference to the underlying UT_WorkBuffer.
UT_StringStreamBuffer(exint reserved_size, openmode mode=in_out)
exint length() const
UT_WorkBuffer & buffer()
GLenum src
Definition: glcorearb.h:1792