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/buffer.hpp>
23 #include <boost/iostreams/detail/iostream.hpp>  // seekdir, streamsize.
24 #include <boost/iostreams/detail/streambuf.hpp>
25 #include <boost/iostreams/operations.hpp>
26 #include <boost/iostreams/pipeline.hpp>
27 #include <boost/type_traits/is_convertible.hpp>
28 #ifdef BOOST_NO_STDC_NAMESPACE
29 namespace std { using ::toupper; using ::tolower; }
30 #endif
31 
32 // Must come last.
33 #include <boost/iostreams/detail/config/disable_warnings.hpp>
34 
35 namespace boost { namespace iostreams { namespace test {
36 
37 struct toupper_filter : public input_filter {
38     template<typename Source>
getboost::iostreams::test::toupper_filter39     int get(Source& s)
40     {
41         int c = boost::iostreams::get(s);
42         return c != EOF && c != WOULD_BLOCK ?
43             std::toupper((unsigned char) c) :
44             c;
45     }
46 };
47 BOOST_IOSTREAMS_PIPABLE(toupper_filter, 0)
48 
49 struct tolower_filter : public output_filter {
50     template<typename Sink>
putboost::iostreams::test::tolower_filter51     bool put(Sink& s, char c)
52     {
53         return boost::iostreams::put(
54                    s, (char) std::tolower((unsigned char) c)
55                );
56     }
57 };
58 BOOST_IOSTREAMS_PIPABLE(tolower_filter, 0)
59 
60 struct toupper_multichar_filter : public multichar_input_filter {
61     template<typename Source>
readboost::iostreams::test::toupper_multichar_filter62     std::streamsize read(Source& s, char* buf, std::streamsize n)
63     {
64         std::streamsize result = boost::iostreams::read(s, buf, n);
65         if (result == -1)
66             return -1;
67         for (int z = 0; z < result; ++z)
68             buf[z] = (char) std::toupper((unsigned char) buf[z]);
69         return result;
70     }
71 };
72 BOOST_IOSTREAMS_PIPABLE(toupper_multichar_filter, 0)
73 
74 struct tolower_multichar_filter : public multichar_output_filter {
75     template<typename Sink>
writeboost::iostreams::test::tolower_multichar_filter76     std::streamsize write(Sink& s, const char* buf, std::streamsize n)
77     {
78         std::streamsize result;
79         for (result = 0; result < n; ++result) {
80             char c = (char) std::tolower((unsigned char) buf[result]);
81             if (!boost::iostreams::put(s, c))
82                 break;
83         }
84         return result;
85     }
86 };
87 BOOST_IOSTREAMS_PIPABLE(tolower_multichar_filter, 0)
88 
89 struct padding_filter : dual_use_filter {
padding_filterboost::iostreams::test::padding_filter90     explicit padding_filter(char pad_char)
91         : pad_char_(pad_char), use_pad_char_(false), eof_(false)
92         { }
93 
94     template<typename Source>
getboost::iostreams::test::padding_filter95     int get(Source& src)
96     {
97         int result;
98         if (use_pad_char_) {
99             result = eof_ ? EOF : pad_char_;
100             use_pad_char_ = false;
101         } else {
102             result = boost::iostreams::get(src);
103             if (result != EOF && result != WOULD_BLOCK)
104                 use_pad_char_ = true;
105             eof_ = result == EOF;
106         }
107         return result;
108     }
109 
110     template<typename Sink>
putboost::iostreams::test::padding_filter111     bool put(Sink& s, char c)
112     {
113         if (use_pad_char_) {
114             if (!boost::iostreams::put(s, pad_char_))
115                 return false;
116             use_pad_char_ = false;
117         }
118         if (!boost::iostreams::put(s, c))
119             return false;
120         if (!boost::iostreams::put(s, pad_char_))
121             use_pad_char_ = true;
122         return true;
123     }
124 
125     char  pad_char_;
126     bool  use_pad_char_;
127     bool  eof_;
128 };
129 BOOST_IOSTREAMS_PIPABLE(padding_filter, 0)
130 
131 struct flushable_output_filter {
132     typedef char char_type;
133     struct category
134         : output_filter_tag,
135           flushable_tag
136         { };
137     template<typename Sink>
putboost::iostreams::test::flushable_output_filter138     bool put(Sink&, char c)
139     {
140         buf_.push_back(c);
141         return true;
142     }
143     template<typename Sink>
flushboost::iostreams::test::flushable_output_filter144     bool flush(Sink& s)
145     {
146         if (!buf_.empty()) {
147             boost::iostreams::write(s, &buf_[0], (std::streamsize) buf_.size());
148             buf_.clear();
149         }
150         return true;
151     }
152     std::vector<char> buf_;
153 };
154 BOOST_IOSTREAMS_PIPABLE(flushable_output_filter, 0)
155 
156 struct identity_seekable_filter : filter<seekable> {
157     template<typename Source>
getboost::iostreams::test::identity_seekable_filter158     int get(Source& s) { return boost::iostreams::get(s); }
159 
160     template<typename Sink>
putboost::iostreams::test::identity_seekable_filter161     bool put(Sink& s, char c) { return boost::iostreams::put(s, c); }
162 
163     template<typename Device>
seekboost::iostreams::test::identity_seekable_filter164     std::streampos seek(Device& d, stream_offset off, BOOST_IOS::seekdir way)
165     { return boost::iostreams::seek(d, off, way); }
166 };
167 BOOST_IOSTREAMS_PIPABLE(identity_seekable_filter, 0)
168 
169 struct identity_seekable_multichar_filter : multichar_filter<seekable> {
170     template<typename Source>
readboost::iostreams::test::identity_seekable_multichar_filter171     std::streamsize read(Source& s, char* buf, std::streamsize n)
172     { return boost::iostreams::read(s, buf, n); }
173     template<typename Sink>
writeboost::iostreams::test::identity_seekable_multichar_filter174     std::streamsize write(Sink& s, const char* buf, std::streamsize n)
175     { return boost::iostreams::write(s, buf, n); }
176     template<typename Device>
seekboost::iostreams::test::identity_seekable_multichar_filter177     std::streampos seek(Device& d, stream_offset off, BOOST_IOS::seekdir way)
178     { return boost::iostreams::seek(d, off, way); }
179 };
180 BOOST_IOSTREAMS_PIPABLE(identity_seekable_multichar_filter, 0)
181 
182 } } } // End namespaces detail, iostreams, boost.
183 
184 #include <boost/iostreams/detail/config/enable_warnings.hpp>
185 
186 #endif // #ifndef BOOST_IOSTREAMS_TEST_FILTERS_HPP_INCLUDED
187