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.) |
5 | |
6 | // See http://www.boost.org/libs/iostreams for documentation. |
7 | |
8 | #include <cctype> |
9 | #include <boost/iostreams/device/file.hpp> |
10 | #include <boost/iostreams/filter/stdio.hpp> |
11 | #include <boost/iostreams/filtering_stream.hpp> |
12 | #include <boost/test/test_tools.hpp> |
13 | #include <boost/test/unit_test.hpp> |
14 | #include "detail/filters.hpp" |
15 | #include "detail/temp_file.hpp" |
16 | #include "detail/verification.hpp" |
17 | |
18 | // Must come last. |
19 | #include <boost/iostreams/detail/config/disable_warnings.hpp> // BCC 5.x. |
20 | |
21 | using namespace boost::iostreams; |
22 | using boost::unit_test::test_suite; |
23 | |
24 | struct toupper_stdio_filter : stdio_filter { |
25 | void do_filter() |
26 | { |
27 | int c; |
28 | while ((c = std::cin.get()) != EOF) |
29 | std::cout.put(c: std::toupper(c: (unsigned char)c)); |
30 | } |
31 | }; |
32 | |
33 | struct tolower_stdio_filter : stdio_filter { |
34 | void do_filter() |
35 | { |
36 | int c; |
37 | while ((c = std::cin.get()) != EOF) |
38 | std::cout.put(c: std::tolower(c: (unsigned char)c)); |
39 | } |
40 | }; |
41 | |
42 | struct padding_stdio_filter : stdio_filter { |
43 | padding_stdio_filter(char pad_char) : pad_char_(pad_char) { } |
44 | void do_filter() |
45 | { |
46 | int c; |
47 | while ((c = std::cin.get()) != EOF) { |
48 | std::cout.put(c: c); |
49 | std::cout.put(c: pad_char_); |
50 | } |
51 | } |
52 | char pad_char_; |
53 | }; |
54 | |
55 | void read_stdio_filter() |
56 | { |
57 | using namespace boost::iostreams::test; |
58 | |
59 | test_file src1, src2; |
60 | filtering_istream first, second; |
61 | |
62 | first.push(t: toupper_filter()); |
63 | first.push(t: padding_filter('a')); |
64 | first.push(t: file_source(src1.name(), in_mode)); |
65 | second.push(t: toupper_stdio_filter()); |
66 | second.push(t: padding_stdio_filter('a')); |
67 | second.push(t: file_source(src2.name(), in_mode)); |
68 | BOOST_CHECK_MESSAGE( |
69 | compare_streams_in_chunks(first, second), |
70 | "failed reading from a stdio_filter" |
71 | ); |
72 | |
73 | first.reset(); |
74 | first.push(t: padding_filter('a')); |
75 | first.push(t: toupper_filter()); |
76 | first.push(t: file_source(src1.name(), in_mode)); |
77 | second.reset(); |
78 | second.push(t: padding_stdio_filter('a')); |
79 | second.push(t: toupper_stdio_filter()); |
80 | second.push(t: file_source(src2.name(), in_mode)); |
81 | BOOST_CHECK_MESSAGE( |
82 | compare_streams_in_chunks(first, second), |
83 | "failed reading from a stdio_filter" |
84 | ); |
85 | } |
86 | |
87 | void write_stdio_filter() |
88 | { |
89 | using namespace std; |
90 | using namespace boost::iostreams::test; |
91 | |
92 | temp_file dest1, dest2; |
93 | filtering_ostream out1, out2; |
94 | |
95 | out1.push(t: tolower_filter()); |
96 | out1.push(t: padding_filter('a')); |
97 | out1.push(t: file_sink(dest1.name(), in_mode)); |
98 | out2.push(t: tolower_stdio_filter()); |
99 | out2.push(t: padding_stdio_filter('a')); |
100 | out2.push(t: file_sink(dest2.name(), in_mode)); |
101 | write_data_in_chunks(os&: out1); |
102 | write_data_in_chunks(os&: out2); |
103 | out1.reset(); |
104 | out2.reset(); |
105 | |
106 | { |
107 | ifstream first(dest1.name().c_str()); |
108 | ifstream second(dest2.name().c_str()); |
109 | BOOST_CHECK_MESSAGE( |
110 | compare_streams_in_chunks(first, second), |
111 | "failed writing to a stdio_filter" |
112 | ); |
113 | } |
114 | |
115 | out1.push(t: padding_filter('a')); |
116 | out1.push(t: tolower_filter()); |
117 | out1.push(t: file_sink(dest1.name(), in_mode)); |
118 | out2.push(t: padding_stdio_filter('a')); |
119 | out2.push(t: tolower_stdio_filter()); |
120 | out2.push(t: file_sink(dest2.name(), in_mode)); |
121 | write_data_in_chunks(os&: out1); |
122 | write_data_in_chunks(os&: out2); |
123 | out1.reset(); |
124 | out2.reset(); |
125 | |
126 | { |
127 | ifstream first(dest1.name().c_str()); |
128 | ifstream second(dest2.name().c_str()); |
129 | BOOST_CHECK_MESSAGE( |
130 | compare_streams_in_chunks(first, second), |
131 | "failed writing to a stdio_filter" |
132 | ); |
133 | } |
134 | } |
135 | |
136 | test_suite* init_unit_test_suite(int, char* []) |
137 | { |
138 | test_suite* test = BOOST_TEST_SUITE("line_filter test" ); |
139 | test->add(BOOST_TEST_CASE(&read_stdio_filter)); |
140 | test->add(BOOST_TEST_CASE(&write_stdio_filter)); |
141 | return test; |
142 | } |
143 | |
144 | #include <boost/iostreams/detail/config/enable_warnings.hpp> // BCC 5.x. |
145 | |