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 <cstdio> // EOF. |
9 | #include <boost/iostreams/filtering_stream.hpp> |
10 | #include <boost/iostreams/stream.hpp> |
11 | #include <boost/shared_ptr.hpp> |
12 | #include <boost/test/test_tools.hpp> |
13 | #include <boost/test/unit_test.hpp> |
14 | #include "detail/temp_file.hpp" |
15 | #include "detail/verification.hpp" |
16 | |
17 | using namespace std; |
18 | using namespace boost; |
19 | using namespace boost::iostreams; |
20 | using namespace boost::iostreams::test; |
21 | using boost::unit_test::test_suite; |
22 | |
23 | class closable_source : public source { |
24 | public: |
25 | closable_source() : open_(new bool(true)) { } |
26 | std::streamsize read(char*, std::streamsize) { return 0; } |
27 | void open() { *open_ = true; } |
28 | void close() { *open_ = false; } |
29 | bool is_open() const { return *open_; } |
30 | private: |
31 | boost::shared_ptr<bool> open_; |
32 | }; |
33 | |
34 | class closable_input_filter : public input_filter { |
35 | public: |
36 | closable_input_filter() : open_(new bool(true)) { } |
37 | |
38 | template<typename Source> |
39 | int get(Source&) { return EOF; } |
40 | |
41 | void open() { *open_ = true; } |
42 | |
43 | template<typename Source> |
44 | void close(Source&) { *open_ = false; } |
45 | |
46 | bool is_open() const { return *open_; } |
47 | private: |
48 | boost::shared_ptr<bool> open_; |
49 | }; |
50 | |
51 | void auto_close_source() |
52 | { |
53 | // Rely on auto_close to close source. |
54 | closable_source src; |
55 | { |
56 | stream<closable_source> in(src); |
57 | BOOST_CHECK(src.is_open()); |
58 | BOOST_CHECK(in.auto_close()); |
59 | } |
60 | BOOST_CHECK(!src.is_open()); |
61 | |
62 | // Use close() to close components. |
63 | src.open(); |
64 | { |
65 | stream<closable_source> in(src); |
66 | BOOST_CHECK(src.is_open()); |
67 | BOOST_CHECK(in.auto_close()); |
68 | in.close(); |
69 | BOOST_CHECK(!src.is_open()); |
70 | } |
71 | |
72 | // Use close() to close components, with auto_close disabled. |
73 | src.open(); |
74 | { |
75 | stream<closable_source> in(src); |
76 | BOOST_CHECK(src.is_open()); |
77 | in.set_auto_close(false); |
78 | in.close(); |
79 | BOOST_CHECK(!src.is_open()); |
80 | } |
81 | |
82 | // Disable auto_close. |
83 | src.open(); |
84 | { |
85 | stream<closable_source> in(src); |
86 | BOOST_CHECK(src.is_open()); |
87 | in.set_auto_close(false); |
88 | BOOST_CHECK(!in.auto_close()); |
89 | } |
90 | BOOST_CHECK(src.is_open()); |
91 | } |
92 | |
93 | void auto_close_filter() |
94 | { |
95 | closable_source src; |
96 | closable_input_filter flt; |
97 | |
98 | // Rely on auto_close to close components. |
99 | { |
100 | filtering_istream in; |
101 | in.push(t: flt); |
102 | in.push(t: src); |
103 | BOOST_CHECK(flt.is_open()); |
104 | BOOST_CHECK(src.is_open()); |
105 | BOOST_CHECK(in.auto_close()); |
106 | } |
107 | BOOST_CHECK(!flt.is_open()); |
108 | BOOST_CHECK(!src.is_open()); |
109 | |
110 | // Use reset() to close components. |
111 | flt.open(); |
112 | src.open(); |
113 | { |
114 | filtering_istream in; |
115 | in.push(t: flt); |
116 | in.push(t: src); |
117 | BOOST_CHECK(flt.is_open()); |
118 | BOOST_CHECK(src.is_open()); |
119 | BOOST_CHECK(in.auto_close()); |
120 | in.reset(); |
121 | BOOST_CHECK(!flt.is_open()); |
122 | BOOST_CHECK(!src.is_open()); |
123 | } |
124 | |
125 | // Use reset() to close components, with auto_close disabled. |
126 | flt.open(); |
127 | src.open(); |
128 | { |
129 | filtering_istream in; |
130 | in.push(t: flt); |
131 | in.push(t: src); |
132 | BOOST_CHECK(flt.is_open()); |
133 | BOOST_CHECK(src.is_open()); |
134 | in.set_auto_close(false); |
135 | in.reset(); |
136 | BOOST_CHECK(!flt.is_open()); |
137 | BOOST_CHECK(!src.is_open()); |
138 | } |
139 | |
140 | // Disable auto_close. |
141 | flt.open(); |
142 | src.open(); |
143 | { |
144 | filtering_istream in; |
145 | in.push(t: flt); |
146 | in.push(t: src); |
147 | BOOST_CHECK(flt.is_open()); |
148 | BOOST_CHECK(src.is_open()); |
149 | in.set_auto_close(false); |
150 | BOOST_CHECK(!in.auto_close()); |
151 | in.pop(); |
152 | BOOST_CHECK(flt.is_open()); |
153 | BOOST_CHECK(src.is_open()); |
154 | } |
155 | BOOST_CHECK(!flt.is_open()); |
156 | BOOST_CHECK(src.is_open()); |
157 | |
158 | // Disable auto_close; disconnect and reconnect resource. |
159 | flt.open(); |
160 | src.open(); |
161 | { |
162 | filtering_istream in; |
163 | in.push(t: flt); |
164 | in.push(t: src); |
165 | BOOST_CHECK(flt.is_open()); |
166 | BOOST_CHECK(src.is_open()); |
167 | in.set_auto_close(false); |
168 | BOOST_CHECK(!in.auto_close()); |
169 | in.pop(); |
170 | BOOST_CHECK(flt.is_open()); |
171 | BOOST_CHECK(src.is_open()); |
172 | in.push(t: src); |
173 | } |
174 | BOOST_CHECK(!flt.is_open()); |
175 | BOOST_CHECK(!src.is_open()); |
176 | } |
177 | |
178 | test_suite* init_unit_test_suite(int, char* []) |
179 | { |
180 | test_suite* test = BOOST_TEST_SUITE("auto_close test"); |
181 | test->add(BOOST_TEST_CASE(&auto_close_source)); |
182 | test->add(BOOST_TEST_CASE(&auto_close_filter)); |
183 | return test; |
184 | } |
185 |