summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemko Tronçon <git@el-tramo.be>2009-06-01 08:48:42 (GMT)
committerRemko Tronçon <git@el-tramo.be>2009-06-01 09:24:28 (GMT)
commit2812bddd81f8a1b804c7460f4e14cd0aa393d129 (patch)
treed46294f35150c4f0f43deaf2d31fceaf945ae715 /3rdParty/Boost/boost/asio/buffered_read_stream.hpp
downloadswift-2812bddd81f8a1b804c7460f4e14cd0aa393d129.zip
swift-2812bddd81f8a1b804c7460f4e14cd0aa393d129.tar.bz2
Import.
Diffstat (limited to '3rdParty/Boost/boost/asio/buffered_read_stream.hpp')
-rw-r--r--3rdParty/Boost/boost/asio/buffered_read_stream.hpp422
1 files changed, 422 insertions, 0 deletions
diff --git a/3rdParty/Boost/boost/asio/buffered_read_stream.hpp b/3rdParty/Boost/boost/asio/buffered_read_stream.hpp
new file mode 100644
index 0000000..742123b
--- /dev/null
+++ b/3rdParty/Boost/boost/asio/buffered_read_stream.hpp
@@ -0,0 +1,422 @@
+//
+// buffered_read_stream.hpp
+// ~~~~~~~~~~~~~~~~~~~~~~~~
+//
+// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+//
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+#ifndef BOOST_ASIO_BUFFERED_READ_STREAM_HPP
+#define BOOST_ASIO_BUFFERED_READ_STREAM_HPP
+
+#if defined(_MSC_VER) && (_MSC_VER >= 1200)
+# pragma once
+#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+
+#include <boost/asio/detail/push_options.hpp>
+
+#include <boost/asio/detail/push_options.hpp>
+#include <cstddef>
+#include <cstring>
+#include <boost/config.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/asio/detail/pop_options.hpp>
+
+#include <boost/asio/buffered_read_stream_fwd.hpp>
+#include <boost/asio/buffer.hpp>
+#include <boost/asio/error.hpp>
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/detail/bind_handler.hpp>
+#include <boost/asio/detail/buffer_resize_guard.hpp>
+#include <boost/asio/detail/buffered_stream_storage.hpp>
+#include <boost/asio/detail/noncopyable.hpp>
+
+namespace boost {
+namespace asio {
+
+/// Adds buffering to the read-related operations of a stream.
+/**
+ * The buffered_read_stream class template can be used to add buffering to the
+ * synchronous and asynchronous read operations of a stream.
+ *
+ * @par Thread Safety
+ * @e Distinct @e objects: Safe.@n
+ * @e Shared @e objects: Unsafe.
+ *
+ * @par Concepts:
+ * AsyncReadStream, AsyncWriteStream, Stream, Sync_Read_Stream, SyncWriteStream.
+ */
+template <typename Stream>
+class buffered_read_stream
+ : private noncopyable
+{
+public:
+ /// The type of the next layer.
+ typedef typename boost::remove_reference<Stream>::type next_layer_type;
+
+ /// The type of the lowest layer.
+ typedef typename next_layer_type::lowest_layer_type lowest_layer_type;
+
+#if defined(GENERATING_DOCUMENTATION)
+ /// The default buffer size.
+ static const std::size_t default_buffer_size = implementation_defined;
+#else
+ BOOST_STATIC_CONSTANT(std::size_t, default_buffer_size = 1024);
+#endif
+
+ /// Construct, passing the specified argument to initialise the next layer.
+ template <typename Arg>
+ explicit buffered_read_stream(Arg& a)
+ : next_layer_(a),
+ storage_(default_buffer_size)
+ {
+ }
+
+ /// Construct, passing the specified argument to initialise the next layer.
+ template <typename Arg>
+ buffered_read_stream(Arg& a, std::size_t buffer_size)
+ : next_layer_(a),
+ storage_(buffer_size)
+ {
+ }
+
+ /// Get a reference to the next layer.
+ next_layer_type& next_layer()
+ {
+ return next_layer_;
+ }
+
+ /// Get a reference to the lowest layer.
+ lowest_layer_type& lowest_layer()
+ {
+ return next_layer_.lowest_layer();
+ }
+
+ /// Get a const reference to the lowest layer.
+ const lowest_layer_type& lowest_layer() const
+ {
+ return next_layer_.lowest_layer();
+ }
+
+ /// (Deprecated: use get_io_service().) Get the io_service associated with
+ /// the object.
+ boost::asio::io_service& io_service()
+ {
+ return next_layer_.get_io_service();
+ }
+
+ /// Get the io_service associated with the object.
+ boost::asio::io_service& get_io_service()
+ {
+ return next_layer_.get_io_service();
+ }
+
+ /// Close the stream.
+ void close()
+ {
+ next_layer_.close();
+ }
+
+ /// Close the stream.
+ boost::system::error_code close(boost::system::error_code& ec)
+ {
+ return next_layer_.close(ec);
+ }
+
+ /// Write the given data to the stream. Returns the number of bytes written.
+ /// Throws an exception on failure.
+ template <typename ConstBufferSequence>
+ std::size_t write_some(const ConstBufferSequence& buffers)
+ {
+ return next_layer_.write_some(buffers);
+ }
+
+ /// Write the given data to the stream. Returns the number of bytes written,
+ /// or 0 if an error occurred.
+ template <typename ConstBufferSequence>
+ std::size_t write_some(const ConstBufferSequence& buffers,
+ boost::system::error_code& ec)
+ {
+ return next_layer_.write_some(buffers, ec);
+ }
+
+ /// Start an asynchronous write. The data being written must be valid for the
+ /// lifetime of the asynchronous operation.
+ template <typename ConstBufferSequence, typename WriteHandler>
+ void async_write_some(const ConstBufferSequence& buffers,
+ WriteHandler handler)
+ {
+ next_layer_.async_write_some(buffers, handler);
+ }
+
+ /// Fill the buffer with some data. Returns the number of bytes placed in the
+ /// buffer as a result of the operation. Throws an exception on failure.
+ std::size_t fill()
+ {
+ detail::buffer_resize_guard<detail::buffered_stream_storage>
+ resize_guard(storage_);
+ std::size_t previous_size = storage_.size();
+ storage_.resize(storage_.capacity());
+ storage_.resize(previous_size + next_layer_.read_some(buffer(
+ storage_.data() + previous_size,
+ storage_.size() - previous_size)));
+ resize_guard.commit();
+ return storage_.size() - previous_size;
+ }
+
+ /// Fill the buffer with some data. Returns the number of bytes placed in the
+ /// buffer as a result of the operation, or 0 if an error occurred.
+ std::size_t fill(boost::system::error_code& ec)
+ {
+ detail::buffer_resize_guard<detail::buffered_stream_storage>
+ resize_guard(storage_);
+ std::size_t previous_size = storage_.size();
+ storage_.resize(storage_.capacity());
+ storage_.resize(previous_size + next_layer_.read_some(buffer(
+ storage_.data() + previous_size,
+ storage_.size() - previous_size),
+ ec));
+ resize_guard.commit();
+ return storage_.size() - previous_size;
+ }
+
+ template <typename ReadHandler>
+ class fill_handler
+ {
+ public:
+ fill_handler(boost::asio::io_service& io_service,
+ detail::buffered_stream_storage& storage,
+ std::size_t previous_size, ReadHandler handler)
+ : io_service_(io_service),
+ storage_(storage),
+ previous_size_(previous_size),
+ handler_(handler)
+ {
+ }
+
+ void operator()(const boost::system::error_code& ec,
+ std::size_t bytes_transferred)
+ {
+ storage_.resize(previous_size_ + bytes_transferred);
+ io_service_.dispatch(detail::bind_handler(
+ handler_, ec, bytes_transferred));
+ }
+
+ private:
+ boost::asio::io_service& io_service_;
+ detail::buffered_stream_storage& storage_;
+ std::size_t previous_size_;
+ ReadHandler handler_;
+ };
+
+ /// Start an asynchronous fill.
+ template <typename ReadHandler>
+ void async_fill(ReadHandler handler)
+ {
+ std::size_t previous_size = storage_.size();
+ storage_.resize(storage_.capacity());
+ next_layer_.async_read_some(
+ buffer(
+ storage_.data() + previous_size,
+ storage_.size() - previous_size),
+ fill_handler<ReadHandler>(get_io_service(),
+ storage_, previous_size, handler));
+ }
+
+ /// Read some data from the stream. Returns the number of bytes read. Throws
+ /// an exception on failure.
+ template <typename MutableBufferSequence>
+ std::size_t read_some(const MutableBufferSequence& buffers)
+ {
+ if (storage_.empty())
+ fill();
+ return copy(buffers);
+ }
+
+ /// Read some data from the stream. Returns the number of bytes read or 0 if
+ /// an error occurred.
+ template <typename MutableBufferSequence>
+ std::size_t read_some(const MutableBufferSequence& buffers,
+ boost::system::error_code& ec)
+ {
+ ec = boost::system::error_code();
+ if (storage_.empty() && !fill(ec))
+ return 0;
+ return copy(buffers);
+ }
+
+ template <typename MutableBufferSequence, typename ReadHandler>
+ class read_some_handler
+ {
+ public:
+ read_some_handler(boost::asio::io_service& io_service,
+ detail::buffered_stream_storage& storage,
+ const MutableBufferSequence& buffers, ReadHandler handler)
+ : io_service_(io_service),
+ storage_(storage),
+ buffers_(buffers),
+ handler_(handler)
+ {
+ }
+
+ void operator()(const boost::system::error_code& ec, std::size_t)
+ {
+ if (ec || storage_.empty())
+ {
+ std::size_t length = 0;
+ io_service_.dispatch(detail::bind_handler(handler_, ec, length));
+ }
+ else
+ {
+ using namespace std; // For memcpy.
+
+ std::size_t bytes_avail = storage_.size();
+ std::size_t bytes_copied = 0;
+
+ typename MutableBufferSequence::const_iterator iter = buffers_.begin();
+ typename MutableBufferSequence::const_iterator end = buffers_.end();
+ for (; iter != end && bytes_avail > 0; ++iter)
+ {
+ std::size_t max_length = buffer_size(*iter);
+ std::size_t length = (max_length < bytes_avail)
+ ? max_length : bytes_avail;
+ memcpy(buffer_cast<void*>(*iter),
+ storage_.data() + bytes_copied, length);
+ bytes_copied += length;
+ bytes_avail -= length;
+ }
+
+ storage_.consume(bytes_copied);
+ io_service_.dispatch(detail::bind_handler(handler_, ec, bytes_copied));
+ }
+ }
+
+ private:
+ boost::asio::io_service& io_service_;
+ detail::buffered_stream_storage& storage_;
+ MutableBufferSequence buffers_;
+ ReadHandler handler_;
+ };
+
+ /// Start an asynchronous read. The buffer into which the data will be read
+ /// must be valid for the lifetime of the asynchronous operation.
+ template <typename MutableBufferSequence, typename ReadHandler>
+ void async_read_some(const MutableBufferSequence& buffers,
+ ReadHandler handler)
+ {
+ if (storage_.empty())
+ {
+ async_fill(read_some_handler<MutableBufferSequence, ReadHandler>(
+ get_io_service(), storage_, buffers, handler));
+ }
+ else
+ {
+ std::size_t length = copy(buffers);
+ get_io_service().post(detail::bind_handler(
+ handler, boost::system::error_code(), length));
+ }
+ }
+
+ /// Peek at the incoming data on the stream. Returns the number of bytes read.
+ /// Throws an exception on failure.
+ template <typename MutableBufferSequence>
+ std::size_t peek(const MutableBufferSequence& buffers)
+ {
+ if (storage_.empty())
+ fill();
+ return peek_copy(buffers);
+ }
+
+ /// Peek at the incoming data on the stream. Returns the number of bytes read,
+ /// or 0 if an error occurred.
+ template <typename MutableBufferSequence>
+ std::size_t peek(const MutableBufferSequence& buffers,
+ boost::system::error_code& ec)
+ {
+ ec = boost::system::error_code();
+ if (storage_.empty() && !fill(ec))
+ return 0;
+ return peek_copy(buffers);
+ }
+
+ /// Determine the amount of data that may be read without blocking.
+ std::size_t in_avail()
+ {
+ return storage_.size();
+ }
+
+ /// Determine the amount of data that may be read without blocking.
+ std::size_t in_avail(boost::system::error_code& ec)
+ {
+ ec = boost::system::error_code();
+ return storage_.size();
+ }
+
+private:
+ /// Copy data out of the internal buffer to the specified target buffer.
+ /// Returns the number of bytes copied.
+ template <typename MutableBufferSequence>
+ std::size_t copy(const MutableBufferSequence& buffers)
+ {
+ using namespace std; // For memcpy.
+
+ std::size_t bytes_avail = storage_.size();
+ std::size_t bytes_copied = 0;
+
+ typename MutableBufferSequence::const_iterator iter = buffers.begin();
+ typename MutableBufferSequence::const_iterator end = buffers.end();
+ for (; iter != end && bytes_avail > 0; ++iter)
+ {
+ std::size_t max_length = buffer_size(*iter);
+ std::size_t length = (max_length < bytes_avail)
+ ? max_length : bytes_avail;
+ memcpy(buffer_cast<void*>(*iter), storage_.data() + bytes_copied, length);
+ bytes_copied += length;
+ bytes_avail -= length;
+ }
+
+ storage_.consume(bytes_copied);
+ return bytes_copied;
+ }
+
+ /// Copy data from the internal buffer to the specified target buffer, without
+ /// removing the data from the internal buffer. Returns the number of bytes
+ /// copied.
+ template <typename MutableBufferSequence>
+ std::size_t peek_copy(const MutableBufferSequence& buffers)
+ {
+ using namespace std; // For memcpy.
+
+ std::size_t bytes_avail = storage_.size();
+ std::size_t bytes_copied = 0;
+
+ typename MutableBufferSequence::const_iterator iter = buffers.begin();
+ typename MutableBufferSequence::const_iterator end = buffers.end();
+ for (; iter != end && bytes_avail > 0; ++iter)
+ {
+ std::size_t max_length = buffer_size(*iter);
+ std::size_t length = (max_length < bytes_avail)
+ ? max_length : bytes_avail;
+ memcpy(buffer_cast<void*>(*iter), storage_.data() + bytes_copied, length);
+ bytes_copied += length;
+ bytes_avail -= length;
+ }
+
+ return bytes_copied;
+ }
+
+ /// The next layer.
+ Stream next_layer_;
+
+ // The data in the buffer.
+ detail::buffered_stream_storage storage_;
+};
+
+} // namespace asio
+} // namespace boost
+
+#include <boost/asio/detail/pop_options.hpp>
+
+#endif // BOOST_ASIO_BUFFERED_READ_STREAM_HPP