// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) // (C) Copyright 2004-2007 Jonathan Turkanis // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.) // See http://www.boost.org/libs/iostreams for documentation. #include #include #include #include #include #include #include "detail/closable.hpp" #include "./detail/constants.hpp" #include "detail/operation_sequence.hpp" #include "./detail/temp_file.hpp" #include "./detail/verification.hpp" // Must come last. #include using namespace boost::iostreams; using namespace boost::iostreams::test; using boost::unit_test::test_suite; namespace io = boost::iostreams; // Note: The filter is given an internal buffer -- unnecessary in this simple // case -- to stress test symmetric_filter. struct toupper_symmetric_filter_impl { typedef char char_type; explicit toupper_symmetric_filter_impl( std::streamsize buffer_size = default_filter_buffer_size ) : buf_(buffer_size) { buf_.set(0, 0); } bool filter( const char*& src_begin, const char* src_end, char*& dest_begin, char* dest_end, bool /* flush */ ) { while ( can_read(src_begin, src_end) || can_write(dest_begin, dest_end) ) { if (can_read(src_begin, src_end)) read(src_begin, src_end); if (can_write(dest_begin, dest_end)) write(dest_begin, dest_end); } bool result = buf_.ptr() != buf_.eptr(); return result; } void close() { buf_.set(0, 0); } void read(const char*& src_begin, const char* src_end) { std::ptrdiff_t count = (std::min) ( src_end - src_begin, static_cast(buf_.size()) - (buf_.eptr() - buf_.data()) ); while (count-- > 0) *buf_.eptr()++ = std::toupper(*src_begin++); } void write(char*& dest_begin, char* dest_end) { std::ptrdiff_t count = (std::min) ( dest_end - dest_begin, buf_.eptr() - buf_.ptr() ); while (count-- > 0) *dest_begin++ = *buf_.ptr()++; if (buf_.ptr() == buf_.eptr()) buf_.set(0, 0); } bool can_read(const char*& src_begin, const char* src_end) { return src_begin != src_end && buf_.eptr() != buf_.end(); } bool can_write(char*& dest_begin, char* dest_end) { return dest_begin != dest_end && buf_.ptr() != buf_.eptr(); } boost::iostreams::detail::buffer buf_; }; typedef symmetric_filter toupper_symmetric_filter; void read_symmetric_filter() { test_file test; uppercase_file upper; BOOST_CHECK( test_input_filter( toupper_symmetric_filter(default_filter_buffer_size), file_source(test.name(), in_mode), file_source(upper.name(), in_mode) ) ); } void write_symmetric_filter() { test_file test; uppercase_file upper; BOOST_CHECK( test_output_filter( toupper_symmetric_filter(default_filter_buffer_size), file_source(test.name(), in_mode), file_source(upper.name(), in_mode) ) ); } void close_symmetric_filter() { // Test input { operation_sequence seq; chain ch; ch.push( io::symmetric_filter (1, seq.new_operation(2)) ); ch.push(closable_device(seq.new_operation(1))); BOOST_CHECK_NO_THROW(ch.reset()); BOOST_CHECK_OPERATION_SEQUENCE(seq); } // Test output { operation_sequence seq; chain ch; ch.push( io::symmetric_filter (1, seq.new_operation(1)) ); ch.push(closable_device(seq.new_operation(2))); BOOST_CHECK_NO_THROW(ch.reset()); BOOST_CHECK_OPERATION_SEQUENCE(seq); } } #ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS struct wcopy_filter_impl { typedef wchar_t char_type; bool filter( const wchar_t*& src_begin, const wchar_t* src_end, wchar_t*& dest_begin, wchar_t* dest_end, bool /* flush */ ) { if(src_begin != src_end && dest_begin != dest_end) { *dest_begin++ = *src_begin++; } return false; } void close() {} }; typedef symmetric_filter wcopy_filter; void wide_symmetric_filter() { { warray_source src(wide_data(), wide_data() + data_length()); std::wstring dest; io::copy(src, io::compose(wcopy_filter(16), io::back_inserter(dest))); BOOST_CHECK(dest == wide_data()); } { warray_source src(wide_data(), wide_data() + data_length()); std::wstring dest; io::copy(io::compose(wcopy_filter(16), src), io::back_inserter(dest)); BOOST_CHECK(dest == wide_data()); } } #endif test_suite* init_unit_test_suite(int, char* []) { test_suite* test = BOOST_TEST_SUITE("symmetric_filter test"); test->add(BOOST_TEST_CASE(&read_symmetric_filter)); test->add(BOOST_TEST_CASE(&write_symmetric_filter)); test->add(BOOST_TEST_CASE(&close_symmetric_filter)); #ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS test->add(BOOST_TEST_CASE(&wide_symmetric_filter)); #endif return test; } #include