blob: 3d01a4f8e210d7a341872b66a1e5f37619dd0658 [file] [log] [blame]
// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
// (C) Copyright 2004-2007 Jonathan Turkanis
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
// See http://www.boost.org/libs/iostreams for documentation.
// Contains the definitions of several constants used by the test program.
#ifndef BOOST_IOSTREAMS_TEST_FILTERS_HPP_INCLUDED
#define BOOST_IOSTREAMS_TEST_FILTERS_HPP_INCLUDED
#include <boost/config.hpp>
#include <algorithm> // min.
#include <cctype> // to_upper, to_lower.
#include <cstdlib> // to_upper, to_lower (VC6).
#include <cstddef> // ptrdiff_t.
#include <vector>
#include <boost/iostreams/char_traits.hpp>
#include <boost/iostreams/concepts.hpp>
#include <boost/iostreams/constants.hpp>
#include <boost/iostreams/detail/buffer.hpp>
#include <boost/iostreams/detail/iostream.hpp> // seekdir, streamsize.
#include <boost/iostreams/detail/streambuf.hpp>
#include <boost/iostreams/operations.hpp>
#include <boost/iostreams/pipeline.hpp>
#include <boost/type_traits/is_convertible.hpp>
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std { using ::toupper; using ::tolower; }
#endif
// Must come last.
#include <boost/iostreams/detail/config/disable_warnings.hpp>
namespace boost { namespace iostreams { namespace test {
struct toupper_filter : public input_filter {
template<typename Source>
int get(Source& s)
{
int c = boost::iostreams::get(s);
return c != EOF && c != WOULD_BLOCK ?
std::toupper((unsigned char) c) :
c;
}
};
BOOST_IOSTREAMS_PIPABLE(toupper_filter, 0)
struct tolower_filter : public output_filter {
template<typename Sink>
bool put(Sink& s, char c)
{
return boost::iostreams::put(
s, (char) std::tolower((unsigned char) c)
);
}
};
BOOST_IOSTREAMS_PIPABLE(tolower_filter, 0)
struct toupper_multichar_filter : public multichar_input_filter {
template<typename Source>
std::streamsize read(Source& s, char* buf, std::streamsize n)
{
std::streamsize result = boost::iostreams::read(s, buf, n);
if (result == -1)
return -1;
for (int z = 0; z < result; ++z)
buf[z] = (char) std::toupper((unsigned char) buf[z]);
return result;
}
};
BOOST_IOSTREAMS_PIPABLE(toupper_multichar_filter, 0)
struct tolower_multichar_filter : public multichar_output_filter {
template<typename Sink>
std::streamsize write(Sink& s, const char* buf, std::streamsize n)
{
std::streamsize result;
for (result = 0; result < n; ++result) {
char c = (char) std::tolower((unsigned char) buf[result]);
if (!boost::iostreams::put(s, c))
break;
}
return result;
}
};
BOOST_IOSTREAMS_PIPABLE(tolower_multichar_filter, 0)
struct padding_filter : dual_use_filter {
explicit padding_filter(char pad_char)
: pad_char_(pad_char), use_pad_char_(false), eof_(false)
{ }
template<typename Source>
int get(Source& src)
{
int result;
if (use_pad_char_) {
result = eof_ ? EOF : pad_char_;
use_pad_char_ = false;
} else {
result = boost::iostreams::get(src);
if (result != EOF && result != WOULD_BLOCK)
use_pad_char_ = true;
eof_ = result == EOF;
}
return result;
}
template<typename Sink>
bool put(Sink& s, char c)
{
if (use_pad_char_) {
if (!boost::iostreams::put(s, pad_char_))
return false;
use_pad_char_ = false;
}
if (!boost::iostreams::put(s, c))
return false;
if (!boost::iostreams::put(s, pad_char_))
use_pad_char_ = true;
return true;
}
char pad_char_;
bool use_pad_char_;
bool eof_;
};
BOOST_IOSTREAMS_PIPABLE(padding_filter, 0)
struct flushable_output_filter {
typedef char char_type;
struct category
: output_filter_tag,
flushable_tag
{ };
template<typename Sink>
bool put(Sink&, char c)
{
buf_.push_back(c);
return true;
}
template<typename Sink>
bool flush(Sink& s)
{
if (!buf_.empty()) {
boost::iostreams::write(s, &buf_[0], (std::streamsize) buf_.size());
buf_.clear();
}
return true;
}
std::vector<char> buf_;
};
BOOST_IOSTREAMS_PIPABLE(flushable_output_filter, 0)
struct identity_seekable_filter : filter<seekable> {
template<typename Source>
int get(Source& s) { return boost::iostreams::get(s); }
template<typename Sink>
bool put(Sink& s, char c) { return boost::iostreams::put(s, c); }
template<typename Device>
std::streampos seek(Device& d, stream_offset off, BOOST_IOS::seekdir way)
{ return boost::iostreams::seek(d, off, way); }
};
BOOST_IOSTREAMS_PIPABLE(identity_seekable_filter, 0)
struct identity_seekable_multichar_filter : multichar_filter<seekable> {
template<typename Source>
std::streamsize read(Source& s, char* buf, std::streamsize n)
{ return boost::iostreams::read(s, buf, n); }
template<typename Sink>
std::streamsize write(Sink& s, const char* buf, std::streamsize n)
{ return boost::iostreams::write(s, buf, n); }
template<typename Device>
std::streampos seek(Device& d, stream_offset off, BOOST_IOS::seekdir way)
{ return boost::iostreams::seek(d, off, way); }
};
BOOST_IOSTREAMS_PIPABLE(identity_seekable_multichar_filter, 0)
} } } // End namespaces detail, iostreams, boost.
#include <boost/iostreams/detail/config/enable_warnings.hpp>
#endif // #ifndef BOOST_IOSTREAMS_TEST_FILTERS_HPP_INCLUDED