1 // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
2 // (C) Copyright 2004-2007 Jonathan Turkanis
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
6 // See http://www.boost.org/libs/iostreams for documentation.
8 #include <boost/iostreams/detail/buffer.hpp>
9 #include <boost/iostreams/device/file.hpp>
10 #include <boost/iostreams/filter/symmetric.hpp>
11 #include <boost/iostreams/filter/test.hpp>
12 #include <boost/test/test_tools.hpp>
13 #include <boost/test/unit_test.hpp>
14 #include "detail/closable.hpp"
15 #include "./detail/constants.hpp"
16 #include "detail/operation_sequence.hpp"
17 #include "./detail/temp_file.hpp"
18 #include "./detail/verification.hpp"
21 #include <boost/iostreams/detail/config/disable_warnings.hpp>
23 using namespace boost::iostreams
;
24 using namespace boost::iostreams::test
;
25 using boost::unit_test::test_suite
;
26 namespace io
= boost::iostreams
;
28 // Note: The filter is given an internal buffer -- unnecessary in this simple
29 // case -- to stress test symmetric_filter.
30 struct toupper_symmetric_filter_impl
{
31 typedef char char_type
;
32 explicit toupper_symmetric_filter_impl(
33 std::streamsize buffer_size
=
34 default_filter_buffer_size
40 bool filter( const char*& src_begin
, const char* src_end
,
41 char*& dest_begin
, char* dest_end
, bool /* flush */ )
43 while ( can_read(src_begin
, src_end
) ||
44 can_write(dest_begin
, dest_end
) )
46 if (can_read(src_begin
, src_end
))
47 read(src_begin
, src_end
);
48 if (can_write(dest_begin
, dest_end
))
49 write(dest_begin
, dest_end
);
51 bool result
= buf_
.ptr() != buf_
.eptr();
54 void close() { buf_
.set(0, 0); }
55 void read(const char*& src_begin
, const char* src_end
)
57 std::ptrdiff_t count
=
58 (std::min
) ( src_end
- src_begin
,
59 static_cast<std::ptrdiff_t>(buf_
.size()) -
60 (buf_
.eptr() - buf_
.data()) );
62 *buf_
.eptr()++ = std::toupper(*src_begin
++);
64 void write(char*& dest_begin
, char* dest_end
)
66 std::ptrdiff_t count
=
67 (std::min
) ( dest_end
- dest_begin
,
68 buf_
.eptr() - buf_
.ptr() );
70 *dest_begin
++ = *buf_
.ptr()++;
71 if (buf_
.ptr() == buf_
.eptr())
74 bool can_read(const char*& src_begin
, const char* src_end
)
75 { return src_begin
!= src_end
&& buf_
.eptr() != buf_
.end(); }
76 bool can_write(char*& dest_begin
, char* dest_end
)
77 { return dest_begin
!= dest_end
&& buf_
.ptr() != buf_
.eptr(); }
78 boost::iostreams::detail::buffer
<char> buf_
;
81 typedef symmetric_filter
<toupper_symmetric_filter_impl
>
82 toupper_symmetric_filter
;
84 void read_symmetric_filter()
89 test_input_filter( toupper_symmetric_filter(default_filter_buffer_size
),
90 file_source(test
.name(), in_mode
),
91 file_source(upper
.name(), in_mode
) )
95 void write_symmetric_filter()
100 test_output_filter( toupper_symmetric_filter(default_filter_buffer_size
),
101 file_source(test
.name(), in_mode
),
102 file_source(upper
.name(), in_mode
) )
106 void close_symmetric_filter()
110 operation_sequence seq
;
113 io::symmetric_filter
<closable_symmetric_filter
>
114 (1, seq
.new_operation(2))
116 ch
.push(closable_device
<input
>(seq
.new_operation(1)));
117 BOOST_CHECK_NO_THROW(ch
.reset());
118 BOOST_CHECK_OPERATION_SEQUENCE(seq
);
123 operation_sequence seq
;
126 io::symmetric_filter
<closable_symmetric_filter
>
127 (1, seq
.new_operation(1))
129 ch
.push(closable_device
<output
>(seq
.new_operation(2)));
130 BOOST_CHECK_NO_THROW(ch
.reset());
131 BOOST_CHECK_OPERATION_SEQUENCE(seq
);
135 #ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS
137 struct wcopy_filter_impl
{
138 typedef wchar_t char_type
;
139 bool filter( const wchar_t*& src_begin
, const wchar_t* src_end
,
140 wchar_t*& dest_begin
, wchar_t* dest_end
, bool /* flush */ )
142 if(src_begin
!= src_end
&& dest_begin
!= dest_end
) {
143 *dest_begin
++ = *src_begin
++;
150 typedef symmetric_filter
<wcopy_filter_impl
> wcopy_filter
;
152 void wide_symmetric_filter()
155 warray_source
src(wide_data(), wide_data() + data_length());
157 io::copy(src
, io::compose(wcopy_filter(16), io::back_inserter(dest
)));
158 BOOST_CHECK(dest
== wide_data());
161 warray_source
src(wide_data(), wide_data() + data_length());
163 io::copy(io::compose(wcopy_filter(16), src
), io::back_inserter(dest
));
164 BOOST_CHECK(dest
== wide_data());
170 test_suite
* init_unit_test_suite(int, char* [])
172 test_suite
* test
= BOOST_TEST_SUITE("symmetric_filter test");
173 test
->add(BOOST_TEST_CASE(&read_symmetric_filter
));
174 test
->add(BOOST_TEST_CASE(&write_symmetric_filter
));
175 test
->add(BOOST_TEST_CASE(&close_symmetric_filter
));
176 #ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS
177 test
->add(BOOST_TEST_CASE(&wide_symmetric_filter
));
182 #include <boost/iostreams/detail/config/enable_warnings.hpp>