HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups 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 setp64(char *first, char *last);
105  void setg64(char *first, char *next, char *last);
106 
107  void pbump64(exint offset);
108  void gbump64(exint offset);
109 
110  char * epptr64() const;
111  char * egptr64() const;
112 
113  bool validatePPtr() const;
114  bool validateGPtr() const;
115 
116 private:
117  template<bool bump_write_ptr>
118  void bump64(exint offset);
119 
120  void updateReadEnd();
121  void writeToBuffer(const char *ptr, exint bytes);
122 
123  // Helpers to realize the CRTP for the static polymorphism we're after.
124  UT_WorkBuffer &buffer() { return static_cast<T *>(this)->buffer(); }
125  const UT_WorkBuffer &buffer() const { return static_cast<const T *>(this)->buffer(); }
126 
127  openmode myMode;
128  char * myEGPtr;
129  char * myEPPtr;
130 };
131 
132 /// ======================================================================
133 
134 /// Specialization of UT_StringStreamBufferBase which owns its own
135 /// UT_WorkBuffer.
137  : public UT_StringStreamBufferBase<UT_StringStreamBuffer>
138 {
140 public:
141  // Start with an empty buffer.
143  : Base(mode)
144  {
145  init();
146  }
147 
148  // Start with an empty string buffer with a given size reservation
149  explicit UT_StringStreamBuffer(exint reserved_size,
150  openmode mode = in_out)
151  : Base(mode)
152  {
153  init(NULL, reserved_size);
154  }
155 
156  // Provide a buffer to populate the existing work buffer with.
158  openmode mode = in_out)
159  : Base(mode)
160  {
161  init(buf.buffer(), buf.length());
162  }
163 
164  // Provide a block of memory to populate the existing work buffer with.
166  exint len = -1,
167  openmode mode = in_out)
168  : Base(mode)
169  {
170  init(buf, len);
171  }
172 
173  const UT_WorkBuffer &str() const { return Base::str(); }
174 
175  // Set the buffer to a new value. Resets all current read/write offsets.
176  void str(const char *buf, exint len = -1)
177  {
178  init(buf, len);
179  }
180 
181 
182  void str(const UT_WorkBuffer &wb)
183  {
184  init(wb.buffer(), wb.length());
185  }
186 
187  /// Swaps the contents of our buffer with the given buffer and resets
188  /// the stream to the swapped-in buffer.
189  void swap(UT_WorkBuffer &buf);
190 
191  /// Steals the contents of the buffer into the UT_String object given and
192  /// resets the stream.
193  void steal(UT_String &str);
194 
195 protected:
197  UT_WorkBuffer &buffer() { return myBuffer; }
198  const UT_WorkBuffer &buffer() const { return myBuffer; }
199  static bool autoTerminate() { return false; }
200 
201 private:
202 
203  void init(const char *buf = NULL, exint len = -1);
204 
205  UT_WorkBuffer myBuffer;
206 };
207 
208 /// An input stream object that owns its own string buffer storage.
209 class UT_IStringStream : public std::istream
210 {
211 public:
212  /// Start with an empty string buffer. Use rdbuf()->swap() to swap in new
213  /// data when required. Otherwise it will simply eof right from the start.
214  explicit UT_IStringStream(openmode m = ios_base::in)
215  : myBuffer(m | ios_base::in),
216  std::istream(&myBuffer)
217  { }
218 
219  /// Populate the input stream with an existing UT_WorkBuffer. The contents
220  /// of the buffer are copied into the internal storage. The input position
221  /// start at the beginning of the buffer.
223  openmode m = ios_base::in)
224  : myBuffer(buf, m | ios_base::in),
225  std::istream(&myBuffer)
226  { }
227 
228  /// Populate the input stream with an existing raw character buffer.
229  /// The contents of the buffer are copied into the internal storage.
230  /// The input position start at the beginning of the buffer.
231  explicit UT_IStringStream(const char *buf, exint len = -1,
232  openmode m = ios_base::in)
233  : myBuffer(buf, len, m | ios_base::in),
234  std::istream(&myBuffer)
235  { }
236 
237  /// Returns the underlying stream buffer object.
238  UT_StringStreamBuffer *rdbuf() const { return SYSconst_cast(&myBuffer); }
239 
240  /// Returns a read-only reference to the underlying UT_WorkBuffer.
241  const UT_WorkBuffer &str() const { return myBuffer.str(); }
242 
243  /// Resets the input stream and clears all existing input data.
244  void reset() { myBuffer.reset(); }
245 private:
246  UT_StringStreamBuffer myBuffer;
247 };
248 
249 /// An output stream object that owns its own string buffer storage.
250 class UT_OStringStream : public std::ostream
251 {
252 public:
253  /// Start with an empty string buffer.
254  explicit UT_OStringStream(openmode m = ios_base::out)
255  : myBuffer(m | ios_base::out),
256  std::ostream(&myBuffer)
257  { }
258 
259  /// Start with an empty string buffer with a given size reservation, if it
260  /// is known in advance how much data will be written out.
261  explicit UT_OStringStream(exint reserved_size,
262  openmode m = ios_base::out)
263  : myBuffer(reserved_size, m | ios_base::out),
264  std::ostream(&myBuffer)
265  { }
266 
267  /// Populate the input stream with an existing UT_WorkBuffer. The contents
268  /// of the buffer are copied into the internal storage and the output
269  /// position set to the end of the buffer.
271  openmode m = ios_base::out)
272  : myBuffer(buf, m | ios_base::out),
273  std::ostream(&myBuffer)
274  { }
275 
276  /// Populate the input stream with an existing raw character buffer.
277  /// The contents of the buffer are copied into the internal storage and
278  /// the output position set to the end of the buffer.
279  explicit UT_OStringStream(const char *buf, exint len = -1,
280  openmode m = ios_base::out)
281  : myBuffer(buf, len, m | ios_base::out),
282  std::ostream(&myBuffer)
283  { }
284 
285  /// Returns the underlying stream buffer object.
286  UT_StringStreamBuffer *rdbuf() const { return SYSconst_cast(&myBuffer); }
287 
288  /// Returns a read-only reference to the underlying UT_WorkBuffer.
289  const UT_WorkBuffer &str() const { return myBuffer.str(); }
290 
291  /// Resets the input stream and clears all existing input data.
292  void reset() { myBuffer.reset(); }
293 private:
294  UT_StringStreamBuffer myBuffer;
295 };
296 
297 /// An bi-directional stream object that owns its own string buffer storage.
298 class UT_StringStream : public std::iostream
299 {
300 public:
301  /// Start with an empty string buffer. Use rdbuf()->swap() to swap in new
302  /// data if required. Otherwise it will simply eof, on read, right from
303  /// the start.
304  explicit UT_StringStream(openmode m = in_out)
305  : myBuffer(m),
306  std::iostream(&myBuffer)
307  { }
308 
309  /// Start with an empty string buffer with a given size reservation, if it
310  /// is known in advance how much data will be written out. The input stream
311  /// will still be empty.
312  explicit UT_StringStream(exint reserved_size,
313  openmode m = in_out)
314  : myBuffer(reserved_size, m),
315  std::iostream(&myBuffer)
316  { }
317 
318  /// Populate the input stream with an existing UT_WorkBuffer. The contents
319  /// of the buffer are copied into the internal storage, the output
320  /// position set to the end of the buffer, and the input position at the
321  /// beginning of the buffer.
323  openmode m = in_out)
324  : myBuffer(buf, m),
325  std::iostream(&myBuffer)
326  { }
327 
328  /// Populate the input stream with an existing raw character buffer.
329  /// The contents of the buffer are copied into the internal storage,
330  /// the output position set to the end of the buffer, and the
331  /// input position at the beginning of the buffer.
332  explicit UT_StringStream(const char *buf, exint len = -1,
333  openmode m = in_out)
334  : myBuffer(buf, len, m),
335  std::iostream(&myBuffer)
336  { }
337 
338  /// Returns the underlying stream buffer object.
339  UT_StringStreamBuffer *rdbuf() const { return SYSconst_cast(&myBuffer); }
340 
341  /// Returns a read-only reference to the underlying UT_WorkBuffer.
342  const UT_WorkBuffer &str() const { return myBuffer.str(); }
343 
344  /// Resets the input stream and clears all existing input data.
345  void reset() { myBuffer.reset(); }
346 private:
347  UT_StringStreamBuffer myBuffer;
348 };
349 
350 /// ======================================================================
351 /// A version of std::streambuf which holds a reference to an external
352 /// UT_WorkBuffer object. It is important that the life cycle of the external
353 /// UT_WorkBuffer fully encloses the life cycle of the UT_StringRefStreamBuffer
354 /// object. Upon destruction of the UT_StringRefStreamBuffer object the
355 /// UT_WorkBuffer object will be guaranteed to be null terminated. While the
356 /// UT_StringRefStream is live, no such guarantee is made. To force a null
357 /// termination, call UT_StringRefStream::sync().
358 /// If the external buffer is changed outside of the stream object, then
359 /// it is necessary to call UT_StringRefStream::sync() so that any references
360 /// to the buffer can be updated. In this case, an output stream will be reset
361 /// to the end of the buffer. The input stream is left to point to the same
362 /// location, unless it now points beyond the end, in which case it gets marked
363 /// as eof.
364 /// Note that there is a difference between ref-buffer and non-ref-buffer
365 /// when writing data after seeking back in the stream. Because the ref-buffer
366 /// auto terminates after the newly written characters, it may terminate
367 /// the string before the end of previously written characters, effectively
368 /// discarding these older characters.
369 
371  : public UT_StringStreamBufferBase<UT_StringRefStreamBuffer>
372 {
374 public:
375  /// Take a reference to an existing UT_WorkBuffer. The output position set
376  /// to the end of the buffer, and the input position at the beginning of
377  /// the buffer.
379  openmode mode = in_out)
380  : Base(mode),
381  myBuffer(buf)
382  {
383  Base::init(true);
384  }
385 
386  /// Returns a read-only reference to the underlying storage.
387  const UT_WorkBuffer &str() const { return Base::str(); }
388 
389 protected:
390  /// std::streambuf helpers.
391  virtual int sync();
392 
394  UT_WorkBuffer &buffer() { return myBuffer; }
395  const UT_WorkBuffer &buffer() const { return myBuffer; }
396  static bool autoTerminate() { return true; }
397 
398 private:
399  UT_WorkBuffer &myBuffer;
400 };
401 
402 /// An input stream object that keeps a reference to an external string
403 /// buffer storage.
404 /// See @c UT_StringRefStreamBuffer for notes on modifying the external buffer
405 /// while doing stream operations on it.
406 class UT_IStringRefStream : public std::istream
407 {
408 public:
409  /// Take a reference to an existing UT_WorkBuffer. The input position at
410  /// the beginning of the buffer.
412  openmode m = ios_base::in)
413  : myBuffer(buf, m | ios_base::in),
414  std::istream(&myBuffer)
415  { }
416 
417  /// Returns the underlying stream buffer object.
418  UT_StringRefStreamBuffer *rdbuf() const { return SYSconst_cast(&myBuffer); }
419 
420  /// Returns a read-only reference to the underlying UT_WorkBuffer.
421  const UT_WorkBuffer &str() const { return myBuffer.str(); }
422 
423  /// Resets the input stream and clears all existing input data.
424  void reset() { myBuffer.reset(); }
425 private:
426  UT_StringRefStreamBuffer myBuffer;
427 };
428 
429 /// An output stream object that keeps a reference to an external string
430 /// buffer storage.
431 /// See @c UT_StringRefStreamBuffer for notes on modifying the external buffer
432 /// while doing stream operations on it.
433 class UT_OStringRefStream : public std::ostream
434 {
435 public:
436  /// Take a reference to an existing UT_WorkBuffer. The output position set
437  /// to the end of the buffer.
439  openmode m = ios_base::out)
440  : myBuffer(buf, m | ios_base::out),
441  std::ostream(&myBuffer)
442  { }
443 
444  /// Returns the underlying stream buffer object.
445  UT_StringRefStreamBuffer *rdbuf() const { return SYSconst_cast(&myBuffer); }
446 
447  /// Returns a read-only reference to the underlying UT_WorkBuffer.
448  const UT_WorkBuffer &str() const { return myBuffer.str(); }
449 
450  /// Resets the input stream and clears all existing output data.
451  void reset() { myBuffer.reset(); }
452 
453 private:
454  UT_StringRefStreamBuffer myBuffer;
455 };
456 
457 /// An bi-directional stream object that keeps a reference to an external
458 /// string buffer storage.
459 /// See @c UT_StringRefStreamBuffer for notes on modifying the external buffer
460 /// while doing stream operations on it.
461 class UT_StringRefStream : public std::iostream
462 {
463 public:
464  /// Take a reference to an existing UT_WorkBuffer. The output position set
465  /// to the end of the buffer, and the input position at the beginning of
466  /// the buffer.
468  openmode m = in_out)
469  : myBuffer(buf, m),
470  std::iostream(&myBuffer)
471  { }
472 
473  /// Returns the underlying stream buffer object.
474  UT_StringRefStreamBuffer *rdbuf() const { return SYSconst_cast(&myBuffer); }
475 
476  /// Returns a read-only reference to the underlying UT_WorkBuffer.
477  const UT_WorkBuffer &str() const { return myBuffer.str(); }
478 
479  /// Resets the input stream and clears all existing data.
480  void reset() { myBuffer.reset(); }
481 private:
482  UT_StringRefStreamBuffer myBuffer;
483 };
484 
485 
486 // Implementation file
487 #include "UT_StringStreamImpl.h"
488 
489 #endif //__UT_StringStream__
const UT_WorkBuffer & str() const
Returns a read-only reference to the underlying UT_WorkBuffer.
UT_StringStream(openmode m=in_out)
GLint first
Definition: glcorearb.h:404
void reset()
Resets the input stream and clears all existing data.
SYS_FORCE_INLINE exint length() const
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:127
UT_OStringStream(exint reserved_size, openmode m=ios_base::out)
UT_StringRefStreamBuffer * rdbuf() const
Returns the underlying stream buffer object.
SYS_FORCE_INLINE const char * buffer() const
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)
void setg64(char *first, char *next, char *last)
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:116
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
void setp64(char *first, char *last)
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.
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)
UT_WorkBuffer & buffer()
GLenum src
Definition: glcorearb.h:1792