Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:53

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 // Contains: The function template copy, which reads data from a Source 
0009 // and writes it to a Sink until the end of the sequence is reached, returning 
0010 // the number of characters transfered.
0011 
0012 // The implementation is complicated by the need to handle smart adapters
0013 // and direct devices.
0014 
0015 #ifndef BOOST_IOSTREAMS_COPY_HPP_INCLUDED
0016 #define BOOST_IOSTREAMS_COPY_HPP_INCLUDED
0017 
0018 #if defined(_MSC_VER)
0019 # pragma once
0020 #endif              
0021 
0022 #include <boost/config.hpp>                 // Make sure ptrdiff_t is in std.
0023 #include <algorithm>                        // copy, min.
0024 #include <cstddef>                          // ptrdiff_t.
0025 #include <utility>                          // pair.
0026 
0027 #include <boost/detail/workaround.hpp>
0028 #include <boost/iostreams/chain.hpp>
0029 #include <boost/iostreams/constants.hpp>
0030 #include <boost/iostreams/detail/adapter/non_blocking_adapter.hpp>        
0031 #include <boost/iostreams/detail/buffer.hpp>
0032 #include <boost/iostreams/detail/enable_if_stream.hpp>  
0033 #include <boost/iostreams/detail/execute.hpp>
0034 #include <boost/iostreams/detail/functional.hpp>
0035 #include <boost/iostreams/detail/ios.hpp>   // failure, streamsize.                   
0036 #include <boost/iostreams/detail/resolve.hpp>                   
0037 #include <boost/iostreams/detail/wrap_unwrap.hpp>
0038 #include <boost/iostreams/operations.hpp>  // read, write, close.
0039 #include <boost/iostreams/pipeline.hpp>
0040 #include <boost/static_assert.hpp>  
0041 #include <boost/type_traits/is_same.hpp> 
0042 
0043 namespace boost { namespace iostreams {
0044 
0045 namespace detail {
0046 
0047     // The following four overloads of copy_impl() optimize 
0048     // copying in the case that one or both of the two devices
0049     // models Direct (see 
0050     // http://www.boost.org/libs/iostreams/doc/index.html?path=4.1.1.4)
0051 
0052 // Copy from a direct source to a direct sink
0053 template<typename Source, typename Sink>
0054 std::streamsize copy_impl( Source& src, Sink& snk, 
0055                            std::streamsize /* buffer_size */,
0056                            mpl::true_, mpl::true_ )
0057 {   
0058     using namespace std;
0059     typedef typename char_type_of<Source>::type  char_type;
0060     typedef std::pair<char_type*, char_type*>    pair_type;
0061     pair_type p1 = iostreams::input_sequence(src);
0062     pair_type p2 = iostreams::output_sequence(snk);
0063     std::streamsize total = 
0064         static_cast<std::streamsize>(
0065             (std::min)(p1.second - p1.first, p2.second - p2.first)
0066         );
0067     std::copy(p1.first, p1.first + total, p2.first);
0068     return total;
0069 }
0070 
0071 // Copy from a direct source to an indirect sink
0072 template<typename Source, typename Sink>
0073 std::streamsize copy_impl( Source& src, Sink& snk, 
0074                            std::streamsize /* buffer_size */,
0075                            mpl::true_, mpl::false_ )
0076 {
0077     using namespace std;
0078     typedef typename char_type_of<Source>::type  char_type;
0079     typedef std::pair<char_type*, char_type*>    pair_type;
0080     pair_type p = iostreams::input_sequence(src);
0081     std::streamsize size, total;
0082     for ( total = 0, size = static_cast<std::streamsize>(p.second - p.first);
0083           total < size; )
0084     {
0085         std::streamsize amt = 
0086             iostreams::write(snk, p.first + total, size - total); 
0087         total += amt;
0088     }
0089     return total;
0090 }
0091 
0092 // Copy from an indirect source to a direct sink
0093 template<typename Source, typename Sink>
0094 std::streamsize copy_impl( Source& src, Sink& snk, 
0095                            std::streamsize buffer_size,
0096                            mpl::false_, mpl::true_ )
0097 {
0098     typedef typename char_type_of<Source>::type  char_type;
0099     typedef std::pair<char_type*, char_type*>    pair_type;
0100     detail::basic_buffer<char_type>  buf(buffer_size);
0101     pair_type                        p = snk.output_sequence();
0102     std::streamsize                  total = 0;
0103     std::ptrdiff_t                   capacity = p.second - p.first;
0104     while (true) {
0105         std::streamsize amt = 
0106             iostreams::read(
0107                 src, 
0108                 buf.data(),
0109                 buffer_size < capacity - total ?
0110                     buffer_size :
0111                     static_cast<std::streamsize>(capacity - total)
0112             );
0113         if (amt == -1)
0114             break;
0115         std::copy(buf.data(), buf.data() + amt, p.first + total);
0116         total += amt;
0117     }
0118     return total;
0119 }
0120 
0121 // Copy from an indirect source to an indirect sink
0122 template<typename Source, typename Sink>
0123 std::streamsize copy_impl( Source& src, Sink& snk, 
0124                            std::streamsize buffer_size,
0125                            mpl::false_, mpl::false_ )
0126 { 
0127     typedef typename char_type_of<Source>::type char_type;
0128     detail::basic_buffer<char_type>  buf(buffer_size);
0129     non_blocking_adapter<Sink>       nb(snk);
0130     std::streamsize                  total = 0;
0131     bool                             done = false;
0132     while (!done) {
0133         std::streamsize amt;
0134         done = (amt = iostreams::read(src, buf.data(), buffer_size)) == -1;
0135         if (amt != -1) {
0136             iostreams::write(nb, buf.data(), amt);
0137             total += amt;
0138         }
0139     }
0140     return total;
0141 }
0142 
0143     // The following function object is used with 
0144     // boost::iostreams::detail::execute() in the primary 
0145     // overload of copy_impl(), below
0146 
0147 // Function object that delegates to one of the above four 
0148 // overloads of compl_impl()
0149 template<typename Source, typename Sink>
0150 class copy_operation {
0151 public:
0152     typedef std::streamsize result_type;
0153     copy_operation(Source& src, Sink& snk, std::streamsize buffer_size)
0154         : src_(src), snk_(snk), buffer_size_(buffer_size)
0155         { }
0156     std::streamsize operator()() 
0157     {
0158         return copy_impl( src_, snk_, buffer_size_, 
0159                           is_direct<Source>(), is_direct<Sink>() );
0160     }
0161 private:
0162     copy_operation& operator=(const copy_operation&);
0163     Source&          src_;
0164     Sink&            snk_;
0165     std::streamsize  buffer_size_;
0166 };
0167 
0168 // Primary overload of copy_impl. Delegates to one of the above four 
0169 // overloads of compl_impl(), depending on which of the two given 
0170 // devices, if any, models Direct (see 
0171 // http://www.boost.org/libs/iostreams/doc/index.html?path=4.1.1.4)
0172 template<typename Source, typename Sink>
0173 std::streamsize copy_impl(Source src, Sink snk, std::streamsize buffer_size)
0174 {
0175     using namespace std;
0176     typedef typename char_type_of<Source>::type  src_char;
0177     typedef typename char_type_of<Sink>::type    snk_char;
0178     BOOST_STATIC_ASSERT((is_same<src_char, snk_char>::value));
0179     return detail::execute_all(
0180                copy_operation<Source, Sink>(src, snk, buffer_size),
0181                detail::call_close_all(src),
0182                detail::call_close_all(snk)
0183            );
0184 }
0185 
0186 } // End namespace detail.
0187                     
0188 //------------------Definition of copy----------------------------------------//
0189 
0190 // Overload of copy() for the case where neither the source nor the sink is
0191 // a standard stream or stream buffer
0192 template<typename Source, typename Sink>
0193 std::streamsize
0194 copy( const Source& src, const Sink& snk,
0195       std::streamsize buffer_size = default_device_buffer_size
0196       BOOST_IOSTREAMS_DISABLE_IF_STREAM(Source)
0197       BOOST_IOSTREAMS_DISABLE_IF_STREAM(Sink) )
0198 { 
0199     typedef typename char_type_of<Source>::type char_type;
0200     return detail::copy_impl( detail::resolve<input, char_type>(src), 
0201                               detail::resolve<output, char_type>(snk), 
0202                               buffer_size ); 
0203 }
0204 
0205 // Overload of copy() for the case where the source, but not the sink, is
0206 // a standard stream or stream buffer
0207 template<typename Source, typename Sink>
0208 std::streamsize
0209 copy( Source& src, const Sink& snk,
0210       std::streamsize buffer_size = default_device_buffer_size
0211       BOOST_IOSTREAMS_ENABLE_IF_STREAM(Source)
0212       BOOST_IOSTREAMS_DISABLE_IF_STREAM(Sink) ) 
0213 { 
0214     typedef typename char_type_of<Source>::type char_type;
0215     return detail::copy_impl( detail::wrap(src), 
0216                               detail::resolve<output, char_type>(snk), 
0217                               buffer_size );
0218 }
0219 
0220 // Overload of copy() for the case where the sink, but not the source, is
0221 // a standard stream or stream buffer
0222 template<typename Source, typename Sink>
0223 std::streamsize
0224 copy( const Source& src, Sink& snk,
0225       std::streamsize buffer_size = default_device_buffer_size
0226       BOOST_IOSTREAMS_DISABLE_IF_STREAM(Source)
0227       BOOST_IOSTREAMS_ENABLE_IF_STREAM(Sink) ) 
0228 { 
0229     typedef typename char_type_of<Source>::type char_type;
0230     return detail::copy_impl( detail::resolve<input, char_type>(src), 
0231                               detail::wrap(snk), buffer_size );
0232 }
0233 
0234 // Overload of copy() for the case where neither the source nor the sink is
0235 // a standard stream or stream buffer
0236 template<typename Source, typename Sink>
0237 std::streamsize
0238 copy( Source& src, Sink& snk,
0239       std::streamsize buffer_size = default_device_buffer_size
0240       BOOST_IOSTREAMS_ENABLE_IF_STREAM(Source)
0241       BOOST_IOSTREAMS_ENABLE_IF_STREAM(Sink) ) 
0242 { 
0243     return detail::copy_impl(detail::wrap(src), detail::wrap(snk), buffer_size);
0244 }
0245 
0246 } } // End namespaces iostreams, boost.
0247 
0248 #endif // #ifndef BOOST_IOSTREAMS_COPY_HPP_INCLUDED