aggregate.hpp

来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 169 行

HPP
169
字号
// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)// (C) Copyright 2003-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.#ifndef BOOST_IOSTREAMS_AGGREGATE_FILTER_HPP_INCLUDED#define BOOST_IOSTREAMS_AGGREGATE_FILTER_HPP_INCLUDED#if defined(_MSC_VER) && (_MSC_VER >= 1020)# pragma once#endif              #include <algorithm>                          // copy, min.#include <cassert>#include <iterator>                           // back_inserter#include <vector>#include <boost/iostreams/constants.hpp>      // default_device_buffer_size #include <boost/iostreams/categories.hpp>#include <boost/iostreams/detail/char_traits.hpp>#include <boost/iostreams/detail/ios.hpp>     // openmode, streamsize.#include <boost/iostreams/pipeline.hpp>#include <boost/iostreams/read.hpp>           // check_eof #include <boost/iostreams/write.hpp>#include <boost/mpl/bool.hpp>#include <boost/type_traits/is_convertible.hpp>// Must come last.#include <boost/iostreams/detail/config/disable_warnings.hpp>  // MSVC.namespace boost { namespace iostreams {//// Template name: aggregate_filter.// Template paramters://      Ch - The character type.//      Alloc - The allocator type.// Description: Utility for defining DualUseFilters which filter an//      entire stream at once. To use, override the protected virtual//      member do_filter.// Note: This filter should not be copied while it is in use.//template<typename Ch, typename Alloc = std::allocator<Ch> >class aggregate_filter  {public:    typedef Ch char_type;    struct category        : dual_use,          filter_tag,          multichar_tag,          closable_tag        { };    aggregate_filter() : ptr_(0), state_(0) { }    virtual ~aggregate_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;        if (!(state_ & f_eof))            do_read(src);        std::streamsize amt =            (std::min)(n, static_cast<std::streamsize>(data_.size() - ptr_));        if (amt) {            BOOST_IOSTREAMS_CHAR_TRAITS(char_type)::copy(s, &data_[ptr_], amt);            ptr_ += amt;        }        return detail::check_eof(amt);    }    template<typename Sink>    std::streamsize write(Sink&, const char_type* s, std::streamsize n)    {        assert(!(state_ & f_read));        state_ |= f_write;        data_.insert(data_.end(), s, s + n);        return n;    }    template<typename Sink>    void close(Sink& sink, BOOST_IOS::openmode which)    {        if ((state_ & f_read) != 0 && which == BOOST_IOS::in)            close_impl();        if ((state_ & f_write) != 0 && which == BOOST_IOS::out) {            try {                vector_type filtered;                do_filter(data_, filtered);                do_write(                     sink, &filtered[0],                    static_cast<std::streamsize>(filtered.size())                );            } catch (...) {                close_impl();                throw;            }            close_impl();        }    }protected:    typedef std::vector<Ch, Alloc>           vector_type;    typedef typename vector_type::size_type  size_type;private:    virtual void do_filter(const vector_type& src, vector_type& dest) = 0;    virtual void do_close() { }    template<typename Source>    void do_read(Source& src)    {        using std::streamsize;        vector_type data;        while (true) {            const std::streamsize  size = default_device_buffer_size;            Ch                     buf[size];            std::streamsize        amt;            if ((amt = boost::iostreams::read(src, buf, size)) == -1)                break;            data.insert(data.end(), buf, buf + amt);        }        do_filter(data, data_);        state_ |= f_eof;    }    template<typename Sink>    void do_write(Sink& sink, const char* s, std::streamsize n)     {         typedef typename iostreams::category_of<Sink>::type  category;        typedef is_convertible<category, output>             can_write;        do_write(sink, s, n, can_write());     }    template<typename Sink>    void do_write(Sink& sink, const char* s, std::streamsize n, mpl::true_)     { iostreams::write(sink, s, n); }    template<typename Sink>    void do_write(Sink&, const char*, std::streamsize, mpl::false_) { }    void close_impl()    {        data_.clear();        ptr_ = 0;        state_ = 0;        do_close();    }    enum flag_type {        f_read   = 1,        f_write  = f_read << 1,        f_eof    = f_write << 1    };    // Note: typically will not be copied while vector contains data.    vector_type  data_;    size_type    ptr_;    int          state_;};BOOST_IOSTREAMS_PIPABLE(aggregate_filter, 1)} } // End namespaces iostreams, boost.#include <boost/iostreams/detail/config/enable_warnings.hpp>  // MSVC.#endif // #ifndef BOOST_IOSTREAMS_AGGREGATE_FILTER_HPP_INCLUDED

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?