1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ossrv_pub/boost_apis/boost/iostreams/copy.hpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,198 @@
1.4 +// (C) Copyright Jonathan Turkanis 2003.
1.5 +// Distributed under the Boost Software License, Version 1.0. (See accompanying
1.6 +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
1.7 +
1.8 +// See http://www.boost.org/libs/iostreams for documentation.
1.9 +
1.10 +// Contains: The function template copy, which reads data from a Source
1.11 +// and writes it to a Sink until the end of the sequence is reached, returning
1.12 +// the number of characters transfered.
1.13 +
1.14 +// The implementation is complicated by the need to handle smart adapters
1.15 +// and direct devices.
1.16 +
1.17 +#ifndef BOOST_IOSTREAMS_COPY_HPP_INCLUDED
1.18 +#define BOOST_IOSTREAMS_COPY_HPP_INCLUDED
1.19 +
1.20 +#if defined(_MSC_VER) && (_MSC_VER >= 1020)
1.21 +# pragma once
1.22 +#endif
1.23 +
1.24 +#include <algorithm> // copy.
1.25 +#include <utility> // pair.
1.26 +#include <boost/detail/workaround.hpp>
1.27 +#include <boost/iostreams/chain.hpp>
1.28 +#include <boost/iostreams/constants.hpp>
1.29 +#include <boost/iostreams/detail/adapter/non_blocking_adapter.hpp>
1.30 +#include <boost/iostreams/detail/buffer.hpp>
1.31 +#include <boost/iostreams/detail/closer.hpp>
1.32 +#include <boost/iostreams/detail/enable_if_stream.hpp>
1.33 +#include <boost/iostreams/detail/ios.hpp> // failure, streamsize.
1.34 +#include <boost/iostreams/detail/resolve.hpp>
1.35 +#include <boost/iostreams/detail/wrap_unwrap.hpp>
1.36 +#include <boost/iostreams/operations.hpp> // read, write, close.
1.37 +#include <boost/iostreams/pipeline.hpp>
1.38 +#include <boost/static_assert.hpp>
1.39 +#include <boost/type_traits/is_same.hpp>
1.40 +
1.41 +namespace boost { namespace iostreams {
1.42 +
1.43 +namespace detail {
1.44 +
1.45 +template<typename Source, typename Sink>
1.46 +std::streamsize copy_impl( Source& src, Sink& snk,
1.47 + std::streamsize /* buffer_size */,
1.48 + mpl::true_, mpl::true_ )
1.49 +{ // Copy from a direct Source to a direct Sink.
1.50 + using namespace std;
1.51 + typedef typename char_type_of<Source>::type char_type;
1.52 + typedef pair<char_type*, char_type*> pair_type;
1.53 + pair_type p1 = iostreams::input_sequence(src);
1.54 + pair_type p2 = iostreams::output_sequence(snk);
1.55 + if (p1.second - p1.first < p2.second - p2.first) {
1.56 + std::copy(p1.first, p1.second, p2.first);
1.57 + return static_cast<streamsize>(p1.second - p1.first);
1.58 + } else {
1.59 + throw BOOST_IOSTREAMS_FAILURE("destination too small");
1.60 + }
1.61 +}
1.62 +
1.63 +template<typename Source, typename Sink>
1.64 +std::streamsize copy_impl( Source& src, Sink& snk,
1.65 + std::streamsize /* buffer_size */,
1.66 + mpl::true_, mpl::false_ )
1.67 +{ // Copy from a direct Source to an indirect Sink.
1.68 + using namespace std;
1.69 + typedef typename char_type_of<Source>::type char_type;
1.70 + typedef pair<char_type*, char_type*> pair_type;
1.71 + pair_type p = iostreams::input_sequence(src);
1.72 + std::streamsize size, total;
1.73 + for ( total = 0, size = static_cast<streamsize>(p.second - p.first);
1.74 + total < size; )
1.75 + {
1.76 + std::streamsize amt =
1.77 + iostreams::write(snk, p.first + total, size - total);
1.78 + total += amt;
1.79 + }
1.80 + return size;
1.81 +}
1.82 +
1.83 +template<typename Source, typename Sink>
1.84 +std::streamsize copy_impl( Source& src, Sink& snk,
1.85 + std::streamsize buffer_size,
1.86 + mpl::false_, mpl::true_ )
1.87 +{ // Copy from an indirect Source to a direct Sink.
1.88 + using namespace std;
1.89 + typedef typename char_type_of<Source>::type char_type;
1.90 + typedef pair<char_type*, char_type*> pair_type;
1.91 + detail::basic_buffer<char_type> buf(buffer_size);
1.92 + pair_type p = snk.output_sequence();
1.93 + streamsize total = 0;
1.94 + bool done = false;
1.95 + while (!done) {
1.96 + streamsize amt;
1.97 + done = (amt = iostreams::read(src, buf.data(), buffer_size)) == -1;
1.98 + std::copy(buf.data(), buf.data() + amt, p.first + total);
1.99 + if (amt != -1)
1.100 + total += amt;
1.101 + }
1.102 + return total;
1.103 +}
1.104 +
1.105 +template<typename Source, typename Sink>
1.106 +std::streamsize copy_impl( Source& src, Sink& snk,
1.107 + std::streamsize buffer_size,
1.108 + mpl::false_, mpl::false_ )
1.109 +{ // Copy from an indirect Source to a indirect Sink. This algorithm
1.110 + // can be improved by eliminating the non_blocking_adapter.
1.111 + typedef typename char_type_of<Source>::type char_type;
1.112 + detail::basic_buffer<char_type> buf(buffer_size);
1.113 + non_blocking_adapter<Sink> nb(snk);
1.114 + std::streamsize total = 0;
1.115 + bool done = false;
1.116 + while (!done) {
1.117 + std::streamsize amt;
1.118 + done = (amt = iostreams::read(src, buf.data(), buffer_size)) == -1;
1.119 + if (amt != -1) {
1.120 + iostreams::write(nb, buf.data(), amt);
1.121 + total += amt;
1.122 + }
1.123 + }
1.124 + return total;
1.125 +}
1.126 +
1.127 +template<typename Source, typename Sink>
1.128 +std::streamsize copy_impl(Source src, Sink snk, std::streamsize buffer_size)
1.129 +{
1.130 + using namespace std;
1.131 + typedef typename char_type_of<Source>::type src_char;
1.132 + typedef typename char_type_of<Sink>::type snk_char;
1.133 + BOOST_STATIC_ASSERT((is_same<src_char, snk_char>::value));
1.134 + bool nothrow = false;
1.135 + external_closer<Source> close_source(src, BOOST_IOS::in, nothrow);
1.136 + external_closer<Sink> close_sink(snk, BOOST_IOS::out, nothrow);
1.137 + streamsize result =
1.138 + copy_impl( src, snk, buffer_size,
1.139 + is_direct<Source>(), is_direct<Sink>() );
1.140 + return result;
1.141 +}
1.142 +
1.143 +} // End namespace detail.
1.144 +
1.145 +//------------------Definition of copy----------------------------------------//
1.146 +
1.147 +template<typename Source, typename Sink>
1.148 +std::streamsize
1.149 +copy( const Source& src, const Sink& snk,
1.150 + std::streamsize buffer_size = default_device_buffer_size
1.151 + BOOST_IOSTREAMS_DISABLE_IF_STREAM(Source)
1.152 + BOOST_IOSTREAMS_DISABLE_IF_STREAM(Sink) )
1.153 +{
1.154 + typedef typename char_type_of<Source>::type char_type;
1.155 + return detail::copy_impl( detail::resolve<input, char_type>(src),
1.156 + detail::resolve<output, char_type>(snk),
1.157 + buffer_size );
1.158 +}
1.159 +
1.160 +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------//
1.161 +
1.162 +template<typename Source, typename Sink>
1.163 +std::streamsize
1.164 +copy( Source& src, const Sink& snk,
1.165 + std::streamsize buffer_size = default_device_buffer_size
1.166 + BOOST_IOSTREAMS_ENABLE_IF_STREAM(Source)
1.167 + BOOST_IOSTREAMS_DISABLE_IF_STREAM(Sink) )
1.168 +{
1.169 + typedef typename char_type_of<Source>::type char_type;
1.170 + return detail::copy_impl( detail::wrap(src),
1.171 + detail::resolve<output, char_type>(snk),
1.172 + buffer_size );
1.173 +}
1.174 +
1.175 +template<typename Source, typename Sink>
1.176 +std::streamsize
1.177 +copy( const Source& src, Sink& snk,
1.178 + std::streamsize buffer_size = default_device_buffer_size
1.179 + BOOST_IOSTREAMS_DISABLE_IF_STREAM(Source)
1.180 + BOOST_IOSTREAMS_ENABLE_IF_STREAM(Sink) )
1.181 +{
1.182 + typedef typename char_type_of<Source>::type char_type;
1.183 + return detail::copy_impl( detail::resolve<input, char_type>(src),
1.184 + detail::wrap(snk), buffer_size);
1.185 +}
1.186 +
1.187 +template<typename Source, typename Sink>
1.188 +std::streamsize
1.189 +copy( Source& src, Sink& snk,
1.190 + std::streamsize buffer_size = default_device_buffer_size
1.191 + BOOST_IOSTREAMS_ENABLE_IF_STREAM(Source)
1.192 + BOOST_IOSTREAMS_ENABLE_IF_STREAM(Sink) )
1.193 +{
1.194 + return detail::copy_impl(detail::wrap(src), detail::wrap(snk), buffer_size);
1.195 +}
1.196 +
1.197 +#endif // #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //-----------------------//
1.198 +
1.199 +} } // End namespaces iostreams, boost.
1.200 +
1.201 +#endif // #ifndef BOOST_IOSTREAMS_COPY_HPP_INCLUDED