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
28namespace boost { namespace iostreams { namespace test {
29
30template<typename Category>
31class closable_device { };
32
33// Source
34template<>
35class closable_device<input> : public source {
36public:
37 closable_device(operation close) : close_(close) { }
38 std::streamsize read(char*, std::streamsize) { return -1; }
39 void close() { close_.execute(); }
40private:
41 operation close_;
42};
43
44// Sink
45template<>
46class closable_device<output> : public sink {
47public:
48 closable_device(operation close) : close_(close) { }
49 std::streamsize write(const char*, std::streamsize) { return 0; }
50 void close() { close_.execute(); }
51private:
52 operation close_;
53};
54
55struct borland_output { };
56
57// Copy of closable_device<output>, for Borland <= 5.8.2
58template<>
59class closable_device<borland_output> : public sink {
60public:
61 closable_device(operation close) : close_(close) { }
62 std::streamsize write(const char*, std::streamsize) { return 0; }
63 void close() { close_.execute(); }
64private:
65 operation close_;
66};
67
68// Bidirectional device
69template<>
70class closable_device<bidirectional> : public device<bidirectional> {
71public:
72 closable_device(operation close_input, operation close_output)
73 : close_input_(close_input), close_output_(close_output)
74 { }
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)
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 }
90private:
91 operation close_input_;
92 operation close_output_;
93};
94
95// Seekable device
96template<>
97class closable_device<seekable> : public device<seekable> {
98public:
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(); }
104private:
105 operation close_;
106};
107
108struct direct_input
109 : input, device_tag, closable_tag, direct_tag
110 { };
111struct direct_output
112 : output, device_tag, closable_tag, direct_tag
113 { };
114struct direct_bidirectional
115 : bidirectional, device_tag, closable_tag, direct_tag
116 { };
117struct direct_seekable
118 : seekable, device_tag, closable_tag, direct_tag
119 { };
120
121// Direct source
122template<>
123class closable_device<direct_input> {
124public:
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(); }
131private:
132 operation close_;
133};
134
135// Direct sink
136template<>
137class closable_device<direct_output> {
138public:
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(); }
145private:
146 operation close_;
147};
148
149// Direct bidirectional device
150template<>
151class closable_device<direct_bidirectional> {
152public:
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)
157 { }
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)
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 }
175private:
176 operation close_input_;
177 operation close_output_;
178};
179
180// Direct seekable device
181template<>
182class closable_device<direct_seekable> {
183public:
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(); }
192private:
193 operation close_;
194};
195
196template<typename Mode>
197class closable_filter { };
198
199// Input filter
200template<>
201class closable_filter<input> : public input_filter {
202public:
203 closable_filter(operation close) : close_(close) { }
204
205 template<typename Source>
206 int get(Source&) { return EOF; }
207
208 template<typename Source>
209 void close(Source&) { close_.execute(); }
210private:
211 operation close_;
212};
213
214// Output filter
215template<>
216class closable_filter<output> : public output_filter {
217public:
218 closable_filter(operation close) : close_(close) { }
219
220 template<typename Sink>
221 bool put(Sink&, char) { return true; }
222
223 template<typename Sink>
224 void close(Sink&) { close_.execute(); }
225private:
226 operation close_;
227};
228
229// Bidirectional filter
230template<>
231class closable_filter<bidirectional> : public filter<bidirectional> {
232public:
233 closable_filter(operation close_input, operation close_output)
234 : close_input_(close_input), close_output_(close_output)
235 { }
236
237 template<typename Source>
238 int get(Source&) { return EOF; }
239
240 template<typename Sink>
241 bool put(Sink&, char) { return true; }
242
243 template<typename Device>
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 }
257private:
258 operation close_input_;
259 operation close_output_;
260};
261
262// Seekable filter
263template<>
264class closable_filter<seekable> : public filter<seekable> {
265public:
266 closable_filter(operation close) : close_(close) { }
267 std::streamsize read(char*, std::streamsize) { return -1; }
268
269 template<typename Source>
270 int get(Source&) { return EOF; }
271
272 template<typename Sink>
273 bool put(Sink&, char) { return true; }
274
275 template<typename Device>
276 stream_offset seek(Device&, stream_offset, BOOST_IOS::seekdir)
277 {
278 return 0;
279 }
280
281 template<typename Device>
282 void close(Device&) { close_.execute(); }
283private:
284 operation close_;
285};
286
287// Dual-use filter
288template<>
289class closable_filter<dual_use> {
290public:
291 typedef char char_type;
292 struct category
293 : filter_tag,
294 dual_use,
295 closable_tag
296 { };
297 closable_filter(operation close_input, operation close_output)
298 : close_input_(close_input), close_output_(close_output)
299 { }
300
301 template<typename Source>
302 int get(Source&) { return EOF; }
303
304 template<typename Sink>
305 bool put(Sink&, char) { return true; }
306
307 template<typename Device>
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 }
321private:
322 operation close_input_;
323 operation close_output_;
324};
325
326// Symmetric filter
327class closable_symmetric_filter {
328public:
329 typedef char char_type;
330 closable_symmetric_filter(operation close) : close_(close) { }
331 bool filter( const char*&, const char*,
332 char*&, char*, bool )
333 {
334 return false;
335 }
336 void close() { close_.execute(); }
337private:
338 operation close_;
339};
340
341} } } // End namespaces test, iostreams, boost.
342
343#endif // #ifndef BOOST_IOSTREAMS_TEST_CLOSABLE_HPP_INCLUDED
344

source code of boost/libs/iostreams/test/detail/closable.hpp