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
28namespace std { using ::toupper; using ::tolower; }
29#endif
30
31// Must come last.
32#include <boost/iostreams/detail/config/disable_warnings.hpp>
33
34namespace boost { namespace iostreams { namespace test {
35
36struct 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};
46BOOST_IOSTREAMS_PIPABLE(toupper_filter, 0)
47
48struct 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};
57BOOST_IOSTREAMS_PIPABLE(tolower_filter, 0)
58
59struct 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};
71BOOST_IOSTREAMS_PIPABLE(toupper_multichar_filter, 0)
72
73struct 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};
86BOOST_IOSTREAMS_PIPABLE(tolower_multichar_filter, 0)
87
88struct 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};
128BOOST_IOSTREAMS_PIPABLE(padding_filter, 0)
129
130struct 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};
153BOOST_IOSTREAMS_PIPABLE(flushable_output_filter, 0)
154
155struct 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};
166BOOST_IOSTREAMS_PIPABLE(identity_seekable_filter, 0)
167
168struct 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};
179BOOST_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

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