1 /* 2 * Distributed under the Boost Software License, Version 1.0.(See accompanying 3 * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.) 4 * 5 * See http://www.boost.org/libs/iostreams for documentation. 6 * 7 * Defines a large collection of closable filters and devices that 8 * execute instances of boost::iostreams::test::operation upon 9 * closre(). Used to verify that filters and devices are closed 10 * correctly by the iostreams library 11 * 12 * File: libs/iostreams/test/detail/closable.hpp 13 * Date: Sun Dec 09 16:12:23 MST 2007 14 * Copyright: 2007-2008 CodeRage, LLC 15 * Author: Jonathan Turkanis 16 * Contact: turkanis at coderage dot com 17 */ 18 19 #ifndef BOOST_IOSTREAMS_TEST_CLOSABLE_HPP_INCLUDED 20 #define BOOST_IOSTREAMS_TEST_CLOSABLE_HPP_INCLUDED 21 22 #include <boost/iostreams/categories.hpp> 23 #include <boost/iostreams/char_traits.hpp> // EOF 24 #include <boost/iostreams/concepts.hpp> 25 #include <boost/iostreams/detail/ios.hpp> 26 #include "./operation_sequence.hpp" 27 28 namespace boost { namespace iostreams { namespace test { 29 30 template<typename Category> 31 class closable_device { }; 32 33 // Source 34 template<> 35 class closable_device<input> : public source { 36 public: closable_device(operation close)37 closable_device(operation close) : close_(close) { } read(char *,std::streamsize)38 std::streamsize read(char*, std::streamsize) { return -1; } close()39 void close() { close_.execute(); } 40 private: 41 operation close_; 42 }; 43 44 // Sink 45 template<> 46 class closable_device<output> : public sink { 47 public: closable_device(operation close)48 closable_device(operation close) : close_(close) { } write(const char *,std::streamsize)49 std::streamsize write(const char*, std::streamsize) { return 0; } close()50 void close() { close_.execute(); } 51 private: 52 operation close_; 53 }; 54 55 struct borland_output { }; 56 57 // Copy of closable_device<output>, for Borland <= 5.8.2 58 template<> 59 class closable_device<borland_output> : public sink { 60 public: closable_device(operation close)61 closable_device(operation close) : close_(close) { } write(const char *,std::streamsize)62 std::streamsize write(const char*, std::streamsize) { return 0; } close()63 void close() { close_.execute(); } 64 private: 65 operation close_; 66 }; 67 68 // Bidirectional device 69 template<> 70 class closable_device<bidirectional> : public device<bidirectional> { 71 public: closable_device(operation close_input,operation close_output)72 closable_device(operation close_input, operation close_output) 73 : close_input_(close_input), close_output_(close_output) 74 { } read(char *,std::streamsize)75 std::streamsize read(char*, std::streamsize) { return -1; } write(const char *,std::streamsize)76 std::streamsize write(const char*, std::streamsize) { return 0; } close(BOOST_IOS::openmode which)77 void close(BOOST_IOS::openmode which) 78 { 79 switch (which) { 80 case BOOST_IOS::in: 81 close_input_.execute(); 82 break; 83 case BOOST_IOS::out: 84 close_output_.execute(); 85 break; 86 default: 87 break; 88 } 89 } 90 private: 91 operation close_input_; 92 operation close_output_; 93 }; 94 95 // Seekable device 96 template<> 97 class closable_device<seekable> : public device<seekable> { 98 public: closable_device(operation close)99 closable_device(operation close) : close_(close) { } read(char *,std::streamsize)100 std::streamsize read(char*, std::streamsize) { return -1; } write(const char *,std::streamsize)101 std::streamsize write(const char*, std::streamsize) { return 0; } seek(stream_offset,BOOST_IOS::seekdir)102 stream_offset seek(stream_offset, BOOST_IOS::seekdir) { return 0; } close()103 void close() { close_.execute(); } 104 private: 105 operation close_; 106 }; 107 108 struct direct_input 109 : input, device_tag, closable_tag, direct_tag 110 { }; 111 struct direct_output 112 : output, device_tag, closable_tag, direct_tag 113 { }; 114 struct direct_bidirectional 115 : bidirectional, device_tag, closable_tag, direct_tag 116 { }; 117 struct direct_seekable 118 : seekable, device_tag, closable_tag, direct_tag 119 { }; 120 121 // Direct source 122 template<> 123 class closable_device<direct_input> { 124 public: 125 typedef char char_type; 126 typedef direct_input category; closable_device(operation close)127 closable_device(operation close) : close_(close) { } input_sequence()128 std::pair<char*, char*> input_sequence() 129 { return std::pair<char*, char*>(static_cast<char*>(0), static_cast<char*>(0)); } close()130 void close() { close_.execute(); } 131 private: 132 operation close_; 133 }; 134 135 // Direct sink 136 template<> 137 class closable_device<direct_output> { 138 public: 139 typedef char char_type; 140 typedef direct_output category; closable_device(operation close)141 closable_device(operation close) : close_(close) { } output_sequence()142 std::pair<char*, char*> output_sequence() 143 { return std::pair<char*, char*>(static_cast<char*>(0), static_cast<char*>(0)); } close()144 void close() { close_.execute(); } 145 private: 146 operation close_; 147 }; 148 149 // Direct bidirectional device 150 template<> 151 class closable_device<direct_bidirectional> { 152 public: 153 typedef char char_type; 154 typedef direct_bidirectional category; closable_device(operation close_input,operation close_output)155 closable_device(operation close_input, operation close_output) 156 : close_input_(close_input), close_output_(close_output) 157 { } input_sequence()158 std::pair<char*, char*> input_sequence() 159 { return std::pair<char*, char*>(static_cast<char*>(0), static_cast<char*>(0)); } output_sequence()160 std::pair<char*, char*> output_sequence() 161 { return std::pair<char*, char*>(static_cast<char*>(0), static_cast<char*>(0)); } close(BOOST_IOS::openmode which)162 void close(BOOST_IOS::openmode which) 163 { 164 switch (which) { 165 case BOOST_IOS::in: 166 close_input_.execute(); 167 break; 168 case BOOST_IOS::out: 169 close_output_.execute(); 170 break; 171 default: 172 break; 173 } 174 } 175 private: 176 operation close_input_; 177 operation close_output_; 178 }; 179 180 // Direct seekable device 181 template<> 182 class closable_device<direct_seekable> { 183 public: 184 typedef char char_type; 185 typedef direct_seekable category; closable_device(operation close)186 closable_device(operation close) : close_(close) { } input_sequence()187 std::pair<char*, char*> input_sequence() 188 { return std::pair<char*, char*>(static_cast<char*>(0), static_cast<char*>(0)); } output_sequence()189 std::pair<char*, char*> output_sequence() 190 { return std::pair<char*, char*>(static_cast<char*>(0), static_cast<char*>(0)); } close()191 void close() { close_.execute(); } 192 private: 193 operation close_; 194 }; 195 196 template<typename Mode> 197 class closable_filter { }; 198 199 // Input filter 200 template<> 201 class closable_filter<input> : public input_filter { 202 public: closable_filter(operation close)203 closable_filter(operation close) : close_(close) { } 204 205 template<typename Source> get(Source &)206 int get(Source&) { return EOF; } 207 208 template<typename Source> close(Source &)209 void close(Source&) { close_.execute(); } 210 private: 211 operation close_; 212 }; 213 214 // Output filter 215 template<> 216 class closable_filter<output> : public output_filter { 217 public: closable_filter(operation close)218 closable_filter(operation close) : close_(close) { } 219 220 template<typename Sink> put(Sink &,char)221 bool put(Sink&, char) { return true; } 222 223 template<typename Sink> close(Sink &)224 void close(Sink&) { close_.execute(); } 225 private: 226 operation close_; 227 }; 228 229 // Bidirectional filter 230 template<> 231 class closable_filter<bidirectional> : public filter<bidirectional> { 232 public: closable_filter(operation close_input,operation close_output)233 closable_filter(operation close_input, operation close_output) 234 : close_input_(close_input), close_output_(close_output) 235 { } 236 237 template<typename Source> get(Source &)238 int get(Source&) { return EOF; } 239 240 template<typename Sink> put(Sink &,char)241 bool put(Sink&, char) { return true; } 242 243 template<typename Device> close(Device &,BOOST_IOS::openmode which)244 void close(Device&, BOOST_IOS::openmode which) 245 { 246 switch (which) { 247 case BOOST_IOS::in: 248 close_input_.execute(); 249 break; 250 case BOOST_IOS::out: 251 close_output_.execute(); 252 break; 253 default: 254 break; 255 } 256 } 257 private: 258 operation close_input_; 259 operation close_output_; 260 }; 261 262 // Seekable filter 263 template<> 264 class closable_filter<seekable> : public filter<seekable> { 265 public: closable_filter(operation close)266 closable_filter(operation close) : close_(close) { } read(char *,std::streamsize)267 std::streamsize read(char*, std::streamsize) { return -1; } 268 269 template<typename Source> get(Source &)270 int get(Source&) { return EOF; } 271 272 template<typename Sink> put(Sink &,char)273 bool put(Sink&, char) { return true; } 274 275 template<typename Device> seek(Device &,stream_offset,BOOST_IOS::seekdir)276 stream_offset seek(Device&, stream_offset, BOOST_IOS::seekdir) 277 { 278 return 0; 279 } 280 281 template<typename Device> close(Device &)282 void close(Device&) { close_.execute(); } 283 private: 284 operation close_; 285 }; 286 287 // Dual-use filter 288 template<> 289 class closable_filter<dual_use> { 290 public: 291 typedef char char_type; 292 struct category 293 : filter_tag, 294 dual_use, 295 closable_tag 296 { }; closable_filter(operation close_input,operation close_output)297 closable_filter(operation close_input, operation close_output) 298 : close_input_(close_input), close_output_(close_output) 299 { } 300 301 template<typename Source> get(Source &)302 int get(Source&) { return EOF; } 303 304 template<typename Sink> put(Sink &,char)305 bool put(Sink&, char) { return true; } 306 307 template<typename Device> close(Device &,BOOST_IOS::openmode which)308 void close(Device&, BOOST_IOS::openmode which) 309 { 310 switch (which) { 311 case BOOST_IOS::in: 312 close_input_.execute(); 313 break; 314 case BOOST_IOS::out: 315 close_output_.execute(); 316 break; 317 default: 318 break; 319 } 320 } 321 private: 322 operation close_input_; 323 operation close_output_; 324 }; 325 326 // Symmetric filter 327 class closable_symmetric_filter { 328 public: 329 typedef char char_type; closable_symmetric_filter(operation close)330 closable_symmetric_filter(operation close) : close_(close) { } filter(const char * &,const char *,char * &,char *,bool)331 bool filter( const char*&, const char*, 332 char*&, char*, bool ) 333 { 334 return false; 335 } close()336 void close() { close_.execute(); } 337 private: 338 operation close_; 339 }; 340 341 } } } // End namespaces test, iostreams, boost. 342 343 #endif // #ifndef BOOST_IOSTREAMS_TEST_CLOSABLE_HPP_INCLUDED 344