removed _filter from header name

[SVN r30122]
This commit is contained in:
Jonathan Turkanis
2005-07-15 23:46:02 +00:00
parent 59b4ee1213
commit 51dcda2d2b
3 changed files with 389 additions and 0 deletions

View File

@@ -0,0 +1,214 @@
// (C) Copyright Jonathan Turkanis 2005.
// 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.
#ifndef BOOST_IOSTREAMS_LINE_FILTER_HPP_INCLUDED
#define BOOST_IOSTREAMS_LINE_FILTER_HPP_INCLUDED
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <algorithm> // min.
#include <cassert>
#include <memory> // allocator.
#include <string>
#include <boost/config.hpp> // BOOST_STATIC_CONSTANT.
#include <boost/iostreams/categories.hpp>
#include <boost/iostreams/detail/closer.hpp>
#include <boost/iostreams/detail/ios.hpp> // openmode, streamsize.
#include <boost/iostreams/pipeline.hpp>
// Must come last.
#include <boost/iostreams/detail/config/disable_warnings.hpp> // VC7.1 C4244.
namespace boost { namespace iostreams {
//
// Template name: line_filter.
// Template paramters:
// Ch - The character type.
// Alloc - The allocator type.
// Description: Filter which processes data one line at a time.
//
template< typename Ch,
typename Alloc =
#if BOOST_WORKAROUND(__GNUC__, < 3)
typename std::basic_string<Ch>::allocator_type
#else
std::allocator<Ch>
#endif
>
class basic_line_filter {
private:
typedef typename std::basic_string<Ch>::traits_type string_traits;
public:
typedef Ch char_type;
typedef char_traits<char_type> traits_type;
typedef std::basic_string<
Ch,
string_traits,
Alloc
> string_type;
struct category
: dual_use,
filter_tag,
multichar_tag,
closable_tag
{ };
protected:
basic_line_filter() : pos_(string_type::npos), state_(0) { }
public:
virtual ~basic_line_filter() { }
template<typename Source>
std::streamsize read(Source& src, char_type* s, std::streamsize n)
{
using namespace std;
assert(!(state_ & f_write));
state_ |= f_read;
// Handle unfinished business.
streamsize result = 0;
if (!cur_line_.empty() && (result = read_line(s, n)) == n)
return n;
typename traits_type::int_type status = traits_type::good();
while (result < n && !traits_type::is_eof(status)) {
// Call next_line() to retrieve a line of filtered test, and
// read_line() to copy it into buffer s.
if (traits_type::would_block(status = next_line(src)))
return result;
result += read_line(s + result, n - result);
}
return detail::check_eof(result);
}
template<typename Sink>
std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
{
using namespace std;
assert(!(state_ & f_read));
state_ |= f_write;
// Handle unfinished business.
if (pos_ != string_type::npos && !write_line(snk))
return 0;
const char_type *cur = s, *next;
while (true) {
// Search for the next full line in [cur, s + n), filter it
// and write it to snk.
typename string_type::size_type rest = n - (cur - s);
if ((next = traits_type::find(cur, rest, traits_type::newline()))) {
cur_line_.append(cur, next - cur);
cur = next + 1;
if (!write_line(snk))
return static_cast<std::streamsize>(cur - s);
} else {
cur_line_.append(cur, rest);
return n;
}
}
}
typedef basic_line_filter<Ch, Alloc> self;
friend struct detail::closer<self>;
template<typename Sink>
void close(Sink& snk, BOOST_IOS::openmode which)
{
if ((state_ & f_read) && (which & BOOST_IOS::in))
close();
if ((state_ & f_write) && (which & BOOST_IOS::out)) {
detail::closer<self> closer(*this);
if (!cur_line_.empty())
write_line(snk);
}
}
private:
virtual string_type do_filter(const string_type& line) = 0;
// Copies filtered characters fron the current line into
// the given buffer.
std::streamsize read_line(char_type* s, std::streamsize n)
{
using namespace std;
streamsize result =
(std::min) (n, static_cast<streamsize>(cur_line_.size()));
traits_type::copy(s, cur_line_.data(), result);
cur_line_.erase(0, result);
return result;
}
// Attempts to retrieve a line of text from the given source; returns
// an int_type as a good/eof/would_block status code.
template<typename Source>
typename traits_type::int_type next_line(Source& src)
{
using namespace std;
typename traits_type::int_type c;
while ( traits_type::is_good(c = iostreams::get(src)) &&
c != traits_type::newline() )
{
cur_line_ += traits_type::to_int_type(c);
}
if (!traits_type::would_block(c)) {
if (!cur_line_.empty() || c == traits_type::newline())
cur_line_ = do_filter(cur_line_);
if (c == traits_type::newline())
cur_line_ += c;
}
return c; // status indicator.
}
// Filters the current line and attemps to write it to the given sink.
// Returns true for success.
template<typename Sink>
bool write_line(Sink& snk)
{
string_type line = do_filter(cur_line_) + traits_type::newline();
std::streamsize amt = static_cast<std::streamsize>(line.size());
bool result = iostreams::write(snk, line.data(), amt) == amt;
if (result)
clear();
return result;
}
void close()
{
clear();
state_ = 0;
}
void clear()
{
cur_line_.erase();
pos_ = string_type::npos;
}
enum {
f_read = 1,
f_write = f_read << 1
};
string_type cur_line_;
typename string_type::size_type pos_;
int state_;
};
BOOST_IOSTREAMS_PIPABLE(basic_line_filter, 2)
typedef basic_line_filter<char> line_filter;
typedef basic_line_filter<wchar_t> wline_filter;
} } // End namespaces iostreams, boost.
#include <boost/iostreams/detail/config/enable_warnings.hpp>
#endif // #ifndef BOOST_IOSTREAMS_LINE_FILTER_HPP_INCLUDED

