Doxygen
Loading...
Searching...
No Matches
textstream.h
Go to the documentation of this file.
1/******************************************************************************
2 *
3 * Copyright (C) 1997-2021 by Dimitri van Heesch.
4 *
5 * Permission to use, copy, modify, and distribute this software and its
6 * documentation under the terms of the GNU General Public License is hereby
7 * granted. No representations are made about the suitability of this software
8 * for any purpose. It is provided "as is" without express or implied warranty.
9 * See the GNU General Public License for more details.
10 *
11 * Documents produced by Doxygen are derivative works derived from the
12 * input used in their production; they are not affected by this license.
13 *
14 */
15
16#ifndef TEXTSTREAM_H
17#define TEXTSTREAM_H
18
19#include <string>
20#include <iostream>
21#include <sstream>
22#include <cstdint>
23#include <cstdio>
24#include <fstream>
25#include <type_traits>
26
27#include "dstring.h"
28#include "construct.h"
29
30/** @brief Text streaming class that buffers data.
31 *
32 * Simpler version of std::ostringstream that has much better
33 * performance.
34 */
35class TextStream final
36{
37 static const int INITIAL_CAPACITY = 4096;
38 public:
39 /** Creates an empty stream object.
40 */
41 explicit TextStream(size_t capacity = INITIAL_CAPACITY)
42 {
43 m_buffer.reserve(capacity);
44 }
45 /** Create a text stream object for writing to a std::ostream.
46 * @note data is buffered until flush() is called or the object is destroyed.
47 */
48 explicit TextStream(std::ostream *s) : m_s(s)
49 {
51 }
52 /** Create a text stream, initializing the buffer with string \a s
53 */
54 explicit TextStream(const std::string &s) : m_buffer(s)
55 {
56 m_buffer.reserve(s.length()+INITIAL_CAPACITY);
57 }
58
59 /** Writes any data that is buffered to the attached std::ostream */
61
63
64 /** Sets or changes the std::ostream to write to.
65 * @note Any data already buffered will be flushed.
66 */
67 void setStream(std::ostream *s)
68 {
69 flush();
70 m_s = s;
71 m_f = nullptr;
72 }
73
74 void setFile(FILE *f)
75 {
76 flush();
77 m_s = nullptr;
78 m_f = f;
79 }
80
81 /** Adds a character to the stream */
83 {
84 m_buffer+=c;
85 return *this;
86 }
87
88
89 /** Adds an unsigned character to the stream */
90 TextStream &operator<<( unsigned char c)
91 {
92 m_buffer+=c;
93 return *this;
94 }
95
96 /** Adds an unsigned character string to the stream */
97 TextStream &operator<<( const unsigned char *s)
98 {
99 if (s)
100 {
101 const unsigned char *p = s;
102 while (*p)
103 {
104 m_buffer+=*p;
105 p++;
106 }
107 }
108 return *this;
109 }
110
111 /** Adds a C-style string to the stream */
112 TextStream &operator<<( const char *s)
113 {
114 if (s) m_buffer+=s;
115 return *this;
116 }
117
118 /** Adds a DString to the stream */
120 {
121 m_buffer+=s.str();
122 return *this;
123 }
124
125 /** Adds a std::string to the stream */
126 TextStream &operator<<( const std::string &s )
127 {
128 m_buffer+=s;
129 return *this;
130 }
131
132 /** Adds a signed short integer to the stream */
133 TextStream &operator<<( signed short i)
134 {
135 output_int32(i,i<0);
136 return *this;
137 }
138
139 /** Adds a unsigned short integer to the stream */
140 TextStream &operator<<( unsigned short i)
141 {
142 output_int32(i,false);
143 return *this;
144 }
145
146 /** Adds a signed integer to the stream */
147 TextStream &operator<<( signed int i)
148 {
149 output_int32(i,i<0);
150 return *this;
151 }
152
153 /** Adds a unsigned integer to the stream */
154 TextStream &operator<<( unsigned int i)
155 {
156 output_int32(i,false);
157 return *this;
158 }
159
160 /** Adds a size_t integer to the stream.
161 * We use SFINAE to avoid a compiler error in case size_t already matches the 'unsigned int' overload.
162 */
163 template<typename T,
164 typename std::enable_if<std::is_same<T,size_t>::value,T>::type* = nullptr
165 >
167 {
168 output_int32(static_cast<uint32_t>(i),false);
169 return *this;
170 }
171
172 /** Adds a float to the stream */
174 {
175 output_double(static_cast<double>(f));
176 return *this;
177 }
178
179 /** Adds a double to the stream */
181 {
182 output_double(d);
183 return *this;
184 }
185
186 // also allow += instead of << for convenience
187 void operator+=( char c) { *this << c; }
188 void operator+=( unsigned char c) { *this << c; }
189 void operator+=( const unsigned char *s) { *this << s; }
190 void operator+=( const char *s) { *this << s; }
191 void operator+=( const DString &s) { *this << s; }
192 void operator+=( const std::string &s) { *this << s; }
193 void operator+=( signed short i) { *this << i; }
194 void operator+=( unsigned short i) { *this << i; }
195 void operator+=( signed int i) { *this << i; }
196 void operator+=( unsigned int i) { *this << i; }
197 void operator+=( float f) { *this << f; }
198 void operator+=( double d) { *this << d; }
199
200 /** Adds a array of character to the stream
201 * @param buf the character buffer
202 * @param len the number of characters in the buffer to write
203 */
204 void write(const char *buf,size_t len)
205 {
206 m_buffer.append(buf,len);
207 }
208
209 /** Flushes the buffer. If a std::ostream is attached, the buffer's
210 * contents will be written to the stream.
211 */
212 void flush()
213 {
214 if (m_s)
215 {
216 m_s->write(m_buffer.c_str(),m_buffer.length());
217 }
218 else if (m_f)
219 {
220 fwrite(m_buffer.c_str(),1,m_buffer.length(),m_f);
221 }
222 m_buffer.clear();
223 }
224
225 /** Clears any buffered data */
226 void clear()
227 {
228 m_buffer.clear();
229 }
230
231 /** Return the contents of the buffer as a std::string object */
232 std::string str() const
233 {
234 return m_buffer;
235 }
236
237 /** Sets the buffer's contents to string \a s.
238 * Any data already in the buffer will be flushed.
239 */
240 void str(const std::string &s)
241 {
242 flush();
243 m_buffer=s;
244 }
245
246 /** Sets the buffer's contents to string \a s
247 * Any data already in the buffer will be flushed.
248 */
249 void str(const char *s)
250 {
251 flush();
252 if (s) m_buffer=s;
253 }
254
255 /** Returns true iff the buffer is empty */
256 bool empty() const
257 {
258 return m_buffer.empty();
259 }
260
261 private:
262 /** Writes a string representation of an integer to the buffer
263 * @param n the absolute value of the integer
264 * @param neg indicates if the integer is negative
265 */
266 void output_int32( uint32_t n, bool neg )
267 {
268 char buf[20];
269 char *p = &buf[19];
270 *p = '\0';
271 if ( neg )
272 {
273 n = static_cast<uint32_t>(-static_cast<int32_t>(n));
274 }
275 do { *--p = (static_cast<char>(n%10)) + '0'; n /= 10; } while ( n );
276 if ( neg ) *--p = '-';
277 m_buffer+=p;
278 }
279 void output_double( double d)
280 {
281 char buf[64];
282 snprintf(buf,64,"%f",d);
283 m_buffer+=buf;
284 }
285 std::string m_buffer;
286 std::ostream *m_s = nullptr;
287 FILE *m_f = nullptr;
288};
289
290#endif
A String class for use with Doxygen wrapping std::string and adding some additional functionality off...
Definition dstring.h:89
const std::string & str() const
Definition dstring.h:634
Text streaming class that buffers data.
Definition textstream.h:36
bool empty() const
Returns true iff the buffer is empty.
Definition textstream.h:256
void operator+=(unsigned short i)
Definition textstream.h:194
void operator+=(const DString &s)
Definition textstream.h:191
void setStream(std::ostream *s)
Sets or changes the std::ostream to write to.
Definition textstream.h:67
void operator+=(const char *s)
Definition textstream.h:190
TextStream & operator<<(const std::string &s)
Adds a std::string to the stream.
Definition textstream.h:126
void output_double(double d)
Definition textstream.h:279
TextStream & operator<<(float f)
Adds a float to the stream.
Definition textstream.h:173
TextStream & operator<<(unsigned short i)
Adds a unsigned short integer to the stream.
Definition textstream.h:140
void output_int32(uint32_t n, bool neg)
Writes a string representation of an integer to the buffer.
Definition textstream.h:266
TextStream & operator<<(signed int i)
Adds a signed integer to the stream.
Definition textstream.h:147
void operator+=(float f)
Definition textstream.h:197
std::string m_buffer
Definition textstream.h:285
TextStream & operator<<(double d)
Adds a double to the stream.
Definition textstream.h:180
TextStream & operator<<(const DString &s)
Adds a DString to the stream.
Definition textstream.h:119
void operator+=(double d)
Definition textstream.h:198
TextStream & operator<<(T i)
Adds a size_t integer to the stream.
Definition textstream.h:166
TextStream & operator<<(const unsigned char *s)
Adds an unsigned character string to the stream.
Definition textstream.h:97
TextStream(const std::string &s)
Create a text stream, initializing the buffer with string s.
Definition textstream.h:54
void str(const std::string &s)
Sets the buffer's contents to string s.
Definition textstream.h:240
TextStream & operator<<(signed short i)
Adds a signed short integer to the stream.
Definition textstream.h:133
TextStream & operator<<(const char *s)
Adds a C-style string to the stream.
Definition textstream.h:112
FILE * m_f
Definition textstream.h:287
void flush()
Flushes the buffer.
Definition textstream.h:212
TextStream(std::ostream *s)
Create a text stream object for writing to a std::ostream.
Definition textstream.h:48
std::ostream * m_s
Definition textstream.h:286
void write(const char *buf, size_t len)
Adds a array of character to the stream.
Definition textstream.h:204
void operator+=(unsigned char c)
Definition textstream.h:188
void operator+=(signed int i)
Definition textstream.h:195
void operator+=(signed short i)
Definition textstream.h:193
void operator+=(const unsigned char *s)
Definition textstream.h:189
~TextStream()
Writes any data that is buffered to the attached std::ostream.
Definition textstream.h:60
std::string str() const
Return the contents of the buffer as a std::string object.
Definition textstream.h:232
void operator+=(unsigned int i)
Definition textstream.h:196
void str(const char *s)
Sets the buffer's contents to string s Any data already in the buffer will be flushed.
Definition textstream.h:249
TextStream(size_t capacity=INITIAL_CAPACITY)
Creates an empty stream object.
Definition textstream.h:41
void operator+=(const std::string &s)
Definition textstream.h:192
void operator+=(char c)
Definition textstream.h:187
static const int INITIAL_CAPACITY
Definition textstream.h:37
TextStream & operator<<(unsigned char c)
Adds an unsigned character to the stream.
Definition textstream.h:90
void setFile(FILE *f)
Definition textstream.h:74
TextStream & operator<<(char c)
Adds a character to the stream.
Definition textstream.h:82
void clear()
Clears any buffered data.
Definition textstream.h:226
TextStream & operator<<(unsigned int i)
Adds a unsigned integer to the stream.
Definition textstream.h:154
#define ONLY_DEFAULT_MOVABLE(cls)
Macro to help implementing the rule of 5 for a class that can be moved but not copied.
Definition construct.h:44
Definition dstring.h:902