PageRenderTime 31ms CodeModel.GetById 18ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/iostreams/filter/aggregate.hpp

http://hadesmem.googlecode.com/
C++ Header | 168 lines | 130 code | 21 blank | 17 comment | 14 complexity | 2299768dc723311f5de363d9812a0002 MD5 | raw file
  1// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
  2// (C) Copyright 2003-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#ifndef BOOST_IOSTREAMS_AGGREGATE_FILTER_HPP_INCLUDED
  9#define BOOST_IOSTREAMS_AGGREGATE_FILTER_HPP_INCLUDED
 10
 11#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 12# pragma once
 13#endif              
 14
 15#include <algorithm>                          // copy, min.
 16#include <boost/assert.hpp>
 17#include <iterator>                           // back_inserter
 18#include <vector>
 19#include <boost/iostreams/constants.hpp>      // default_device_buffer_size 
 20#include <boost/iostreams/categories.hpp>
 21#include <boost/iostreams/detail/char_traits.hpp>
 22#include <boost/iostreams/detail/ios.hpp>     // openmode, streamsize.
 23#include <boost/iostreams/pipeline.hpp>
 24#include <boost/iostreams/read.hpp>           // check_eof 
 25#include <boost/iostreams/write.hpp>
 26#include <boost/mpl/bool.hpp>
 27#include <boost/type_traits/is_convertible.hpp>
 28
 29// Must come last.
 30#include <boost/iostreams/detail/config/disable_warnings.hpp>  // MSVC.
 31
 32namespace boost { namespace iostreams {
 33
 34//
 35// Template name: aggregate_filter.
 36// Template paramters:
 37//      Ch - The character type.
 38//      Alloc - The allocator type.
 39// Description: Utility for defining DualUseFilters which filter an
 40//      entire stream at once. To use, override the protected virtual
 41//      member do_filter.
 42// Note: This filter should not be copied while it is in use.
 43//
 44template<typename Ch, typename Alloc = std::allocator<Ch> >
 45class aggregate_filter  {
 46public:
 47    typedef Ch char_type;
 48    struct category
 49        : dual_use,
 50          filter_tag,
 51          multichar_tag,
 52          closable_tag
 53        { };
 54    aggregate_filter() : ptr_(0), state_(0) { }
 55    virtual ~aggregate_filter() { }
 56
 57    template<typename Source>
 58    std::streamsize read(Source& src, char_type* s, std::streamsize n)
 59    {
 60        using namespace std;
 61        BOOST_ASSERT(!(state_ & f_write));
 62        state_ |= f_read;
 63        if (!(state_ & f_eof))
 64            do_read(src);
 65        std::streamsize amt =
 66            (std::min)(n, static_cast<std::streamsize>(data_.size() - ptr_));
 67        if (amt) {
 68            BOOST_IOSTREAMS_CHAR_TRAITS(char_type)::copy(s, &data_[ptr_], amt);
 69            ptr_ += amt;
 70        }
 71        return detail::check_eof(amt);
 72    }
 73
 74    template<typename Sink>
 75    std::streamsize write(Sink&, const char_type* s, std::streamsize n)
 76    {
 77        BOOST_ASSERT(!(state_ & f_read));
 78        state_ |= f_write;
 79        data_.insert(data_.end(), s, s + n);
 80        return n;
 81    }
 82
 83    template<typename Sink>
 84    void close(Sink& sink, BOOST_IOS::openmode which)
 85    {
 86        if ((state_ & f_read) != 0 && which == BOOST_IOS::in)
 87            close_impl();
 88        if ((state_ & f_write) != 0 && which == BOOST_IOS::out) {
 89            try {
 90                vector_type filtered;
 91                do_filter(data_, filtered);
 92                do_write( 
 93                    sink, &filtered[0],
 94                    static_cast<std::streamsize>(filtered.size())
 95                );
 96            } catch (...) {
 97                close_impl();
 98                throw;
 99            }
100            close_impl();
101        }
102    }
103
104protected:
105    typedef std::vector<Ch, Alloc>           vector_type;
106    typedef typename vector_type::size_type  size_type;
107private:
108    virtual void do_filter(const vector_type& src, vector_type& dest) = 0;
109    virtual void do_close() { }
110
111    template<typename Source>
112    void do_read(Source& src)
113    {
114        using std::streamsize;
115        vector_type data;
116        while (true) {
117            const std::streamsize  size = default_device_buffer_size;
118            Ch                     buf[size];
119            std::streamsize        amt;
120            if ((amt = boost::iostreams::read(src, buf, size)) == -1)
121                break;
122            data.insert(data.end(), buf, buf + amt);
123        }
124        do_filter(data, data_);
125        state_ |= f_eof;
126    }
127
128    template<typename Sink>
129    void do_write(Sink& sink, const char_type* s, std::streamsize n) 
130    { 
131        typedef typename iostreams::category_of<Sink>::type  category;
132        typedef is_convertible<category, output>             can_write;
133        do_write(sink, s, n, can_write()); 
134    }
135
136    template<typename Sink>
137    void do_write(Sink& sink, const char_type* s, std::streamsize n, mpl::true_) 
138    { iostreams::write(sink, s, n); }
139
140    template<typename Sink>
141    void do_write(Sink&, const char_type*, std::streamsize, mpl::false_) { }
142
143    void close_impl()
144    {
145        data_.clear();
146        ptr_ = 0;
147        state_ = 0;
148        do_close();
149    }
150
151    enum flag_type {
152        f_read   = 1,
153        f_write  = f_read << 1,
154        f_eof    = f_write << 1
155    };
156
157    // Note: typically will not be copied while vector contains data.
158    vector_type  data_;
159    size_type    ptr_;
160    int          state_;
161};
162BOOST_IOSTREAMS_PIPABLE(aggregate_filter, 1)
163
164} } // End namespaces iostreams, boost.
165
166#include <boost/iostreams/detail/config/enable_warnings.hpp>  // MSVC.
167
168#endif // #ifndef BOOST_IOSTREAMS_AGGREGATE_FILTER_HPP_INCLUDED