Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 09:44:30

0001 // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
0002 // (C) Copyright 2003-2007 Jonathan Turkanis
0003 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
0005 
0006 // See http://www.boost.org/libs/iostreams for documentation.
0007 
0008 #ifndef BOOST_IOSTREAMS_AGGREGATE_FILTER_HPP_INCLUDED
0009 #define BOOST_IOSTREAMS_AGGREGATE_FILTER_HPP_INCLUDED
0010 
0011 #if defined(_MSC_VER)
0012 # pragma once
0013 #endif              
0014 
0015 #include <algorithm>                          // copy, min.
0016 #include <boost/assert.hpp>
0017 #include <iterator>                           // back_inserter
0018 #include <vector>
0019 #include <boost/iostreams/constants.hpp>      // default_device_buffer_size 
0020 #include <boost/iostreams/categories.hpp>
0021 #include <boost/iostreams/detail/char_traits.hpp>
0022 #include <boost/iostreams/detail/ios.hpp>     // openmode, streamsize.
0023 #include <boost/iostreams/pipeline.hpp>
0024 #include <boost/iostreams/read.hpp>           // check_eof 
0025 #include <boost/iostreams/write.hpp>
0026 #include <boost/mpl/bool.hpp>
0027 #include <boost/type_traits/is_convertible.hpp>
0028 
0029 // Must come last.
0030 #include <boost/iostreams/detail/config/disable_warnings.hpp>  // MSVC.
0031 
0032 namespace boost { namespace iostreams {
0033 
0034 //
0035 // Template name: aggregate_filter.
0036 // Template parameters:
0037 //      Ch - The character type.
0038 //      Alloc - The allocator type.
0039 // Description: Utility for defining DualUseFilters which filter an
0040 //      entire stream at once. To use, override the protected virtual
0041 //      member do_filter.
0042 // Note: This filter should not be copied while it is in use.
0043 //
0044 template<typename Ch, typename Alloc = std::allocator<Ch> >
0045 class aggregate_filter  {
0046 public:
0047     typedef Ch char_type;
0048     struct category
0049         : dual_use,
0050           filter_tag,
0051           multichar_tag,
0052           closable_tag
0053         { };
0054     aggregate_filter() : ptr_(0), state_(0) { }
0055     virtual ~aggregate_filter() { }
0056 
0057     template<typename Source>
0058     std::streamsize read(Source& src, char_type* s, std::streamsize n)
0059     {
0060         using namespace std;
0061         BOOST_ASSERT(!(state_ & f_write));
0062         state_ |= f_read;
0063         if (!(state_ & f_eof))
0064             do_read(src);
0065         std::streamsize amt =
0066             (std::min)(n, static_cast<std::streamsize>(data_.size() - ptr_));
0067         if (amt) {
0068             BOOST_IOSTREAMS_CHAR_TRAITS(char_type)::copy(s, &data_[ptr_], amt);
0069             ptr_ += amt;
0070         }
0071         return detail::check_eof(amt);
0072     }
0073 
0074     template<typename Sink>
0075     std::streamsize write(Sink&, const char_type* s, std::streamsize n)
0076     {
0077         BOOST_ASSERT(!(state_ & f_read));
0078         state_ |= f_write;
0079         data_.insert(data_.end(), s, s + n);
0080         return n;
0081     }
0082 
0083     template<typename Sink>
0084     void close(Sink& sink, BOOST_IOS::openmode which)
0085     {
0086         if ((state_ & f_read) != 0 && which == BOOST_IOS::in)
0087             close_impl();
0088         if ((state_ & f_write) != 0 && which == BOOST_IOS::out) {
0089             try {
0090                 vector_type filtered;
0091                 do_filter(data_, filtered);
0092                 do_write( 
0093                     sink, &filtered[0],
0094                     static_cast<std::streamsize>(filtered.size())
0095                 );
0096             } catch (...) {
0097                 close_impl();
0098                 throw;
0099             }
0100             close_impl();
0101         }
0102     }
0103 
0104 protected:
0105     typedef std::vector<Ch, Alloc>           vector_type;
0106     typedef typename vector_type::size_type  size_type;
0107 private:
0108     virtual void do_filter(const vector_type& src, vector_type& dest) = 0;
0109     virtual void do_close() { }
0110 
0111     template<typename Source>
0112     void do_read(Source& src)
0113     {
0114         using std::streamsize;
0115         vector_type data;
0116         while (true) {
0117             const std::streamsize  size = default_device_buffer_size;
0118             Ch                     buf[size];
0119             std::streamsize        amt;
0120             if ((amt = boost::iostreams::read(src, buf, size)) == -1)
0121                 break;
0122             data.insert(data.end(), buf, buf + amt);
0123         }
0124         do_filter(data, data_);
0125         state_ |= f_eof;
0126     }
0127 
0128     template<typename Sink>
0129     void do_write(Sink& sink, const char_type* s, std::streamsize n) 
0130     { 
0131         typedef typename iostreams::category_of<Sink>::type  category;
0132         typedef is_convertible<category, output>             can_write;
0133         do_write(sink, s, n, can_write()); 
0134     }
0135 
0136     template<typename Sink>
0137     void do_write(Sink& sink, const char_type* s, std::streamsize n, mpl::true_) 
0138     { iostreams::write(sink, s, n); }
0139 
0140     template<typename Sink>
0141     void do_write(Sink&, const char_type*, std::streamsize, mpl::false_) { }
0142 
0143     void close_impl()
0144     {
0145         data_.clear();
0146         ptr_ = 0;
0147         state_ = 0;
0148         do_close();
0149     }
0150 
0151     enum flag_type {
0152         f_read   = 1,
0153         f_write  = f_read << 1,
0154         f_eof    = f_write << 1
0155     };
0156 
0157     // Note: typically will not be copied while vector contains data.
0158     vector_type  data_;
0159     size_type    ptr_;
0160     int          state_;
0161 };
0162 BOOST_IOSTREAMS_PIPABLE(aggregate_filter, 1)
0163 
0164 } } // End namespaces iostreams, boost.
0165 
0166 #include <boost/iostreams/detail/config/enable_warnings.hpp>  // MSVC.
0167 
0168 #endif // #ifndef BOOST_IOSTREAMS_AGGREGATE_FILTER_HPP_INCLUDED