1 #ifndef CPPUNIT_PORTABILITY_STREAM_H_INCLUDED
2 #define CPPUNIT_PORTABILITY_STREAM_H_INCLUDED
3
4 // This module define:
5 // Type CppUT::Stream (either std::stream or a custom type)
6 // Type CppUT::OStringStream (eitjer std::ostringstream, older alternate or a custom type)
7 // Functions stdCOut() & stdCErr() which returns a reference on cout & cerr stream (or our
8 // custom stream).
9
10 #include <cppunit/Portability.h>
11
12
13 #if defined( CPPUNIT_NO_STREAM )
14
15 #include <string>
16 #include <stdio.h>
17 #include <string.h>
18
19 CPPUNIT_NS_BEGIN
20
21 class StreamBuffer
22 {
23 public:
~StreamBuffer()24 virtual ~StreamBuffer() {}
25
26 virtual void write( const char *text, unsigned int length ) = 0;
27
flush()28 virtual void flush() {}
29 };
30
31
32 class StringStreamBuffer : public StreamBuffer
33 {
34 public:
str()35 std::string str() const
36 {
37 return str_;
38 }
39
40 public: // overridden from StreamBuffer
write(const char * text,unsigned int length)41 void write( const char *text, unsigned int length )
42 {
43 str_.append( text, length );
44 }
45
46 private:
47 std::string str_;
48 };
49
50
51 class FileStreamBuffer : public StreamBuffer
52 {
53 public:
FileStreamBuffer(FILE * file)54 FileStreamBuffer( FILE *file )
55 : file_( file )
56 {
57 }
58
file()59 FILE *file() const
60 {
61 return file_;
62 }
63
64 public: // overridden from StreamBuffer
write(const char * text,unsigned int length)65 void write( const char *text, unsigned int length )
66 {
67 if ( file_ )
68 fwrite( text, sizeof(char), length, file_ );
69 }
70
flush()71 void flush()
72 {
73 if ( file_ )
74 fflush( file_ );
75 }
76
77 private:
78 FILE *file_;
79 };
80
81
82 class OStream
83 {
84 public:
OStream()85 OStream()
86 : buffer_( 0 )
87 {
88 }
89
OStream(StreamBuffer * buffer)90 OStream( StreamBuffer *buffer )
91 : buffer_( buffer )
92 {
93 }
94
~OStream()95 virtual ~OStream()
96 {
97 flush();
98 }
99
flush()100 OStream &flush()
101 {
102 if ( buffer_ )
103 buffer_->flush();
104 return *this;
105 }
106
setBuffer(StreamBuffer * buffer)107 void setBuffer( StreamBuffer *buffer )
108 {
109 buffer_ = buffer;
110 }
111
write(const char * text,unsigned int length)112 OStream &write( const char *text, unsigned int length )
113 {
114 if ( buffer_ )
115 buffer_->write( text, length );
116 return *this;
117 }
118
write(const char * text)119 OStream &write( const char *text )
120 {
121 return write( text, strlen(text) );
122 }
123
124 OStream &operator <<( bool v )
125 {
126 const char *out = v ? "true" : "false";
127 return write( out );
128 }
129
130 OStream &operator <<( short v )
131 {
132 char buffer[64];
133 sprintf( buffer, "%hd", v );
134 return write( buffer );
135 }
136
137 OStream &operator <<( unsigned short v )
138 {
139 char buffer[64];
140 sprintf( buffer, "%hu", v );
141 return write( buffer );
142 }
143
144 OStream &operator <<( int v )
145 {
146 char buffer[64];
147 sprintf( buffer, "%d", v );
148 return write( buffer );
149 }
150
151 OStream &operator <<( unsigned int v )
152 {
153 char buffer[64];
154 sprintf( buffer, "%u", v );
155 return write( buffer );
156 }
157
158 OStream &operator <<( long v )
159 {
160 char buffer[64];
161 sprintf( buffer, "%ld", v );
162 return write( buffer );
163 }
164
165 OStream &operator <<( unsigned long v )
166 {
167 char buffer[64];
168 sprintf( buffer, "%lu", v );
169 return write( buffer );
170 }
171
172 OStream &operator <<( float v )
173 {
174 char buffer[128];
175 sprintf( buffer, "%.16g", double(v) );
176 return write( buffer );
177 }
178
179 OStream &operator <<( double v )
180 {
181 char buffer[128];
182 sprintf( buffer, "%.16g", v );
183 return write( buffer );
184 }
185
186 OStream &operator <<( long double v )
187 {
188 char buffer[128];
189 sprintf( buffer, "%.16g", double(v) );
190 return write( buffer );
191 }
192
193 OStream &operator <<( const void *v )
194 {
195 char buffer[64];
196 sprintf( buffer, "%p", v );
197 return write( buffer );
198 }
199
200 OStream &operator <<( const char *v )
201 {
202 return write( v ? v : "NULL" );
203 }
204
205 OStream &operator <<( char c )
206 {
207 char buffer[16];
208 sprintf( buffer, "%c", c );
209 return write( buffer );
210 }
211
212 OStream &operator <<( const std::string &s )
213 {
214 return write( s.c_str(), s.length() );
215 }
216
217 private:
218 StreamBuffer *buffer_;
219 };
220
221
222 class OStringStream : public OStream
223 {
224 public:
OStringStream()225 OStringStream()
226 : OStream( &buffer_ )
227 {
228 }
229
str()230 std::string str() const
231 {
232 return buffer_.str();
233 }
234
235 private:
236 StringStreamBuffer buffer_;
237 };
238
239
240 class OFileStream : public OStream
241 {
242 public:
OFileStream(FILE * file)243 OFileStream( FILE *file )
244 : OStream( &buffer_ )
245 , buffer_( file )
246 , ownFile_( false )
247 {
248 }
249
OFileStream(const char * path)250 OFileStream( const char *path )
251 : OStream( &buffer_ )
252 , buffer_( fopen( path, "wt" ) )
253 , ownFile_( true )
254 {
255 }
256
~OFileStream()257 virtual ~OFileStream()
258 {
259 if ( ownFile_ && buffer_.file() )
260 fclose( buffer_.file() );
261 }
262
263 private:
264 FileStreamBuffer buffer_;
265 bool ownFile_;
266 };
267
stdCOut()268 inline OStream &stdCOut()
269 {
270 static OFileStream stream( stdout );
271 return stream;
272 }
273
stdCErr()274 inline OStream &stdCErr()
275 {
276 static OFileStream stream( stderr );
277 return stream;
278 }
279
280 CPPUNIT_NS_END
281
282 #elif CPPUNIT_HAVE_SSTREAM // #if defined( CPPUNIT_NO_STREAM )
283 # include <sstream>
284 # include <fstream>
285
286 CPPUNIT_NS_BEGIN
287 typedef std::ostringstream OStringStream; // The standard C++ way
288 typedef std::ofstream OFileStream;
289 CPPUNIT_NS_END
290
291
292 #elif CPPUNIT_HAVE_CLASS_STRSTREAM
293 # include <string>
294 # if CPPUNIT_HAVE_STRSTREAM
295 # include <strstream>
296 # else // CPPUNIT_HAVE_STRSTREAM
297 # include <strstream.h>
298 # endif // CPPUNIT_HAVE_CLASS_STRSTREAM
299
300 CPPUNIT_NS_BEGIN
301
302 class OStringStream : public std::ostrstream
303 {
304 public:
305 std::string str()
306 {
307 // (*this) << '\0';
308 // std::string msg(std::ostrstream::str());
309 // std::ostrstream::freeze(false);
310 // return msg;
311 // Alternative implementation that don't rely on freeze which is not
312 // available on some platforms:
313 return std::string( std::ostrstream::str(), pcount() );
314 }
315 };
316
317 CPPUNIT_NS_END
318 #else // CPPUNIT_HAVE_CLASS_STRSTREAM
319 # error Cannot define CppUnit::OStringStream.
320 #endif // #if defined( CPPUNIT_NO_STREAM )
321
322
323
324 #if !defined( CPPUNIT_NO_STREAM )
325
326 #include <iostream>
327
328 CPPUNIT_NS_BEGIN
329
330 typedef std::ostream OStream;
331
stdCOut()332 inline OStream &stdCOut()
333 {
334 return std::cout;
335 }
336
stdCErr()337 inline OStream &stdCErr()
338 {
339 return std::cerr;
340 }
341
342 CPPUNIT_NS_END
343
344 #endif // #if !defined( CPPUNIT_NO_STREAM )
345
346 #endif // CPPUNIT_PORTABILITY_STREAM_H_INCLUDED
347
348