Paul J. Lucas has proposed merging lp:~paul-lucas/zorba/bug-1189636 into lp:zorba.
Commit message: * Added hexbinary::streambuf and friends. * Fixed buffer overflow bug in base64::streambuf::xsputn(). Requested reviews: Paul J. Lucas (paul-lucas) Related bugs: Bug #1189636 in Zorba: "transcoding hexBinary streambuf" https://bugs.launchpad.net/zorba/+bug/1189636 For more details, see: https://code.launchpad.net/~paul-lucas/zorba/bug-1189636/+merge/170471 * Added hexbinary::streambuf and friends. * Fixed buffer overflow bug in base64::streambuf::xsputn(). -- https://code.launchpad.net/~paul-lucas/zorba/bug-1189636/+merge/170471 Your team Zorba Coders is subscribed to branch lp:zorba.
=== modified file 'ChangeLog' --- ChangeLog 2013-06-19 19:27:26 +0000 +++ ChangeLog 2013-06-20 00:55:33 +0000 @@ -23,6 +23,7 @@ Bug Fixes/Other Changes: * Fixed bug #1117952 (Improve XML error output format) * Fixed bug #1188084 (fn-replace-42 failing) + * Fixed bug #1189636 (transcoding hexBinary streambuf) * Fixed bug in hoisting through try-catch expr * Fixed bug #1162631 (format-integer 'w' format of negative numbers) * Fixed bug #1190261 (relative paths bug in file module) === modified file 'include/zorba/util/base64_stream.h' --- include/zorba/util/base64_stream.h 2013-06-12 00:21:05 +0000 +++ include/zorba/util/base64_stream.h 2013-06-20 00:55:33 +0000 @@ -198,7 +198,7 @@ * destroyed. * \code * void f( ostream &os ) { - * base64::auto_attach<ostream> const raii( os, "ISO-8859-1" ); + * base64::auto_attach<ostream> const raii( os ); * // ... * } * \endcode === added file 'include/zorba/util/hexbinary_stream.h' --- include/zorba/util/hexbinary_stream.h 1970-01-01 00:00:00 +0000 +++ include/zorba/util/hexbinary_stream.h 2013-06-20 00:55:33 +0000 @@ -0,0 +1,310 @@ +/* + * Copyright 2006-2008 The FLWOR Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ZORBA_HEXBINARY_STREAM_API_H +#define ZORBA_HEXBINARY_STREAM_API_H + +#include <streambuf> + +#include <zorba/config.h> +#include <zorba/internal/cxx_util.h> +#include <zorba/internal/streambuf.h> + +namespace zorba { +namespace hexbinary { + +/////////////////////////////////////////////////////////////////////////////// + +/** + * A %hexbinary::streambuf is-a std::streambuf for encoding to and decoding + * from HexBinary on-the-fly. + * + * To use it, replace a stream's streambuf: + * \code + * istream is; + * // ... + * hexbinary::streambuf hb_buf( is.rdbuf() ); + * is.ios::rdbuf( &hb_buf ); + * \endcode + * Note that the %hexbinary::streambuf must exist for as long as it's being + * used by the stream. If you are replacing the streabuf for a stream you did + * not create, you should set it back to the original streambuf: + * \code + * void f( ostream &os ) { + * hexbinary::streambuf hb_buf( os.rdbuf() ); + * try { + * os.ios::rdbuf( &hb_buf ); + * // ... + * } + * catch ( ... ) { + * os.ios::rdbuf( hb_buf.orig_streambuf() ); + * throw; + * } + * os.ios::rdbuf( hb_buf.orig_streambuf() ); + * } + * \endcode + * Alternatively, you may wish to use either \c attach(), \c auto_attach, or + * \c hexbinary::stream instead. + * + * While %hexbinary::streambuf does support seeking, the positions are relative + * to the original byte stream. + */ +class ZORBA_DLL_PUBLIC streambuf : public std::streambuf { +public: + /** + * Constructs a %hexbinary::streambuf. + * + * @param orig The original streambuf to read/write from/to. + * @throws std::invalid_argument if is not supported or \a orig is null. + */ + streambuf( std::streambuf *orig ); + + /** + * Gets the original streambuf. + * + * @return said streambuf. + */ + std::streambuf* orig_streambuf() const { + return orig_buf_; + } + +protected: + void imbue( std::locale const& ); + pos_type seekoff( off_type, std::ios_base::seekdir, std::ios_base::openmode ); + pos_type seekpos( pos_type, std::ios_base::openmode ); + std::streambuf* setbuf( char_type*, std::streamsize ); + std::streamsize showmanyc(); + int_type overflow( int_type ); + int_type pbackfail( int_type ); + int_type underflow(); + std::streamsize xsgetn( char_type*, std::streamsize ); + std::streamsize xsputn( char_type const*, std::streamsize ); + +private: + std::streambuf *orig_buf_; + char gbuf_[2]; + + void clear(); + + // forbid + streambuf( streambuf const& ); + streambuf& operator=( streambuf const& ); +}; + +/////////////////////////////////////////////////////////////////////////////// + +} // namespace hexbinary + +namespace internal { +namespace hexbinary { + +ZORBA_DLL_PUBLIC +std::streambuf* alloc_streambuf( std::streambuf *orig ); + +ZORBA_DLL_PUBLIC +int get_streambuf_index(); + +} // namespace hexbinary +} // namespace internal + +namespace hexbinary { + +/////////////////////////////////////////////////////////////////////////////// + +/** + * Attaches a hexbinary::streambuf to a stream. Unlike using a + * hexbinary::streambuf directly, this function will create the streambuf, + * attach it to the stream, and manage it for the lifetime of the stream + * automatically. + * + * @param ios The stream to attach the hexbinary::streambuf to. If the stream + * already has a hexbinary::streambuf attached to it, this function does + * nothing. + */ +template<typename charT,class Traits> inline +void attach( std::basic_ios<charT,Traits> &ios ) { + int const index = internal::hexbinary::get_streambuf_index(); + void *&pword = ios.pword( index ); + if ( !pword ) { + std::streambuf *const buf = + internal::hexbinary::alloc_streambuf( ios.rdbuf() ); + ios.rdbuf( buf ); + pword = buf; + ios.register_callback( internal::stream_callback, index ); + } +} + +/** + * Detaches a previously attached hexbinary::streambuf from a stream. The + * streambuf is destroyed and the stream's original streambuf is restored. + * + * @param ios The stream to detach the hexbinary::streambuf from. If the + * stream doesn't have a hexbinary::streambuf attached to it, this function + * does nothing. + */ +template<typename charT,class Traits> inline +void detach( std::basic_ios<charT,Traits> &ios ) { + int const index = internal::hexbinary::get_streambuf_index(); + if ( streambuf *const buf = static_cast<streambuf*>( ios.pword( index ) ) ) { + ios.pword( index ) = nullptr; + ios.rdbuf( buf->orig_streambuf() ); + internal::dealloc_streambuf( buf ); + } +} + +/** + * Checks whether the given stream has a hexbinary::streambuf attached. + * + * @param ios The stream to check. + * @return \c true only if a hexbinary::streambuf is attached. + */ +template<typename charT,class Traits> inline +bool is_attached( std::basic_ios<charT,Traits> &ios ) { + return !!ios.pword( internal::hexbinary::get_streambuf_index() ); +} + +/** + * A %hexbinary::auto_attach is a class that attaches a hexbinary::streambuf to + * a stream and automatically detaches it when the %auto_attach object is + * destroyed. + * \code + * void f( ostream &os ) { + * hexbinary::auto_attach<ostream> const raii( os ); + * // ... + * } + * \endcode + * A %hexbinary::auto_attach is useful for streams not created by you. + * + * @see http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization + */ +template<class StreamType> +class auto_attach { +public: + /** + * Constructs an %auto_attach object calling attach() on the given stream. + * + * @param stream The stream to attach the hexbinary::streambuf to. If the + * stream already has a hexbinary::streambuf attached to it, this contructor + * does nothing. + */ + auto_attach( StreamType &stream ) : stream_( stream ) { + attach( stream ); + } + + /** + * Destroys this %auto_attach object calling detach() on the previously + * attached stream. + */ + ~auto_attach() { + detach( stream_ ); + } + +private: + StreamType &stream_; +}; + +/////////////////////////////////////////////////////////////////////////////// + +/** + * A %hexbinary::stream is used to wrap a C++ standard I/O stream with a + * hexbinary::streambuf so that encoding/decoding and the management of the + * streambuf happens automatically. + * + * A %hexbinary::stream is useful for streams created by you. + * + * @tparam StreamType The I/O stream class type to wrap. It must be a concrete + * stream class. + */ +template<class StreamType> +class stream : public StreamType { +public: + /** + * Constructs a %hexbinary::stream. + */ + stream() : +#ifdef WIN32 +# pragma warning( push ) +# pragma warning( disable : 4355 ) +#endif /* WIN32 */ + hb_buf_( this->rdbuf() ) +#ifdef WIN32 +# pragma warning( pop ) +#endif /* WIN32 */ + { + init(); + } + + /** + * Constructs a %stream. + * + * @tparam StreamArgType The type of the first argument of \a StreamType's + * constructor. + * @param stream_arg The argument to pass as the first argument to + * \a StreamType's constructor. + */ + template<typename StreamArgType> + stream( StreamArgType stream_arg ) : + StreamType( stream_arg ), +#ifdef WIN32 +# pragma warning( push ) +# pragma warning( disable : 4355 ) +#endif /* WIN32 */ + hb_buf_( this->rdbuf() ) +#ifdef WIN32 +# pragma warning( pop ) +#endif /* WIN32 */ + { + init(); + } + + /** + * Constructs a %hexbinary::stream. + * + * @tparam StreamArgType The type of the first argument of \a StreamType's + * constructor. + * @param stream_arg The argument to pass as the first argument to + * \a StreamType's constructor. + * @param mode The open-mode to pass to \a StreamType's constructor. + */ + template<typename StreamArgType> + stream( StreamArgType stream_arg, std::ios_base::openmode mode ) : + StreamType( stream_arg, mode ), +#ifdef WIN32 +# pragma warning( push ) +# pragma warning( disable : 4355 ) +#endif /* WIN32 */ + hb_buf_( this->rdbuf() ) +#ifdef WIN32 +# pragma warning( pop ) +#endif /* WIN32 */ + { + init(); + } + +private: + streambuf hb_buf_; + + void init() { + this->std::ios::rdbuf( &hb_buf_ ); + } +}; + +/////////////////////////////////////////////////////////////////////////////// + +} // namespace hexbinary +} // namespace zorba +#endif /* ZORBA_HEXBINARY_STREAM_API_H */ +/* vim:set et sw=2 ts=2: */ === modified file 'src/api/CMakeLists.txt' --- src/api/CMakeLists.txt 2013-05-31 03:38:45 +0000 +++ src/api/CMakeLists.txt 2013-06-20 00:55:33 +0000 @@ -25,6 +25,7 @@ dynamiccontextimpl.cpp resultiteratorimpl.cpp zorba_string.cpp + hexbinary_streambuf.cpp itemfactoryimpl.cpp item.cpp identtypesimpl.cpp === modified file 'src/api/base64_streambuf.cpp' --- src/api/base64_streambuf.cpp 2013-06-11 23:38:49 +0000 +++ src/api/base64_streambuf.cpp 2013-06-20 00:55:33 +0000 @@ -44,6 +44,11 @@ plen_ = 0; } +inline void streambuf::clear() { + resetg(); + resetp(); +} + inline void streambuf::writep() { char chunk[4]; orig_buf_->sputn( chunk, base64::encode( pbuf_, plen_, chunk ) ); @@ -60,11 +65,6 @@ writep(); } -void streambuf::clear() { - resetg(); - resetp(); -} - void streambuf::imbue( std::locale const &loc ) { orig_buf_->pubimbue( loc ); } @@ -153,7 +153,7 @@ if ( streamsize const gsize = egptr() - gptr() ) { // - // Get any chunk fragment pending the the get buffer first. + // Get any chunk fragment pending in the get buffer first. // streamsize const n = min( gsize, size ); traits_type::copy( to, gptr(), static_cast<size_t>( n ) ); @@ -198,7 +198,9 @@ while ( size >= 3 ) { char ebuf[ Large_External_Buf_Size ]; - streamsize const put = min( (streamsize)(sizeof ebuf), size ); + static streamsize const esize = + (streamsize)base64::decoded_size( sizeof ebuf ); + streamsize const put = min( esize, size ); streamsize const encoded = base64::encode( from, static_cast<size_type>( put ), ebuf ); orig_buf_->sputn( ebuf, encoded ); === added file 'src/api/hexbinary_streambuf.cpp' --- src/api/hexbinary_streambuf.cpp 1970-01-01 00:00:00 +0000 +++ src/api/hexbinary_streambuf.cpp 2013-06-20 00:55:33 +0000 @@ -0,0 +1,216 @@ +/* + * Copyright 2006-2008 The FLWOR Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "stdafx.h" + +#include <stdexcept> + +//#define ZORBA_DEBUG_HEXBINARY_STREAMBUF +#ifdef ZORBA_DEBUG_HEXBINARY_STREAMBUF +# include <stdio.h> +#endif + +#include <zorba/util/hexbinary_stream.h> + +#include "util/hexbinary_util.h" + +using namespace std; + +namespace zorba { +namespace hexbinary { + +int const Large_External_Buf_Size = 4096; + +/////////////////////////////////////////////////////////////////////////////// + +inline void streambuf::clear() { + setg( gbuf_, gbuf_ + sizeof gbuf_, gbuf_ + sizeof gbuf_ ); +} + +streambuf::streambuf( std::streambuf *orig ) : orig_buf_( orig ) { + if ( !orig ) + throw invalid_argument( "null streambuf" ); + clear(); +} + +void streambuf::imbue( std::locale const &loc ) { + orig_buf_->pubimbue( loc ); +} + +streambuf::pos_type streambuf::seekoff( off_type o, ios_base::seekdir d, + ios_base::openmode m ) { + clear(); + return orig_buf_->pubseekoff( o, d, m ); +} + +streambuf::pos_type streambuf::seekpos( pos_type p, ios_base::openmode m ) { + clear(); + return orig_buf_->pubseekpos( p, m ); +} + +std::streambuf* streambuf::setbuf( char_type *p, streamsize s ) { + orig_buf_->pubsetbuf( p, s ); + return this; +} + +streamsize streambuf::showmanyc() { + return orig_buf_->in_avail(); +} + +streambuf::int_type streambuf::overflow( int_type c ) { +#ifdef ZORBA_DEBUG_HEXBINARY_STREAMBUF + printf( "overflow()\n" ); +#endif + bool const is_eof = traits_type::eq_int_type( c, traits_type::eof() ); + if ( !is_eof ) { + char const p = traits_type::to_char_type( c ); + char ebuf[2]; + orig_buf_->sputn( ebuf, hexbinary::encode( &p, 1, ebuf ) ); + } + return c; +} + +streambuf::int_type streambuf::pbackfail( int_type c ) { + if ( !traits_type::eq_int_type( c, traits_type::eof() ) && + gptr() > eback() ) { + c = orig_buf_->sputbackc( traits_type::to_char_type( c ) ); + if ( !traits_type::eq_int_type( c, traits_type::eof() ) ) + gbump( -1 ); + return c; + } + return traits_type::eof(); +} + +streambuf::int_type streambuf::underflow() { +#ifdef ZORBA_DEBUG_HEXBINARY_STREAMBUF + printf( "underflow()\n" ); +#endif + char chunk[2]; + int chunk_len = 0; + + while ( gptr() >= egptr() ) { + int_type const c = orig_buf_->sbumpc(); + bool is_eof = false; + if ( traits_type::eq_int_type( c, traits_type::eof() ) ) { + if ( !chunk_len ) + return traits_type::eof(); + is_eof = true; + } else { + chunk[ chunk_len++ ] = traits_type::to_char_type( c ); + } + if ( chunk_len == sizeof chunk || (is_eof && chunk_len) ) { + streamsize const n = hexbinary::decode( chunk, chunk_len, eback() ); + setg( gbuf_, gbuf_, gbuf_ + n ); + } + } + return traits_type::to_int_type( *gptr() ); +} + +streamsize streambuf::xsgetn( char_type *to, streamsize size ) { +#ifdef ZORBA_DEBUG_HEXBINARY_STREAMBUF + printf( "xsgetn()\n" ); +#endif + streamsize return_size = 0; + + if ( streamsize const gsize = egptr() - gptr() ) { + // + // Get any chunk fragment pending in the get buffer first. + // + streamsize const n = min( gsize, size ); + traits_type::copy( to, gptr(), static_cast<size_t>( n ) ); + gbump( static_cast<int>( n ) ); + to += n; + size -= n, return_size += n; + } + + // + // Must get bytes in terms of encoded size. + // + size = hexbinary::encoded_size( static_cast<size_type>( size ) ); + + while ( size ) { + char ebuf[ Large_External_Buf_Size ]; + streamsize const get = min( (streamsize)(sizeof ebuf), size ); + if ( streamsize got = orig_buf_->sgetn( ebuf, get ) ) { + streamsize const decoded = + hexbinary::decode( ebuf, static_cast<size_type>( got ), to ); + to += decoded; + size -= got, return_size += decoded; + } else + break; + } + + return return_size; +} + +streamsize streambuf::xsputn( char_type const *from, streamsize size ) { +#ifdef ZORBA_DEBUG_HEXBINARY_STREAMBUF + printf( "xsputn()\n" ); +#endif + streamsize return_size = 0; + + while ( size ) { + char ebuf[ Large_External_Buf_Size ]; + static streamsize const esize = + (streamsize)hexbinary::decoded_size( sizeof ebuf ); + streamsize const put = min( esize, size ); + streamsize const encoded = + hexbinary::encode( from, static_cast<size_type>( put ), ebuf ); + orig_buf_->sputn( ebuf, encoded ); + from += put, size -= put, return_size += put; + } + + return return_size; +} + +/////////////////////////////////////////////////////////////////////////////// + +} // namespace hexbinary + +namespace internal { +namespace hexbinary { + +// Both new & delete are done inside Zorba rather than in the header to +// guarantee that they're cross-DLL-boundary safe on Windows. + +std::streambuf* alloc_streambuf( std::streambuf *orig ) { + return new zorba::hexbinary::streambuf( orig ); +} + +int get_streambuf_index() { + // + // This function is out-of-line because it has a static constant within it. + // It has a static constant within it to guarantee (1) initialization before + // use and (2) initialization happens exactly once. + // + // See: "Standard C++ IOStreams and Locales: Advanced Programmer's Guide and + // Reference," Angelika Langer and Klaus Kreft, Addison-Wesley, 2000, section + // 3.3.1.1: "Initializing and Maintaining the iword/pword Index." + // + // See: "The C++ Programming Language," Bjarne Stroustrup, Addison-Wesley, + // 2000, section 10.4.8: "Local Static Store." + // + static int const index = ios_base::xalloc(); + return index; +} + +} // namespace hexbinary +} // namespace internal + +/////////////////////////////////////////////////////////////////////////////// + +} // namespace zorba +/* vim:set et sw=2 ts=2: */ === modified file 'src/unit_tests/CMakeLists.txt' --- src/unit_tests/CMakeLists.txt 2013-05-31 03:38:45 +0000 +++ src/unit_tests/CMakeLists.txt 2013-06-20 00:55:33 +0000 @@ -20,6 +20,7 @@ test_fs_util.cpp test_hashmaps.cpp test_hexbinary.cpp + test_hexbinary_streambuf.cpp test_json_parser.cpp test_mem_sizeof.cpp test_parameters.cpp === added file 'src/unit_tests/test_hexbinary_streambuf.cpp' --- src/unit_tests/test_hexbinary_streambuf.cpp 1970-01-01 00:00:00 +0000 +++ src/unit_tests/test_hexbinary_streambuf.cpp 2013-06-20 00:55:33 +0000 @@ -0,0 +1,142 @@ +/* + * Copyright 2006-2008 The FLWOR Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "stdafx.h" +#include <fstream> +#include <iostream> +#include <sstream> + +#include <zorba/util/hexbinary_stream.h> + +using namespace std; +using namespace zorba; + +struct test { + char const *raw_str; + char const *hb_str; +}; + +/////////////////////////////////////////////////////////////////////////////// + +static int failures; + +static bool assert_true( int no, char const *expr, int line, bool result ) { + if ( !result ) { + cout << '#' << no << " FAILED, line " << line << ": " << expr << endl; + ++failures; + } + return result; +} + +static void print_exception( int no, char const *expr, int line, + std::exception const &e ) { + assert_true( no, expr, line, false ); + cout << "+ exception: " << e.what() << endl; +} + +#define ASSERT_TRUE( NO, EXPR ) assert_true( NO, #EXPR, __LINE__, !!(EXPR) ) + +#define ASSERT_TRUE_AND_NO_EXCEPTION( NO, EXPR ) \ + try { ASSERT_TRUE( NO, EXPR ); } \ + catch ( exception const &e ) { print_exception( NO, #EXPR, __LINE__, e ); } \ + catch ( ... ) { assert_true( NO, #EXPR, __LINE__, false ); } + +/////////////////////////////////////////////////////////////////////////////// + +static bool test_getline( test const *t ) { + string const hb_str( t->hb_str ); + istringstream iss( hb_str ); + hexbinary::streambuf hb_sbuf( iss.rdbuf() ); + iss.ios::rdbuf( &hb_sbuf ); + + char raw_buf[ 1024 ]; + iss.getline( raw_buf, sizeof raw_buf ); + if ( iss.gcount() ) { + string const raw_str( raw_buf ); + return raw_str == t->raw_str; + } + return false; +} + +static bool test_read( test const *t ) { + string const hb_str( t->hb_str ); + istringstream iss( hb_str ); + hexbinary::streambuf hb_sbuf( iss.rdbuf() ); + iss.ios::rdbuf( &hb_sbuf ); + + char raw_buf[ 1024 ]; + iss.read( raw_buf, sizeof raw_buf ); + if ( iss.gcount() ) { + string const raw_str( + raw_buf, static_cast<string::size_type>( iss.gcount() ) + ); + return raw_str == t->raw_str; + } + return false; +} + +static bool test_insertion( test const *t ) { + ostringstream oss; + hexbinary::streambuf hb_sbuf( oss.rdbuf() ); + oss.ios::rdbuf( &hb_sbuf ); + + oss << t->raw_str << flush; + string const hb_str( oss.str() ); + + string const expected_hb_str( t->hb_str ); + return hb_str == expected_hb_str; +} + +static bool test_put( test const *t ) { + ostringstream oss; + { // local scope + hexbinary::auto_attach<ostringstream> const raii( oss ); + + for ( char const *c = t->raw_str; *c; ++c ) + oss.put( *c ); + } // local scope + string const hb_str( oss.str() ); + + string const expected_hb_str( t->hb_str ); + return hb_str == expected_hb_str; +} + +/////////////////////////////////////////////////////////////////////////////// + +static test const tests[] = { + /* 0 */ { "Now", "4E6F77" }, + /* 1 */ { "Now is the time", "4E6F77206973207468652074696D65" }, + { 0, 0 } +}; + +namespace zorba { +namespace UnitTests { + +int test_hexbinary_streambuf( int, char*[] ) { + int test_no = 0; + for ( test const *t = tests; t->raw_str; ++t, ++test_no ) { + ASSERT_TRUE_AND_NO_EXCEPTION( test_no, test_getline( t ) ); + ASSERT_TRUE_AND_NO_EXCEPTION( test_no, test_read( t ) ); + ASSERT_TRUE_AND_NO_EXCEPTION( test_no, test_insertion( t ) ); + ASSERT_TRUE_AND_NO_EXCEPTION( test_no, test_put( t ) ); + } + cout << failures << " test(s) failed\n"; + return failures ? 1 : 0; +} + +} // namespace UnitTests +} // namespace zorba +/* vim:set et sw=2 ts=2: */ === modified file 'src/unit_tests/unit_test_list.h' --- src/unit_tests/unit_test_list.h 2013-05-31 03:38:45 +0000 +++ src/unit_tests/unit_test_list.h 2013-06-20 00:55:33 +0000 @@ -34,6 +34,7 @@ int test_fs_util( int, char*[] ); int test_hashmaps( int argc, char* argv[] ); int test_hexbinary( int argc, char* argv[] ); + int test_hexbinary_streambuf( int argc, char* argv[] ); #ifndef ZORBA_NO_ICU int test_icu_streambuf( int, char*[] ); === modified file 'src/unit_tests/unit_tests.cpp' --- src/unit_tests/unit_tests.cpp 2013-06-12 13:19:13 +0000 +++ src/unit_tests/unit_tests.cpp 2013-06-20 00:55:33 +0000 @@ -45,6 +45,7 @@ libunittests["fs_util"] = test_fs_util; libunittests["hashmaps"] = test_hashmaps; libunittests["hexbinary"] = test_hexbinary; + libunittests["hexbinary_streambuf"] = test_hexbinary_streambuf; #ifndef ZORBA_NO_ICU libunittests["icu_streambuf"] = test_icu_streambuf;
-- Mailing list: https://launchpad.net/~zorba-coders Post to : zorba-coders@lists.launchpad.net Unsubscribe : https://launchpad.net/~zorba-coders More help : https://help.launchpad.net/ListHelp