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.)
5 * See http://www.boost.org/libs/iostreams for documentation.
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
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
19 #ifndef BOOST_IOSTREAMS_TEST_CLOSABLE_HPP_INCLUDED
20 #define BOOST_IOSTREAMS_TEST_CLOSABLE_HPP_INCLUDED
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"
28 namespace boost { namespace iostreams { namespace test {
30 template<typename Category>
31 class closable_device { };
35 class closable_device<input> : public source {
37 closable_device(operation close) : close_(close) { }
38 std::streamsize read(char*, std::streamsize) { return -1; }
39 void close() { close_.execute(); }
46 class closable_device<output> : public sink {
48 closable_device(operation close) : close_(close) { }
49 std::streamsize write(const char*, std::streamsize) { return 0; }
50 void close() { close_.execute(); }
55 struct borland_output { };
57 // Copy of closable_device<output>, for Borland <= 5.8.2
59 class closable_device<borland_output> : public sink {
61 closable_device(operation close) : close_(close) { }
62 std::streamsize write(const char*, std::streamsize) { return 0; }
63 void close() { close_.execute(); }
68 // Bidirectional device
70 class closable_device<bidirectional> : public device<bidirectional> {
72 closable_device(operation close_input, operation close_output)
73 : close_input_(close_input), close_output_(close_output)
75 std::streamsize read(char*, std::streamsize) { return -1; }
76 std::streamsize write(const char*, std::streamsize) { return 0; }
77 void close(BOOST_IOS::openmode which)
81 close_input_.execute();
84 close_output_.execute();
91 operation close_input_;
92 operation close_output_;
97 class closable_device<seekable> : public device<seekable> {
99 closable_device(operation close) : close_(close) { }
100 std::streamsize read(char*, std::streamsize) { return -1; }
101 std::streamsize write(const char*, std::streamsize) { return 0; }
102 stream_offset seek(stream_offset, BOOST_IOS::seekdir) { return 0; }
103 void close() { close_.execute(); }
109 : input, device_tag, closable_tag, direct_tag
112 : output, device_tag, closable_tag, direct_tag
114 struct direct_bidirectional
115 : bidirectional, device_tag, closable_tag, direct_tag
117 struct direct_seekable
118 : seekable, device_tag, closable_tag, direct_tag
123 class closable_device<direct_input> {
125 typedef char char_type;
126 typedef direct_input category;
127 closable_device(operation close) : close_(close) { }
128 std::pair<char*, char*> input_sequence()
129 { return std::pair<char*, char*>(static_cast<char*>(0), static_cast<char*>(0)); }
130 void close() { close_.execute(); }
137 class closable_device<direct_output> {
139 typedef char char_type;
140 typedef direct_output category;
141 closable_device(operation close) : close_(close) { }
142 std::pair<char*, char*> output_sequence()
143 { return std::pair<char*, char*>(static_cast<char*>(0), static_cast<char*>(0)); }
144 void close() { close_.execute(); }
149 // Direct bidirectional device
151 class closable_device<direct_bidirectional> {
153 typedef char char_type;
154 typedef direct_bidirectional category;
155 closable_device(operation close_input, operation close_output)
156 : close_input_(close_input), close_output_(close_output)
158 std::pair<char*, char*> input_sequence()
159 { return std::pair<char*, char*>(static_cast<char*>(0), static_cast<char*>(0)); }
160 std::pair<char*, char*> output_sequence()
161 { return std::pair<char*, char*>(static_cast<char*>(0), static_cast<char*>(0)); }
162 void close(BOOST_IOS::openmode which)
166 close_input_.execute();
169 close_output_.execute();
176 operation close_input_;
177 operation close_output_;
180 // Direct seekable device
182 class closable_device<direct_seekable> {
184 typedef char char_type;
185 typedef direct_seekable category;
186 closable_device(operation close) : close_(close) { }
187 std::pair<char*, char*> input_sequence()
188 { return std::pair<char*, char*>(static_cast<char*>(0), static_cast<char*>(0)); }
189 std::pair<char*, char*> output_sequence()
190 { return std::pair<char*, char*>(static_cast<char*>(0), static_cast<char*>(0)); }
191 void close() { close_.execute(); }
196 template<typename Mode>
197 class closable_filter { };
201 class closable_filter<input> : public input_filter {
203 closable_filter(operation close) : close_(close) { }
205 template<typename Source>
206 int get(Source&) { return EOF; }
208 template<typename Source>
209 void close(Source&) { close_.execute(); }
216 class closable_filter<output> : public output_filter {
218 closable_filter(operation close) : close_(close) { }
220 template<typename Sink>
221 bool put(Sink&, char) { return true; }
223 template<typename Sink>
224 void close(Sink&) { close_.execute(); }
229 // Bidirectional filter
231 class closable_filter<bidirectional> : public filter<bidirectional> {
233 closable_filter(operation close_input, operation close_output)
234 : close_input_(close_input), close_output_(close_output)
237 template<typename Source>
238 int get(Source&) { return EOF; }
240 template<typename Sink>
241 bool put(Sink&, char) { return true; }
243 template<typename Device>
244 void close(Device&, BOOST_IOS::openmode which)
248 close_input_.execute();
251 close_output_.execute();
258 operation close_input_;
259 operation close_output_;
264 class closable_filter<seekable> : public filter<seekable> {
266 closable_filter(operation close) : close_(close) { }
267 std::streamsize read(char*, std::streamsize) { return -1; }
269 template<typename Source>
270 int get(Source&) { return EOF; }
272 template<typename Sink>
273 bool put(Sink&, char) { return true; }
275 template<typename Device>
276 stream_offset seek(Device&, stream_offset, BOOST_IOS::seekdir)
281 template<typename Device>
282 void close(Device&) { close_.execute(); }
289 class closable_filter<dual_use> {
291 typedef char char_type;
297 closable_filter(operation close_input, operation close_output)
298 : close_input_(close_input), close_output_(close_output)
301 template<typename Source>
302 int get(Source&) { return EOF; }
304 template<typename Sink>
305 bool put(Sink&, char) { return true; }
307 template<typename Device>
308 void close(Device&, BOOST_IOS::openmode which)
312 close_input_.execute();
315 close_output_.execute();
322 operation close_input_;
323 operation close_output_;
327 class closable_symmetric_filter {
329 typedef char char_type;
330 closable_symmetric_filter(operation close) : close_(close) { }
331 bool filter( const char*&, const char*,
332 char*&, char*, bool )
336 void close() { close_.execute(); }
341 } } } // End namespaces test, iostreams, boost.
343 #endif // #ifndef BOOST_IOSTREAMS_TEST_CLOSABLE_HPP_INCLUDED