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: closable_source()25 closable_source() : open_(new bool(true)) { } read(char *,std::streamsize)26 std::streamsize read(char*, std::streamsize) { return 0; } open()27 void open() { *open_ = true; } close()28 void close() { *open_ = false; } is_open() const29 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: closable_input_filter()36 closable_input_filter() : open_(new bool(true)) { } 37 38 template<typename Source> get(Source &)39 int get(Source&) { return EOF; } 40 open()41 void open() { *open_ = true; } 42 43 template<typename Source> close(Source &)44 void close(Source&) { *open_ = false; } 45 is_open() const46 bool is_open() const { return *open_; } 47 private: 48 boost::shared_ptr<bool> open_; 49 }; 50 auto_close_source()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 auto_close_filter()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(flt); 102 in.push(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(flt); 116 in.push(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(flt); 131 in.push(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(flt); 146 in.push(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(flt); 164 in.push(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(src); 173 } 174 BOOST_CHECK(!flt.is_open()); 175 BOOST_CHECK(!src.is_open()); 176 } 177 init_unit_test_suite(int,char * [])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