View File

@@ -0,0 +1,93 @@
// (C) Copyright Jonathan Turkanis 2003.
// 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.
#ifndef BOOST_IOSTREAMS_REGEX_FILTER_HPP_INCLUDED
#define BOOST_IOSTREAMS_REGEX_FILTER_HPP_INCLUDED
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <memory> // allocator.
#include <boost/function.hpp>
#include <boost/iostreams/filter/aggregate.hpp>
#include <boost/iostreams/pipeline.hpp>
#include <boost/regex.hpp>
namespace boost { namespace iostreams {
template< typename Ch,
typename Tr = regex_traits<Ch>,
typename Alloc = std::allocator<Ch> >
class basic_regex_filter : public aggregate_filter<Ch, Alloc> {
private:
typedef aggregate_filter<Ch, Alloc> base_type;
public:
typedef typename base_type::char_type char_type;
typedef typename base_type::category category;
typedef std::basic_string<Ch> string_type;
typedef basic_regex<Ch, Tr> regex_type;
typedef regex_constants::match_flag_type flag_type;
typedef match_results<const Ch*> match_type;
typedef function1<string_type, const match_type&> formatter;
basic_regex_filter( const regex_type& re,
const formatter& replace,
flag_type flags = regex_constants::match_default )
: re_(re), replace_(replace), flags_(flags) { }
basic_regex_filter( const regex_type& re,
const string_type& fmt,
flag_type flags = regex_constants::match_default,
flag_type fmt_flags = regex_constants::format_default )
: re_(re), replace_(simple_formatter(fmt, fmt_flags)), flags_(flags) { }
basic_regex_filter( const regex_type& re,
const char_type* fmt,
flag_type flags = regex_constants::match_default,
flag_type fmt_flags = regex_constants::format_default )
: re_(re), replace_(simple_formatter(fmt, fmt_flags)), flags_(flags) { }
private:
typedef typename base_type::vector_type vector_type;
void do_filter(const vector_type& src, vector_type& dest)
{
typedef regex_iterator<const Ch*, Ch, Tr> iterator;
if (src.empty())
return;
iterator first(&src[0], &src[0] + src.size(), re_, flags_);
iterator last;
const Ch* suffix = 0; // Prevent GCC 2.95 warning.
for (; first != last; ++first) {
dest.insert( dest.end(),
first->prefix().first,
first->prefix().second );
string_type replacement = replace_(*first);
dest.insert( dest.end(),
replacement.begin(),
replacement.end() );
suffix = first->suffix().first;
}
dest.insert(dest.end(), suffix, &src[0] + src.size());
}
struct simple_formatter {
simple_formatter(const string_type& fmt, flag_type fmt_flags)
: fmt_(fmt), fmt_flags_(fmt_flags_) { }
string_type operator() (const match_type& match) const
{ return match.format(fmt_, fmt_flags_); }
string_type fmt_;
flag_type fmt_flags_;
};
regex_type re_;
formatter replace_;
flag_type flags_;
};
BOOST_IOSTREAMS_PIPABLE(basic_regex_filter, 3)
typedef basic_regex_filter<char> regex_filter;
typedef basic_regex_filter<wchar_t> wregex_filter;
} } // End namespaces iostreams, boost.
#endif // #ifndef BOOST_IOSTREAMS_REGEX_FILTER_HPP_INCLUDED

