From 51dcda2d2bd6910fe21519ed2b2087c0738eba61 Mon Sep 17 00:00:00 2001 From: Jonathan Turkanis Date: Fri, 15 Jul 2005 23:46:02 +0000 Subject: [PATCH] removed _filter from header name [SVN r30122] --- include/boost/iostreams/filter/line.hpp | 214 +++++++++++++++++++++++ include/boost/iostreams/filter/regex.hpp | 93 ++++++++++ include/boost/iostreams/filter/stdio.hpp | 82 +++++++++ 3 files changed, 389 insertions(+) create mode 100755 include/boost/iostreams/filter/line.hpp create mode 100755 include/boost/iostreams/filter/regex.hpp create mode 100755 include/boost/iostreams/filter/stdio.hpp diff --git a/include/boost/iostreams/filter/line.hpp b/include/boost/iostreams/filter/line.hpp new file mode 100755 index 0000000..87bb495 --- /dev/null +++ b/include/boost/iostreams/filter/line.hpp @@ -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 // min. +#include +#include // allocator. +#include +#include // BOOST_STATIC_CONSTANT. +#include +#include +#include // openmode, streamsize. +#include + +// Must come last. +#include // 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::allocator_type + #else + std::allocator + #endif + > +class basic_line_filter { +private: + typedef typename std::basic_string::traits_type string_traits; +public: + typedef Ch char_type; + typedef char_traits 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 + 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 + 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(cur - s); + } else { + cur_line_.append(cur, rest); + return n; + } + } + } + + typedef basic_line_filter self; + friend struct detail::closer; + + template + 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 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(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 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 + bool write_line(Sink& snk) + { + string_type line = do_filter(cur_line_) + traits_type::newline(); + std::streamsize amt = static_cast(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 line_filter; +typedef basic_line_filter wline_filter; + +} } // End namespaces iostreams, boost. + +#include + +#endif // #ifndef BOOST_IOSTREAMS_LINE_FILTER_HPP_INCLUDED diff --git a/include/boost/iostreams/filter/regex.hpp b/include/boost/iostreams/filter/regex.hpp new file mode 100755 index 0000000..f904493 --- /dev/null +++ b/include/boost/iostreams/filter/regex.hpp @@ -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 // allocator. +#include +#include +#include +#include + +namespace boost { namespace iostreams { + +template< typename Ch, + typename Tr = regex_traits, + typename Alloc = std::allocator > +class basic_regex_filter : public aggregate_filter { +private: + typedef aggregate_filter base_type; +public: + typedef typename base_type::char_type char_type; + typedef typename base_type::category category; + typedef std::basic_string string_type; + typedef basic_regex regex_type; + typedef regex_constants::match_flag_type flag_type; + typedef match_results match_type; + typedef function1 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 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 regex_filter; +typedef basic_regex_filter wregex_filter; + + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_REGEX_FILTER_HPP_INCLUDED diff --git a/include/boost/iostreams/filter/stdio.hpp b/include/boost/iostreams/filter/stdio.hpp new file mode 100755 index 0000000..5bd1466 --- /dev/null +++ b/include/boost/iostreams/filter/stdio.hpp @@ -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 +#include // allocator. +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace iostreams { + +namespace detail { + +} // End namespace detail. + +template > +class basic_stdio_filter : public aggregate_filter { +private: + typedef aggregate_filter 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 > + srcbuf(&src[0], &src[0] + src.size()); + stream_buffer< back_insert_device > + 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 stdio_filter; +typedef basic_stdio_filter wstdio_wfilter; + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_STDIO_FILTER_HPP_INCLUDED