1 /* 2 * Created by Phil on 17/01/2011. 3 * Copyright 2011 Two Blue Cubes Ltd. All rights reserved. 4 * 5 * Distributed under the Boost Software License, Version 1.0. (See accompanying 6 * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 * 8 */ 9 #ifndef TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED 10 #define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED 11 12 #include "catch_stream.h" 13 #include "catch_debugger.h" 14 15 #include <stdexcept> 16 #include <cstdio> 17 #include <iostream> 18 19 namespace Catch { 20 21 template<typename WriterF, size_t bufferSize=256> 22 class StreamBufImpl : public StreamBufBase { 23 char data[bufferSize]; 24 WriterF m_writer; 25 26 public: StreamBufImpl()27 StreamBufImpl() { 28 setp( data, data + sizeof(data) ); 29 } 30 ~StreamBufImpl()31 ~StreamBufImpl() CATCH_NOEXCEPT { 32 sync(); 33 } 34 35 private: overflow(int c)36 int overflow( int c ) { 37 sync(); 38 39 if( c != EOF ) { 40 if( pbase() == epptr() ) 41 m_writer( std::string( 1, static_cast<char>( c ) ) ); 42 else 43 sputc( static_cast<char>( c ) ); 44 } 45 return 0; 46 } 47 sync()48 int sync() { 49 if( pbase() != pptr() ) { 50 m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) ); 51 setp( pbase(), epptr() ); 52 } 53 return 0; 54 } 55 }; 56 57 /////////////////////////////////////////////////////////////////////////// 58 59 FileStream(std::string const & filename)60 FileStream::FileStream( std::string const& filename ) { 61 m_ofs.open( filename.c_str() ); 62 if( m_ofs.fail() ) { 63 std::ostringstream oss; 64 oss << "Unable to open file: '" << filename << '\''; 65 throw std::domain_error( oss.str() ); 66 } 67 } 68 stream() const69 std::ostream& FileStream::stream() const { 70 return m_ofs; 71 } 72 73 struct OutputDebugWriter { 74 operator ()Catch::OutputDebugWriter75 void operator()( std::string const&str ) { 76 writeToDebugConsole( str ); 77 } 78 }; 79 DebugOutStream()80 DebugOutStream::DebugOutStream() 81 : m_streamBuf( new StreamBufImpl<OutputDebugWriter>() ), 82 m_os( m_streamBuf.get() ) 83 {} 84 stream() const85 std::ostream& DebugOutStream::stream() const { 86 return m_os; 87 } 88 89 // Store the streambuf from cout up-front because 90 // cout may get redirected when running tests CoutStream()91 CoutStream::CoutStream() 92 : m_os( Catch::cout().rdbuf() ) 93 {} 94 stream() const95 std::ostream& CoutStream::stream() const { 96 return m_os; 97 } 98 99 #ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions cout()100 std::ostream& cout() { 101 return std::cout; 102 } cerr()103 std::ostream& cerr() { 104 return std::cerr; 105 } clog()106 std::ostream& clog() { 107 return std::clog; 108 } 109 #endif 110 } 111 112 #endif // TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED 113