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