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 "qcstring.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 static_cast<TextStream&>(*this);
86 }
87 /** Adds an unsigned character to the stream */
88 TextStream &operator<<( unsigned char c)
89 {
90 m_buffer+=c;
91 return static_cast<TextStream&>(*this);
92 }
93
94 /** Adds an unsigned character string to the stream */
95 TextStream &operator<<( unsigned char *s)
96 {
97 if (s)
98 {
99 unsigned char *p = s;
100 while(*p)
101 {
102 m_buffer+=*p;
103 p++;
104 }
105 }
106 return static_cast<TextStream&>(*this);
107 }
108
109 /** Adds a C-style string to the stream */
110 TextStream &operator<<( const char *s)
111 {
112 if (s) m_buffer+=s;
113 return static_cast<TextStream&>(*this);
114 }
115
116 /** Adds a QCString to the stream */
118 {
119 m_buffer+=s.str();
120 return static_cast<TextStream&>(*this);
121 }
122
123 /** Adds a std::string to the stream */
124 TextStream &operator<<( const std::string &s )
125 {
126 m_buffer+=s;
127 return static_cast<TextStream&>(*this);
128 }
129
130 /** Adds a signed short integer to the stream */
131 TextStream &operator<<( signed short i)
132 {
133 output_int32(i,i<0);
134 return static_cast<TextStream&>(*this);
135 }
136
137 /** Adds a unsigned short integer to the stream */
138 TextStream &operator<<( unsigned short i)
139 {
140 output_int32(i,false);
141 return static_cast<TextStream&>(*this);
142 }
143
144 /** Adds a signed integer to the stream */
145 TextStream &operator<<( signed int i)
146 {
147 output_int32(i,i<0);
148 return static_cast<TextStream&>(*this);
149 }
150
151 /** Adds a unsigned integer to the stream */
152 TextStream &operator<<( unsigned int i)
153 {
154 output_int32(i,false);
155 return static_cast<TextStream&>(*this);
156 }
157
158 /** Adds a size_t integer to the stream.
159 * We use SFINAE to avoid a compiler error in case size_t already matches the 'unsigned int' overload.
160 */
161 template<typename T,
162 typename std::enable_if<std::is_same<T,size_t>::value,T>::type* = nullptr
163 >
165 {
166 output_int32(static_cast<uint32_t>(i),false);
167 return static_cast<TextStream&>(*this);
168 }
169
170 /** Adds a float to the stream */
172 {
173 output_double(static_cast<double>(f));
174 return static_cast<TextStream&>(*this);
175 }
176
177 /** Adds a double to the stream */
179 {
180 output_double(d);
181 return static_cast<TextStream&>(*this);
182 }
183
184 /** Adds a array of character to the stream
185 * @param buf the character buffer
186 * @param len the number of characters in the buffer to write
187 */
188 void write(const char *buf,size_t len)
189 {
190 m_buffer.append(buf,len);
191 }
192
193 /** Flushes the buffer. If a std::ostream is attached, the buffer's
194 * contents will be written to the stream.
195 */
196 void flush()
197 {
198 if (m_s)
199 {
200 m_s->write(m_buffer.c_str(),m_buffer.length());
201 }
202 else if (m_f)
203 {
204 fwrite(m_buffer.c_str(),1,m_buffer.length(),m_f);
205 }
206 m_buffer.clear();
207 }
208
209 /** Clears any buffered data */
210 void clear()
211 {
212 m_buffer.clear();
213 }
214
215 /** Return the contents of the buffer as a std::string object */
216 std::string str() const
217 {
218 return m_buffer;
219 }
220
221 /** Sets the buffer's contents to string \a s.
222 * Any data already in the buffer will be flushed.
223 */
224 void str(const std::string &s)
225 {
226 flush();
227 m_buffer=s;
228 }
229
230 /** Sets the buffer's contents to string \a s
231 * Any data already in the buffer will be flushed.
232 */
233 void str(const char *s)
234 {
235 flush();
236 if (s) m_buffer=s;
237 }
238
239 /** Returns true iff the buffer is empty */
240 bool empty() const
241 {
242 return m_buffer.empty();
243 }
244
245 private:
246 /** Writes a string representation of an integer to the buffer
247 * @param n the absolute value of the integer
248 * @param neg indicates if the integer is negative
249 */
250 void output_int32( uint32_t n, bool neg )
251 {
252 char buf[20];
253 char *p = &buf[19];
254 *p = '\0';
255 if ( neg )
256 {
257 n = static_cast<uint32_t>(-static_cast<int32_t>(n));
258 }
259 do { *--p = (static_cast<char>(n%10)) + '0'; n /= 10; } while ( n );
260 if ( neg ) *--p = '-';
261 m_buffer+=p;
262 }
263 void output_double( double d)
264 {
265 char buf[64];
266 snprintf(buf,64,"%f",d);
267 m_buffer+=buf;
268 }
269 std::string m_buffer;
270 std::ostream *m_s = nullptr;
271 FILE *m_f = nullptr;
272};
273
274#endif
This is an alternative implementation of QCString.
Definition qcstring.h:101
const std::string & str() const
Definition qcstring.h:552
Text streaming class that buffers data.
Definition textstream.h:36
bool empty() const
Returns true iff the buffer is empty.
Definition textstream.h:240
TextStream & operator<<(unsigned char *s)
Adds an unsigned character string to the stream.
Definition textstream.h:95
void setStream(std::ostream *s)
Sets or changes the std::ostream to write to.
Definition textstream.h:67
TextStream & operator<<(const std::string &s)
Adds a std::string to the stream.
Definition textstream.h:124
void output_double(double d)
Definition textstream.h:263
TextStream & operator<<(float f)
Adds a float to the stream.
Definition textstream.h:171
TextStream & operator<<(unsigned short i)
Adds a unsigned short integer to the stream.
Definition textstream.h:138
void output_int32(uint32_t n, bool neg)
Writes a string representation of an integer to the buffer.
Definition textstream.h:250
TextStream & operator<<(signed int i)
Adds a signed integer to the stream.
Definition textstream.h:145
std::string m_buffer
Definition textstream.h:269
TextStream & operator<<(double d)
Adds a double to the stream.
Definition textstream.h:178
TextStream & operator<<(T i)
Adds a size_t integer to the stream.
Definition textstream.h:164
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:224
TextStream & operator<<(const QCString &s)
Adds a QCString to the stream.
Definition textstream.h:117
TextStream & operator<<(signed short i)
Adds a signed short integer to the stream.
Definition textstream.h:131
TextStream & operator<<(const char *s)
Adds a C-style string to the stream.
Definition textstream.h:110
FILE * m_f
Definition textstream.h:271
void flush()
Flushes the buffer.
Definition textstream.h:196
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:270
void write(const char *buf, size_t len)
Adds a array of character to the stream.
Definition textstream.h:188
~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:216
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:233
TextStream(size_t capacity=INITIAL_CAPACITY)
Creates an empty stream object.
Definition textstream.h:41
static const int INITIAL_CAPACITY
Definition textstream.h:37
TextStream & operator<<(unsigned char c)
Adds an unsigned character to the stream.
Definition textstream.h:88
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:210
TextStream & operator<<(unsigned int i)
Adds a unsigned integer to the stream.
Definition textstream.h:152
#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