View File

@@ -0,0 +1,82 @@
// (C) Copyright Jonathan Turkanis 2005.
// 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.
// Based on the work of Christopher Diggins.
#ifndef BOOST_IOSTREAMS_STDIO_FILTER_HPP_INCLUDED
#define BOOST_IOSTREAMS_STDIO_FILTER_HPP_INCLUDED
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <iostream>
#include <memory> // allocator.
#include <vector>
#include <boost/iostreams/detail/config/wide_streams.hpp>
#include <boost/iostreams/detail/char_traits.hpp>
#include <boost/iostreams/detail/ios.hpp>
#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/device/back_inserter.hpp>
#include <boost/iostreams/filter/aggregate.hpp>
#include <boost/iostreams/pipeline.hpp>
#include <boost/iostreams/stream_buffer.hpp>
namespace boost { namespace iostreams {
namespace detail {
} // End namespace detail.
template<typename Ch, typename Alloc = std::allocator<Ch> >
class basic_stdio_filter : public aggregate_filter<Ch, Alloc> {
private:
typedef aggregate_filter<Ch, Alloc> base_type;
public:
typedef typename base_type::char_type char_type;
typedef typename base_type::category category;
typedef typename base_type::vector_type vector_type;
private:
static std::istream& standard_input(char*) { return std::cin; }
static std::ostream& standard_output(char*) { return std::cout; }
#ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS
static std::wistream& standard_input(wchar_t*) { return std::wcin; }
static std::wostream& standard_output(wchar_t*) { return std::wcout; }
#endif // BOOST_IOSTREAMS_NO_WIDE_STREAMS
struct scoped_redirector { // Thanks to Maxim Egorushkin.
typedef BOOST_IOSTREAMS_CHAR_TRAITS(Ch) traits_type;
typedef BOOST_IOSTREAMS_BASIC_IOS(Ch, traits_type) ios_type;
typedef BOOST_IOSTREAMS_BASIC_STREAMBUF(Ch, traits_type) streambuf_type;
scoped_redirector( ios_type& ios,
streambuf_type* newbuf )
: ios_(ios), old_(ios.rdbuf(newbuf))
{ }
~scoped_redirector() { ios_.rdbuf(old_); }
ios_type& ios_;
streambuf_type* old_;
};
virtual void do_filter() = 0;
virtual void do_filter(const vector_type& src, vector_type& dest)
{
stream_buffer< basic_array_source<Ch> >
srcbuf(&src[0], &src[0] + src.size());
stream_buffer< back_insert_device<vector_type> >
destbuf(iostreams::back_inserter(dest));
scoped_redirector redirect_input(standard_input((Ch*)0), &srcbuf);
scoped_redirector redirect_output(standard_output((Ch*)0), &destbuf);
do_filter();
}
};
BOOST_IOSTREAMS_PIPABLE(basic_stdio_filter, 2)
typedef basic_stdio_filter<char> stdio_filter;
typedef basic_stdio_filter<wchar_t> wstdio_wfilter;
} } // End namespaces iostreams, boost.
#endif // #ifndef BOOST_IOSTREAMS_STDIO_FILTER_HPP_INCLUDED