Back to home page

EIC code displayed by LXR

 
 

    


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

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_INVERT_HPP_INCLUDED
0009 #define BOOST_IOSTREAMS_INVERT_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 <boost/config.hpp>                      // BOOST_DEDUCED_TYPENAME.       
0018 #include <boost/detail/workaround.hpp>           // default_filter_buffer_size.
0019 #include <boost/iostreams/char_traits.hpp>
0020 #include <boost/iostreams/compose.hpp>
0021 #include <boost/iostreams/constants.hpp>
0022 #include <boost/iostreams/device/array.hpp>
0023 #include <boost/iostreams/detail/buffer.hpp>
0024 #include <boost/iostreams/detail/counted_array.hpp>
0025 #include <boost/iostreams/detail/execute.hpp>
0026 #include <boost/iostreams/detail/functional.hpp> // clear_flags, call_reset
0027 #include <boost/mpl/if.hpp>
0028 #include <boost/ref.hpp>
0029 #include <boost/shared_ptr.hpp>
0030 #include <boost/type_traits/is_convertible.hpp>
0031 
0032 // Must come last.
0033 #include <boost/iostreams/detail/config/disable_warnings.hpp>  // MSVC.
0034 
0035 namespace boost { namespace iostreams {
0036 
0037 //
0038 // Template name: inverse.
0039 // Template parameters:
0040 //      Filter - A model of InputFilter or OutputFilter.
0041 // Description: Generates an InputFilter from an OutputFilter or
0042 //      vice versa.
0043 //
0044 template<typename Filter>
0045 class inverse {
0046 private:
0047     BOOST_STATIC_ASSERT(is_filter<Filter>::value);
0048     typedef typename category_of<Filter>::type   base_category;
0049     typedef reference_wrapper<Filter>            filter_ref;
0050 public:
0051     typedef typename char_type_of<Filter>::type  char_type;
0052     typedef typename int_type_of<Filter>::type   int_type;
0053     typedef char_traits<char_type>               traits_type;
0054     typedef typename 
0055             mpl::if_<
0056                 is_convertible<
0057                     base_category,
0058                     input
0059                 >,
0060                 output,
0061                 input
0062             >::type                              mode;
0063     struct category 
0064         : mode, 
0065           filter_tag, 
0066           multichar_tag, 
0067           closable_tag 
0068         { };
0069     explicit inverse( const Filter& filter, 
0070                       std::streamsize buffer_size = 
0071                           default_filter_buffer_size) 
0072         : pimpl_(new impl(filter, buffer_size))
0073         { }
0074 
0075     template<typename Source>
0076     std::streamsize read(Source& src, char_type* s, std::streamsize n)
0077     {
0078         typedef detail::counted_array_sink<char_type>  array_sink;
0079         typedef composite<filter_ref, array_sink>      filtered_array_sink;
0080 
0081         BOOST_ASSERT((flags() & f_write) == 0);
0082         if (flags() == 0) {
0083             flags() = f_read;
0084             buf().set(0, 0);
0085         }
0086 
0087         filtered_array_sink snk(filter(), array_sink(s, n));
0088         int_type status;
0089         for ( status = traits_type::good();
0090               snk.second().count() < n && status == traits_type::good(); )
0091         {
0092             status = buf().fill(src);
0093             buf().flush(snk);
0094         }
0095         return snk.second().count() == 0 &&
0096                status == traits_type::eof() 
0097                    ? 
0098                -1
0099                    : 
0100                snk.second().count();
0101     }
0102 
0103     template<typename Sink>
0104     std::streamsize write(Sink& dest, const char_type* s, std::streamsize n)
0105     {
0106         typedef detail::counted_array_source<char_type>  array_source;
0107         typedef composite<filter_ref, array_source>      filtered_array_source;
0108 
0109         BOOST_ASSERT((flags() & f_read) == 0);
0110         if (flags() == 0) {
0111             flags() = f_write;
0112             buf().set(0, 0);
0113         }
0114         
0115         filtered_array_source src(filter(), array_source(s, n));
0116         for (bool good = true; src.second().count() < n && good; ) {
0117             buf().fill(src);
0118             good = buf().flush(dest);
0119         }
0120         return src.second().count();
0121     }
0122 
0123     template<typename Device>
0124     void close(Device& dev)
0125     {
0126         detail::execute_all(
0127             detail::flush_buffer(buf(), dev, (flags() & f_write) != 0),
0128             detail::call_close_all(pimpl_->filter_, dev),
0129             detail::clear_flags(flags())
0130         );
0131     }
0132 private:
0133     filter_ref filter() { return boost::ref(pimpl_->filter_); }
0134     detail::buffer<char_type>& buf() { return pimpl_->buf_; }
0135     int& flags() { return pimpl_->flags_; }
0136     
0137     enum flags_ {
0138         f_read = 1, f_write = 2
0139     };
0140 
0141     struct impl {
0142         impl(const Filter& filter, std::streamsize n) 
0143             : filter_(filter), buf_(n), flags_(0)
0144         { buf_.set(0, 0); }
0145         Filter                     filter_;
0146         detail::buffer<char_type>  buf_;
0147         int                        flags_;
0148     };
0149     shared_ptr<impl> pimpl_;
0150 };
0151 
0152 //
0153 // Template name: invert.
0154 // Template parameters:
0155 //      Filter - A model of InputFilter or OutputFilter.
0156 // Description: Returns an instance of an appropriate specialization of inverse.
0157 //
0158 template<typename Filter>
0159 inverse<Filter> invert(const Filter& f) { return inverse<Filter>(f); }
0160                     
0161 //----------------------------------------------------------------------------//
0162 
0163 } } // End namespaces iostreams, boost.
0164 
0165 #include <boost/iostreams/detail/config/enable_warnings.hpp>  // MSVC.
0166 
0167 #endif // #ifndef BOOST_IOSTREAMS_INVERT_HPP_INCLUDED