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
17using namespace std;
18using namespace boost;
19using namespace boost::iostreams;
20using namespace boost::iostreams::test;
21using boost::unit_test::test_suite;
22
23class closable_source : public source {
24public:
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_; }
30private:
31 boost::shared_ptr<bool> open_;
32};
33
34class closable_input_filter : public input_filter {
35public:
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_; }
47private:
48 boost::shared_ptr<bool> open_;
49};
50
51void 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
93void 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
178test_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

source code of boost/libs/iostreams/test/auto_close_test.cpp