annotate DEPENDENCIES/generic/include/boost/iostreams/copy.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
Chris@16 2 // (C) Copyright 2003-2007 Jonathan Turkanis
Chris@16 3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
Chris@16 4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
Chris@16 5
Chris@16 6 // See http://www.boost.org/libs/iostreams for documentation.
Chris@16 7
Chris@16 8 // Contains: The function template copy, which reads data from a Source
Chris@16 9 // and writes it to a Sink until the end of the sequence is reached, returning
Chris@16 10 // the number of characters transfered.
Chris@16 11
Chris@16 12 // The implementation is complicated by the need to handle smart adapters
Chris@16 13 // and direct devices.
Chris@16 14
Chris@16 15 #ifndef BOOST_IOSTREAMS_COPY_HPP_INCLUDED
Chris@16 16 #define BOOST_IOSTREAMS_COPY_HPP_INCLUDED
Chris@16 17
Chris@16 18 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
Chris@16 19 # pragma once
Chris@16 20 #endif
Chris@16 21
Chris@16 22 #include <boost/config.hpp> // Make sure ptrdiff_t is in std.
Chris@16 23 #include <algorithm> // copy, min.
Chris@16 24 #include <cstddef> // ptrdiff_t.
Chris@16 25 #include <utility> // pair.
Chris@16 26 #include <boost/bind.hpp>
Chris@16 27 #include <boost/detail/workaround.hpp>
Chris@16 28 #include <boost/iostreams/chain.hpp>
Chris@16 29 #include <boost/iostreams/constants.hpp>
Chris@16 30 #include <boost/iostreams/detail/adapter/non_blocking_adapter.hpp>
Chris@16 31 #include <boost/iostreams/detail/buffer.hpp>
Chris@16 32 #include <boost/iostreams/detail/enable_if_stream.hpp>
Chris@16 33 #include <boost/iostreams/detail/execute.hpp>
Chris@16 34 #include <boost/iostreams/detail/functional.hpp>
Chris@16 35 #include <boost/iostreams/detail/ios.hpp> // failure, streamsize.
Chris@16 36 #include <boost/iostreams/detail/resolve.hpp>
Chris@16 37 #include <boost/iostreams/detail/wrap_unwrap.hpp>
Chris@16 38 #include <boost/iostreams/operations.hpp> // read, write, close.
Chris@16 39 #include <boost/iostreams/pipeline.hpp>
Chris@16 40 #include <boost/static_assert.hpp>
Chris@16 41 #include <boost/type_traits/is_same.hpp>
Chris@16 42
Chris@16 43 namespace boost { namespace iostreams {
Chris@16 44
Chris@16 45 namespace detail {
Chris@16 46
Chris@16 47 // The following four overloads of copy_impl() optimize
Chris@16 48 // copying in the case that one or both of the two devices
Chris@16 49 // models Direct (see
Chris@16 50 // http://www.boost.org/libs/iostreams/doc/index.html?path=4.1.1.4)
Chris@16 51
Chris@16 52 // Copy from a direct source to a direct sink
Chris@16 53 template<typename Source, typename Sink>
Chris@16 54 std::streamsize copy_impl( Source& src, Sink& snk,
Chris@16 55 std::streamsize /* buffer_size */,
Chris@16 56 mpl::true_, mpl::true_ )
Chris@16 57 {
Chris@16 58 using namespace std;
Chris@16 59 typedef typename char_type_of<Source>::type char_type;
Chris@16 60 typedef std::pair<char_type*, char_type*> pair_type;
Chris@16 61 pair_type p1 = iostreams::input_sequence(src);
Chris@16 62 pair_type p2 = iostreams::output_sequence(snk);
Chris@16 63 std::streamsize total =
Chris@16 64 static_cast<std::streamsize>(
Chris@16 65 (std::min)(p1.second - p1.first, p2.second - p2.first)
Chris@16 66 );
Chris@16 67 std::copy(p1.first, p1.first + total, p2.first);
Chris@16 68 return total;
Chris@16 69 }
Chris@16 70
Chris@16 71 // Copy from a direct source to an indirect sink
Chris@16 72 template<typename Source, typename Sink>
Chris@16 73 std::streamsize copy_impl( Source& src, Sink& snk,
Chris@16 74 std::streamsize /* buffer_size */,
Chris@16 75 mpl::true_, mpl::false_ )
Chris@16 76 {
Chris@16 77 using namespace std;
Chris@16 78 typedef typename char_type_of<Source>::type char_type;
Chris@16 79 typedef std::pair<char_type*, char_type*> pair_type;
Chris@16 80 pair_type p = iostreams::input_sequence(src);
Chris@16 81 std::streamsize size, total;
Chris@16 82 for ( total = 0, size = static_cast<std::streamsize>(p.second - p.first);
Chris@16 83 total < size; )
Chris@16 84 {
Chris@16 85 std::streamsize amt =
Chris@16 86 iostreams::write(snk, p.first + total, size - total);
Chris@16 87 total += amt;
Chris@16 88 }
Chris@16 89 return total;
Chris@16 90 }
Chris@16 91
Chris@16 92 // Copy from an indirect source to a direct sink
Chris@16 93 template<typename Source, typename Sink>
Chris@16 94 std::streamsize copy_impl( Source& src, Sink& snk,
Chris@16 95 std::streamsize buffer_size,
Chris@16 96 mpl::false_, mpl::true_ )
Chris@16 97 {
Chris@16 98 typedef typename char_type_of<Source>::type char_type;
Chris@16 99 typedef std::pair<char_type*, char_type*> pair_type;
Chris@16 100 detail::basic_buffer<char_type> buf(buffer_size);
Chris@16 101 pair_type p = snk.output_sequence();
Chris@16 102 std::streamsize total = 0;
Chris@16 103 std::ptrdiff_t capacity = p.second - p.first;
Chris@16 104 while (true) {
Chris@16 105 std::streamsize amt =
Chris@16 106 iostreams::read(
Chris@16 107 src,
Chris@16 108 buf.data(),
Chris@16 109 buffer_size < capacity - total ?
Chris@16 110 buffer_size :
Chris@16 111 static_cast<std::streamsize>(capacity - total)
Chris@16 112 );
Chris@16 113 if (amt == -1)
Chris@16 114 break;
Chris@16 115 std::copy(buf.data(), buf.data() + amt, p.first + total);
Chris@16 116 total += amt;
Chris@16 117 }
Chris@16 118 return total;
Chris@16 119 }
Chris@16 120
Chris@16 121 // Copy from an indirect source to an indirect sink
Chris@16 122 template<typename Source, typename Sink>
Chris@16 123 std::streamsize copy_impl( Source& src, Sink& snk,
Chris@16 124 std::streamsize buffer_size,
Chris@16 125 mpl::false_, mpl::false_ )
Chris@16 126 {
Chris@16 127 typedef typename char_type_of<Source>::type char_type;
Chris@16 128 detail::basic_buffer<char_type> buf(buffer_size);
Chris@16 129 non_blocking_adapter<Sink> nb(snk);
Chris@16 130 std::streamsize total = 0;
Chris@16 131 bool done = false;
Chris@16 132 while (!done) {
Chris@16 133 std::streamsize amt;
Chris@16 134 done = (amt = iostreams::read(src, buf.data(), buffer_size)) == -1;
Chris@16 135 if (amt != -1) {
Chris@16 136 iostreams::write(nb, buf.data(), amt);
Chris@16 137 total += amt;
Chris@16 138 }
Chris@16 139 }
Chris@16 140 return total;
Chris@16 141 }
Chris@16 142
Chris@16 143 // The following function object is used with
Chris@16 144 // boost::iostreams::detail::execute() in the primary
Chris@16 145 // overload of copy_impl(), below
Chris@16 146
Chris@16 147 // Function object that delegates to one of the above four
Chris@16 148 // overloads of compl_impl()
Chris@16 149 template<typename Source, typename Sink>
Chris@16 150 class copy_operation {
Chris@16 151 public:
Chris@16 152 typedef std::streamsize result_type;
Chris@16 153 copy_operation(Source& src, Sink& snk, std::streamsize buffer_size)
Chris@16 154 : src_(src), snk_(snk), buffer_size_(buffer_size)
Chris@16 155 { }
Chris@16 156 std::streamsize operator()()
Chris@16 157 {
Chris@16 158 return copy_impl( src_, snk_, buffer_size_,
Chris@16 159 is_direct<Source>(), is_direct<Sink>() );
Chris@16 160 }
Chris@16 161 private:
Chris@16 162 copy_operation& operator=(const copy_operation&);
Chris@16 163 Source& src_;
Chris@16 164 Sink& snk_;
Chris@16 165 std::streamsize buffer_size_;
Chris@16 166 };
Chris@16 167
Chris@16 168 // Primary overload of copy_impl. Delegates to one of the above four
Chris@16 169 // overloads of compl_impl(), depending on which of the two given
Chris@16 170 // devices, if any, models Direct (see
Chris@16 171 // http://www.boost.org/libs/iostreams/doc/index.html?path=4.1.1.4)
Chris@16 172 template<typename Source, typename Sink>
Chris@16 173 std::streamsize copy_impl(Source src, Sink snk, std::streamsize buffer_size)
Chris@16 174 {
Chris@16 175 using namespace std;
Chris@16 176 typedef typename char_type_of<Source>::type src_char;
Chris@16 177 typedef typename char_type_of<Sink>::type snk_char;
Chris@16 178 BOOST_STATIC_ASSERT((is_same<src_char, snk_char>::value));
Chris@16 179 return detail::execute_all(
Chris@16 180 copy_operation<Source, Sink>(src, snk, buffer_size),
Chris@16 181 detail::call_close_all(src),
Chris@16 182 detail::call_close_all(snk)
Chris@16 183 );
Chris@16 184 }
Chris@16 185
Chris@16 186 } // End namespace detail.
Chris@16 187
Chris@16 188 //------------------Definition of copy----------------------------------------//
Chris@16 189
Chris@16 190 // Overload of copy() for the case where neither the source nor the sink is
Chris@16 191 // a standard stream or stream buffer
Chris@16 192 template<typename Source, typename Sink>
Chris@16 193 std::streamsize
Chris@16 194 copy( const Source& src, const Sink& snk,
Chris@16 195 std::streamsize buffer_size = default_device_buffer_size
Chris@16 196 BOOST_IOSTREAMS_DISABLE_IF_STREAM(Source)
Chris@16 197 BOOST_IOSTREAMS_DISABLE_IF_STREAM(Sink) )
Chris@16 198 {
Chris@16 199 typedef typename char_type_of<Source>::type char_type;
Chris@16 200 return detail::copy_impl( detail::resolve<input, char_type>(src),
Chris@16 201 detail::resolve<output, char_type>(snk),
Chris@16 202 buffer_size );
Chris@16 203 }
Chris@16 204
Chris@16 205 #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------//
Chris@16 206
Chris@16 207 // Overload of copy() for the case where the source, but not the sink, is
Chris@16 208 // a standard stream or stream buffer
Chris@16 209 template<typename Source, typename Sink>
Chris@16 210 std::streamsize
Chris@16 211 copy( Source& src, const Sink& snk,
Chris@16 212 std::streamsize buffer_size = default_device_buffer_size
Chris@16 213 BOOST_IOSTREAMS_ENABLE_IF_STREAM(Source)
Chris@16 214 BOOST_IOSTREAMS_DISABLE_IF_STREAM(Sink) )
Chris@16 215 {
Chris@16 216 typedef typename char_type_of<Source>::type char_type;
Chris@16 217 return detail::copy_impl( detail::wrap(src),
Chris@16 218 detail::resolve<output, char_type>(snk),
Chris@16 219 buffer_size );
Chris@16 220 }
Chris@16 221
Chris@16 222 // Overload of copy() for the case where the sink, but not the source, is
Chris@16 223 // a standard stream or stream buffer
Chris@16 224 template<typename Source, typename Sink>
Chris@16 225 std::streamsize
Chris@16 226 copy( const Source& src, Sink& snk,
Chris@16 227 std::streamsize buffer_size = default_device_buffer_size
Chris@16 228 BOOST_IOSTREAMS_DISABLE_IF_STREAM(Source)
Chris@16 229 BOOST_IOSTREAMS_ENABLE_IF_STREAM(Sink) )
Chris@16 230 {
Chris@16 231 typedef typename char_type_of<Source>::type char_type;
Chris@16 232 return detail::copy_impl( detail::resolve<input, char_type>(src),
Chris@16 233 detail::wrap(snk), buffer_size );
Chris@16 234 }
Chris@16 235
Chris@16 236 // Overload of copy() for the case where neither the source nor the sink is
Chris@16 237 // a standard stream or stream buffer
Chris@16 238 template<typename Source, typename Sink>
Chris@16 239 std::streamsize
Chris@16 240 copy( Source& src, Sink& snk,
Chris@16 241 std::streamsize buffer_size = default_device_buffer_size
Chris@16 242 BOOST_IOSTREAMS_ENABLE_IF_STREAM(Source)
Chris@16 243 BOOST_IOSTREAMS_ENABLE_IF_STREAM(Sink) )
Chris@16 244 {
Chris@16 245 return detail::copy_impl(detail::wrap(src), detail::wrap(snk), buffer_size);
Chris@16 246 }
Chris@16 247
Chris@16 248 #endif // #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //-----------------------//
Chris@16 249
Chris@16 250 } } // End namespaces iostreams, boost.
Chris@16 251
Chris@16 252 #endif // #ifndef BOOST_IOSTREAMS_COPY_HPP_INCLUDED