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 | // Contains the definitions of several constants used by the test program. |
9 | |
10 | #ifndef BOOST_IOSTREAMS_TEST_FILTERS_HPP_INCLUDED |
11 | #define BOOST_IOSTREAMS_TEST_FILTERS_HPP_INCLUDED |
12 | |
13 | #include <boost/config.hpp> |
14 | #include <algorithm> // min. |
15 | #include <cctype> // to_upper, to_lower. |
16 | #include <cstdlib> // to_upper, to_lower (VC6). |
17 | #include <cstddef> // ptrdiff_t. |
18 | #include <vector> |
19 | #include <boost/iostreams/char_traits.hpp> |
20 | #include <boost/iostreams/concepts.hpp> |
21 | #include <boost/iostreams/constants.hpp> |
22 | #include <boost/iostreams/detail/iostream.hpp> // seekdir, streamsize. |
23 | #include <boost/iostreams/detail/streambuf.hpp> |
24 | #include <boost/iostreams/operations.hpp> |
25 | #include <boost/iostreams/pipeline.hpp> |
26 | #include <boost/type_traits/is_convertible.hpp> |
27 | #ifdef BOOST_NO_STDC_NAMESPACE |
28 | namespace std { using ::toupper; using ::tolower; } |
29 | #endif |
30 | |
31 | // Must come last. |
32 | #include <boost/iostreams/detail/config/disable_warnings.hpp> |
33 | |
34 | namespace boost { namespace iostreams { namespace test { |
35 | |
36 | struct toupper_filter : public input_filter { |
37 | template<typename Source> |
38 | int get(Source& s) |
39 | { |
40 | int c = boost::iostreams::get(s); |
41 | return c != EOF && c != WOULD_BLOCK ? |
42 | std::toupper(c: (unsigned char) c) : |
43 | c; |
44 | } |
45 | }; |
46 | BOOST_IOSTREAMS_PIPABLE(toupper_filter, 0) |
47 | |
48 | struct tolower_filter : public output_filter { |
49 | template<typename Sink> |
50 | bool put(Sink& s, char c) |
51 | { |
52 | return boost::iostreams::put( |
53 | s, (char) std::tolower(c: (unsigned char) c) |
54 | ); |
55 | } |
56 | }; |
57 | BOOST_IOSTREAMS_PIPABLE(tolower_filter, 0) |
58 | |
59 | struct toupper_multichar_filter : public multichar_input_filter { |
60 | template<typename Source> |
61 | std::streamsize read(Source& s, char* buf, std::streamsize n) |
62 | { |
63 | std::streamsize result = boost::iostreams::read(s, buf, n); |
64 | if (result == -1) |
65 | return -1; |
66 | for (int z = 0; z < result; ++z) |
67 | buf[z] = (char) std::toupper(c: (unsigned char) buf[z]); |
68 | return result; |
69 | } |
70 | }; |
71 | BOOST_IOSTREAMS_PIPABLE(toupper_multichar_filter, 0) |
72 | |
73 | struct tolower_multichar_filter : public multichar_output_filter { |
74 | template<typename Sink> |
75 | std::streamsize write(Sink& s, const char* buf, std::streamsize n) |
76 | { |
77 | std::streamsize result; |
78 | for (result = 0; result < n; ++result) { |
79 | char c = (char) std::tolower(c: (unsigned char) buf[result]); |
80 | if (!boost::iostreams::put(s, c)) |
81 | break; |
82 | } |
83 | return result; |
84 | } |
85 | }; |
86 | BOOST_IOSTREAMS_PIPABLE(tolower_multichar_filter, 0) |
87 | |
88 | struct padding_filter : dual_use_filter { |
89 | explicit padding_filter(char pad_char) |
90 | : pad_char_(pad_char), use_pad_char_(false), eof_(false) |
91 | { } |
92 | |
93 | template<typename Source> |
94 | int get(Source& src) |
95 | { |
96 | int result; |
97 | if (use_pad_char_) { |
98 | result = eof_ ? EOF : pad_char_; |
99 | use_pad_char_ = false; |
100 | } else { |
101 | result = boost::iostreams::get(src); |
102 | if (result != EOF && result != WOULD_BLOCK) |
103 | use_pad_char_ = true; |
104 | eof_ = result == EOF; |
105 | } |
106 | return result; |
107 | } |
108 | |
109 | template<typename Sink> |
110 | bool put(Sink& s, char c) |
111 | { |
112 | if (use_pad_char_) { |
113 | if (!boost::iostreams::put(s, pad_char_)) |
114 | return false; |
115 | use_pad_char_ = false; |
116 | } |
117 | if (!boost::iostreams::put(s, c)) |
118 | return false; |
119 | if (!boost::iostreams::put(s, pad_char_)) |
120 | use_pad_char_ = true; |
121 | return true; |
122 | } |
123 | |
124 | char pad_char_; |
125 | bool use_pad_char_; |
126 | bool eof_; |
127 | }; |
128 | BOOST_IOSTREAMS_PIPABLE(padding_filter, 0) |
129 | |
130 | struct flushable_output_filter { |
131 | typedef char char_type; |
132 | struct category |
133 | : output_filter_tag, |
134 | flushable_tag |
135 | { }; |
136 | template<typename Sink> |
137 | bool put(Sink&, char c) |
138 | { |
139 | buf_.push_back(x: c); |
140 | return true; |
141 | } |
142 | template<typename Sink> |
143 | bool flush(Sink& s) |
144 | { |
145 | if (!buf_.empty()) { |
146 | boost::iostreams::write(s, &buf_[0], (std::streamsize) buf_.size()); |
147 | buf_.clear(); |
148 | } |
149 | return true; |
150 | } |
151 | std::vector<char> buf_; |
152 | }; |
153 | BOOST_IOSTREAMS_PIPABLE(flushable_output_filter, 0) |
154 | |
155 | struct identity_seekable_filter : filter<seekable> { |
156 | template<typename Source> |
157 | int get(Source& s) { return boost::iostreams::get(s); } |
158 | |
159 | template<typename Sink> |
160 | bool put(Sink& s, char c) { return boost::iostreams::put(s, c); } |
161 | |
162 | template<typename Device> |
163 | std::streampos seek(Device& d, stream_offset off, BOOST_IOS::seekdir way) |
164 | { return boost::iostreams::seek(d, off, way); } |
165 | }; |
166 | BOOST_IOSTREAMS_PIPABLE(identity_seekable_filter, 0) |
167 | |
168 | struct identity_seekable_multichar_filter : multichar_filter<seekable> { |
169 | template<typename Source> |
170 | std::streamsize read(Source& s, char* buf, std::streamsize n) |
171 | { return boost::iostreams::read(s, buf, n); } |
172 | template<typename Sink> |
173 | std::streamsize write(Sink& s, const char* buf, std::streamsize n) |
174 | { return boost::iostreams::write(s, buf, n); } |
175 | template<typename Device> |
176 | std::streampos seek(Device& d, stream_offset off, BOOST_IOS::seekdir way) |
177 | { return boost::iostreams::seek(d, off, way); } |
178 | }; |
179 | BOOST_IOSTREAMS_PIPABLE(identity_seekable_multichar_filter, 0) |
180 | |
181 | } } } // End namespaces detail, iostreams, boost. |
182 | |
183 | #include <boost/iostreams/detail/config/enable_warnings.hpp> |
184 | |
185 | #endif // #ifndef BOOST_IOSTREAMS_TEST_FILTERS_HPP_INCLUDED |
186 | |