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 <stdexcept> // out_of_range. |
9 | #include <typeinfo> |
10 | #include <utility> // pair. |
11 | #include <boost/config.hpp> // BOOST_MSVC. |
12 | #include <boost/detail/workaround.hpp> |
13 | #include <boost/iostreams/device/file.hpp> |
14 | #include <boost/iostreams/filtering_stream.hpp> |
15 | #include <boost/iostreams/stream.hpp> |
16 | #include <boost/iostreams/stream_buffer.hpp> |
17 | #include <boost/test/test_tools.hpp> |
18 | #include <boost/test/unit_test.hpp> |
19 | #include "detail/constants.hpp" |
20 | #include "detail/filters.hpp" |
21 | #include "detail/temp_file.hpp" |
22 | #include "detail/verification.hpp" |
23 | |
24 | namespace io = boost::iostreams; |
25 | using boost::unit_test::test_suite; |
26 | |
27 | #define COMPARE_TYPE_ID(x, y) BOOST_IOSTREAMS_COMPARE_TYPE_ID(x, y) |
28 | |
29 | struct indirect_source : io::source { |
30 | void foo() { } |
31 | std::streamsize read(char*, std::streamsize) { return 0; } |
32 | }; |
33 | |
34 | struct direct_source { |
35 | typedef char char_type; |
36 | struct category |
37 | : io::input, io::device_tag, io::direct_tag |
38 | { }; |
39 | void foo() { } |
40 | std::pair<char*, char*> input_sequence() |
41 | { |
42 | return std::pair<char*, char*>(static_cast<char*>(0), static_cast<char*>(0));; |
43 | } |
44 | }; |
45 | |
46 | void compile_time_test() |
47 | { |
48 | using namespace io; |
49 | |
50 | stream_buffer<indirect_source> indirect_buf; |
51 | indirect_buf.open(t: indirect_source()); |
52 | indirect_buf->foo(); |
53 | |
54 | stream_buffer<direct_source> direct_buf; |
55 | direct_buf.open(t: direct_source()); |
56 | direct_buf->foo(); |
57 | |
58 | stream<indirect_source> indirect_stream; |
59 | indirect_stream.open(t: indirect_source()); |
60 | indirect_stream->foo(); |
61 | |
62 | stream<direct_source> direct_stream; |
63 | direct_stream.open(t: direct_source()); |
64 | direct_stream->foo(); |
65 | } |
66 | |
67 | void component_type_test() |
68 | { |
69 | using namespace std; |
70 | using namespace io; |
71 | using namespace boost::iostreams::test; |
72 | |
73 | temp_file dest; |
74 | lowercase_file lower; |
75 | |
76 | filtering_ostream out; |
77 | out.push(t: tolower_filter()); |
78 | out.push(t: tolower_multichar_filter()); |
79 | out.push(t: file_sink(dest.name(), out_mode)); |
80 | |
81 | // Check index 0. |
82 | BOOST_CHECK(COMPARE_TYPE_ID( |
83 | out.component_type(0), |
84 | typeid(tolower_filter) |
85 | )); |
86 | BOOST_CHECK(COMPARE_TYPE_ID( |
87 | BOOST_IOSTREAMS_COMPONENT_TYPE(out, 0), |
88 | typeid(tolower_filter) |
89 | )); |
90 | BOOST_CHECK_NO_THROW(( |
91 | BOOST_IOSTREAMS_COMPONENT(out, 0, tolower_filter) |
92 | )); |
93 | #if !BOOST_WORKAROUND(BOOST_MSVC, < 1310) |
94 | BOOST_CHECK_NO_THROW(( |
95 | out.component<tolower_filter>(0) |
96 | )); |
97 | BOOST_CHECK_NO_THROW(( |
98 | out.component<0, tolower_filter>() |
99 | )); |
100 | #endif |
101 | |
102 | // Check index 1. |
103 | BOOST_CHECK(COMPARE_TYPE_ID( |
104 | out.component_type(1), |
105 | typeid(tolower_multichar_filter) |
106 | )); |
107 | BOOST_CHECK(COMPARE_TYPE_ID( |
108 | BOOST_IOSTREAMS_COMPONENT_TYPE(out, 1), |
109 | typeid(tolower_multichar_filter) |
110 | )); |
111 | BOOST_CHECK_NO_THROW(( |
112 | BOOST_IOSTREAMS_COMPONENT(out, 1, tolower_multichar_filter) |
113 | )); |
114 | #if !BOOST_WORKAROUND(BOOST_MSVC, < 1310) |
115 | BOOST_CHECK_NO_THROW(( |
116 | out.component<tolower_multichar_filter>(1) |
117 | )); |
118 | BOOST_CHECK_NO_THROW(( |
119 | out.component<1, tolower_multichar_filter>() |
120 | )); |
121 | #endif |
122 | |
123 | // Check index 2. |
124 | BOOST_CHECK(COMPARE_TYPE_ID( |
125 | out.component_type(2), |
126 | typeid(file_sink) |
127 | )); |
128 | BOOST_CHECK(COMPARE_TYPE_ID( |
129 | BOOST_IOSTREAMS_COMPONENT_TYPE(out, 2), |
130 | typeid(file_sink) |
131 | )); |
132 | BOOST_CHECK_NO_THROW(( |
133 | BOOST_IOSTREAMS_COMPONENT(out, 2, file_sink) |
134 | )); |
135 | #if !BOOST_WORKAROUND(BOOST_MSVC, < 1310) |
136 | BOOST_CHECK_NO_THROW(( |
137 | out.component<file_sink>(2) |
138 | )); |
139 | BOOST_CHECK_NO_THROW(( |
140 | out.component<2, file_sink>() |
141 | )); |
142 | #endif |
143 | |
144 | // Check index 3. |
145 | BOOST_CHECK_THROW( |
146 | out.component_type(3), |
147 | std::out_of_range |
148 | ); |
149 | BOOST_CHECK_THROW( |
150 | BOOST_IOSTREAMS_COMPONENT_TYPE(out, 3), |
151 | std::out_of_range |
152 | ); |
153 | |
154 | // Check components. |
155 | |
156 | filtering_ostream out2; |
157 | out2.push(t: *(BOOST_IOSTREAMS_COMPONENT(out, 0, tolower_filter))); |
158 | out2.push(t: *(BOOST_IOSTREAMS_COMPONENT(out, 1, tolower_multichar_filter))); |
159 | out2.push(t: *(BOOST_IOSTREAMS_COMPONENT(out, 2, file_sink))); |
160 | write_data_in_chunks(os&: out); |
161 | out.reset(); |
162 | BOOST_CHECK_MESSAGE( |
163 | compare_files(dest.name(), lower.name()), |
164 | "failed accessing components of chain" |
165 | ); |
166 | } |
167 | |
168 | test_suite* init_unit_test_suite(int, char* []) |
169 | { |
170 | test_suite* test = BOOST_TEST_SUITE("component_type test" ); |
171 | test->add(BOOST_TEST_CASE(&component_type_test)); |
172 | return test; |
173 | } |
174 | |