Chris@16: // Chris@16: // detail/buffer_sequence_adapter.hpp Chris@16: // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Chris@16: // Chris@101: // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: Chris@16: #ifndef BOOST_ASIO_DETAIL_BUFFER_SEQUENCE_ADAPTER_HPP Chris@16: #define BOOST_ASIO_DETAIL_BUFFER_SEQUENCE_ADAPTER_HPP Chris@16: Chris@16: #if defined(_MSC_VER) && (_MSC_VER >= 1200) Chris@16: # pragma once Chris@16: #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: namespace boost { Chris@16: namespace asio { Chris@16: namespace detail { Chris@16: Chris@16: class buffer_sequence_adapter_base Chris@16: { Chris@16: protected: Chris@16: #if defined(BOOST_ASIO_WINDOWS_RUNTIME) Chris@16: // The maximum number of buffers to support in a single operation. Chris@16: enum { max_buffers = 1 }; Chris@16: Chris@16: typedef Windows::Storage::Streams::IBuffer^ native_buffer_type; Chris@16: Chris@16: BOOST_ASIO_DECL static void init_native_buffer( Chris@16: native_buffer_type& buf, Chris@16: const boost::asio::mutable_buffer& buffer); Chris@16: Chris@16: BOOST_ASIO_DECL static void init_native_buffer( Chris@16: native_buffer_type& buf, Chris@16: const boost::asio::const_buffer& buffer); Chris@16: #elif defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) Chris@16: // The maximum number of buffers to support in a single operation. Chris@16: enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len }; Chris@16: Chris@16: typedef WSABUF native_buffer_type; Chris@16: Chris@16: static void init_native_buffer(WSABUF& buf, Chris@16: const boost::asio::mutable_buffer& buffer) Chris@16: { Chris@16: buf.buf = boost::asio::buffer_cast(buffer); Chris@16: buf.len = static_cast(boost::asio::buffer_size(buffer)); Chris@16: } Chris@16: Chris@16: static void init_native_buffer(WSABUF& buf, Chris@16: const boost::asio::const_buffer& buffer) Chris@16: { Chris@16: buf.buf = const_cast(boost::asio::buffer_cast(buffer)); Chris@16: buf.len = static_cast(boost::asio::buffer_size(buffer)); Chris@16: } Chris@16: #else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) Chris@16: // The maximum number of buffers to support in a single operation. Chris@16: enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len }; Chris@16: Chris@16: typedef iovec native_buffer_type; Chris@16: Chris@16: static void init_iov_base(void*& base, void* addr) Chris@16: { Chris@16: base = addr; Chris@16: } Chris@16: Chris@16: template Chris@16: static void init_iov_base(T& base, void* addr) Chris@16: { Chris@16: base = static_cast(addr); Chris@16: } Chris@16: Chris@16: static void init_native_buffer(iovec& iov, Chris@16: const boost::asio::mutable_buffer& buffer) Chris@16: { Chris@16: init_iov_base(iov.iov_base, boost::asio::buffer_cast(buffer)); Chris@16: iov.iov_len = boost::asio::buffer_size(buffer); Chris@16: } Chris@16: Chris@16: static void init_native_buffer(iovec& iov, Chris@16: const boost::asio::const_buffer& buffer) Chris@16: { Chris@16: init_iov_base(iov.iov_base, const_cast( Chris@16: boost::asio::buffer_cast(buffer))); Chris@16: iov.iov_len = boost::asio::buffer_size(buffer); Chris@16: } Chris@16: #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__) Chris@16: }; Chris@16: Chris@16: // Helper class to translate buffers into the native buffer representation. Chris@16: template Chris@16: class buffer_sequence_adapter Chris@16: : buffer_sequence_adapter_base Chris@16: { Chris@16: public: Chris@16: explicit buffer_sequence_adapter(const Buffers& buffer_sequence) Chris@16: : count_(0), total_buffer_size_(0) Chris@16: { Chris@16: typename Buffers::const_iterator iter = buffer_sequence.begin(); Chris@16: typename Buffers::const_iterator end = buffer_sequence.end(); Chris@16: for (; iter != end && count_ < max_buffers; ++iter, ++count_) Chris@16: { Chris@16: Buffer buffer(*iter); Chris@16: init_native_buffer(buffers_[count_], buffer); Chris@16: total_buffer_size_ += boost::asio::buffer_size(buffer); Chris@16: } Chris@16: } Chris@16: Chris@16: native_buffer_type* buffers() Chris@16: { Chris@16: return buffers_; Chris@16: } Chris@16: Chris@16: std::size_t count() const Chris@16: { Chris@16: return count_; Chris@16: } Chris@16: Chris@16: bool all_empty() const Chris@16: { Chris@16: return total_buffer_size_ == 0; Chris@16: } Chris@16: Chris@16: static bool all_empty(const Buffers& buffer_sequence) Chris@16: { Chris@16: typename Buffers::const_iterator iter = buffer_sequence.begin(); Chris@16: typename Buffers::const_iterator end = buffer_sequence.end(); Chris@16: std::size_t i = 0; Chris@16: for (; iter != end && i < max_buffers; ++iter, ++i) Chris@16: if (boost::asio::buffer_size(Buffer(*iter)) > 0) Chris@16: return false; Chris@16: return true; Chris@16: } Chris@16: Chris@16: static void validate(const Buffers& buffer_sequence) Chris@16: { Chris@16: typename Buffers::const_iterator iter = buffer_sequence.begin(); Chris@16: typename Buffers::const_iterator end = buffer_sequence.end(); Chris@16: for (; iter != end; ++iter) Chris@16: { Chris@16: Buffer buffer(*iter); Chris@16: boost::asio::buffer_cast(buffer); Chris@16: } Chris@16: } Chris@16: Chris@16: static Buffer first(const Buffers& buffer_sequence) Chris@16: { Chris@16: typename Buffers::const_iterator iter = buffer_sequence.begin(); Chris@16: typename Buffers::const_iterator end = buffer_sequence.end(); Chris@16: for (; iter != end; ++iter) Chris@16: { Chris@16: Buffer buffer(*iter); Chris@16: if (boost::asio::buffer_size(buffer) != 0) Chris@16: return buffer; Chris@16: } Chris@16: return Buffer(); Chris@16: } Chris@16: Chris@16: private: Chris@16: native_buffer_type buffers_[max_buffers]; Chris@16: std::size_t count_; Chris@16: std::size_t total_buffer_size_; Chris@16: }; Chris@16: Chris@16: template Chris@16: class buffer_sequence_adapter Chris@16: : buffer_sequence_adapter_base Chris@16: { Chris@16: public: Chris@16: explicit buffer_sequence_adapter( Chris@16: const boost::asio::mutable_buffers_1& buffer_sequence) Chris@16: { Chris@16: init_native_buffer(buffer_, Buffer(buffer_sequence)); Chris@16: total_buffer_size_ = boost::asio::buffer_size(buffer_sequence); Chris@16: } Chris@16: Chris@16: native_buffer_type* buffers() Chris@16: { Chris@16: return &buffer_; Chris@16: } Chris@16: Chris@16: std::size_t count() const Chris@16: { Chris@16: return 1; Chris@16: } Chris@16: Chris@16: bool all_empty() const Chris@16: { Chris@16: return total_buffer_size_ == 0; Chris@16: } Chris@16: Chris@16: static bool all_empty(const boost::asio::mutable_buffers_1& buffer_sequence) Chris@16: { Chris@16: return boost::asio::buffer_size(buffer_sequence) == 0; Chris@16: } Chris@16: Chris@16: static void validate(const boost::asio::mutable_buffers_1& buffer_sequence) Chris@16: { Chris@16: boost::asio::buffer_cast(buffer_sequence); Chris@16: } Chris@16: Chris@16: static Buffer first(const boost::asio::mutable_buffers_1& buffer_sequence) Chris@16: { Chris@16: return Buffer(buffer_sequence); Chris@16: } Chris@16: Chris@16: private: Chris@16: native_buffer_type buffer_; Chris@16: std::size_t total_buffer_size_; Chris@16: }; Chris@16: Chris@16: template Chris@16: class buffer_sequence_adapter Chris@16: : buffer_sequence_adapter_base Chris@16: { Chris@16: public: Chris@16: explicit buffer_sequence_adapter( Chris@16: const boost::asio::const_buffers_1& buffer_sequence) Chris@16: { Chris@16: init_native_buffer(buffer_, Buffer(buffer_sequence)); Chris@16: total_buffer_size_ = boost::asio::buffer_size(buffer_sequence); Chris@16: } Chris@16: Chris@16: native_buffer_type* buffers() Chris@16: { Chris@16: return &buffer_; Chris@16: } Chris@16: Chris@16: std::size_t count() const Chris@16: { Chris@16: return 1; Chris@16: } Chris@16: Chris@16: bool all_empty() const Chris@16: { Chris@16: return total_buffer_size_ == 0; Chris@16: } Chris@16: Chris@16: static bool all_empty(const boost::asio::const_buffers_1& buffer_sequence) Chris@16: { Chris@16: return boost::asio::buffer_size(buffer_sequence) == 0; Chris@16: } Chris@16: Chris@16: static void validate(const boost::asio::const_buffers_1& buffer_sequence) Chris@16: { Chris@16: boost::asio::buffer_cast(buffer_sequence); Chris@16: } Chris@16: Chris@16: static Buffer first(const boost::asio::const_buffers_1& buffer_sequence) Chris@16: { Chris@16: return Buffer(buffer_sequence); Chris@16: } Chris@16: Chris@16: private: Chris@16: native_buffer_type buffer_; Chris@16: std::size_t total_buffer_size_; Chris@16: }; Chris@16: Chris@16: template Chris@16: class buffer_sequence_adapter > Chris@16: : buffer_sequence_adapter_base Chris@16: { Chris@16: public: Chris@16: explicit buffer_sequence_adapter( Chris@16: const boost::array& buffer_sequence) Chris@16: { Chris@16: init_native_buffer(buffers_[0], Buffer(buffer_sequence[0])); Chris@16: init_native_buffer(buffers_[1], Buffer(buffer_sequence[1])); Chris@16: total_buffer_size_ = boost::asio::buffer_size(buffer_sequence[0]) Chris@16: + boost::asio::buffer_size(buffer_sequence[1]); Chris@16: } Chris@16: Chris@16: native_buffer_type* buffers() Chris@16: { Chris@16: return buffers_; Chris@16: } Chris@16: Chris@16: std::size_t count() const Chris@16: { Chris@16: return 2; Chris@16: } Chris@16: Chris@16: bool all_empty() const Chris@16: { Chris@16: return total_buffer_size_ == 0; Chris@16: } Chris@16: Chris@16: static bool all_empty(const boost::array& buffer_sequence) Chris@16: { Chris@16: return boost::asio::buffer_size(buffer_sequence[0]) == 0 Chris@16: && boost::asio::buffer_size(buffer_sequence[1]) == 0; Chris@16: } Chris@16: Chris@16: static void validate(const boost::array& buffer_sequence) Chris@16: { Chris@16: boost::asio::buffer_cast(buffer_sequence[0]); Chris@16: boost::asio::buffer_cast(buffer_sequence[1]); Chris@16: } Chris@16: Chris@16: static Buffer first(const boost::array& buffer_sequence) Chris@16: { Chris@16: return Buffer(boost::asio::buffer_size(buffer_sequence[0]) != 0 Chris@16: ? buffer_sequence[0] : buffer_sequence[1]); Chris@16: } Chris@16: Chris@16: private: Chris@16: native_buffer_type buffers_[2]; Chris@16: std::size_t total_buffer_size_; Chris@16: }; Chris@16: Chris@16: #if defined(BOOST_ASIO_HAS_STD_ARRAY) Chris@16: Chris@16: template Chris@16: class buffer_sequence_adapter > Chris@16: : buffer_sequence_adapter_base Chris@16: { Chris@16: public: Chris@16: explicit buffer_sequence_adapter( Chris@16: const std::array& buffer_sequence) Chris@16: { Chris@16: init_native_buffer(buffers_[0], Buffer(buffer_sequence[0])); Chris@16: init_native_buffer(buffers_[1], Buffer(buffer_sequence[1])); Chris@16: total_buffer_size_ = boost::asio::buffer_size(buffer_sequence[0]) Chris@16: + boost::asio::buffer_size(buffer_sequence[1]); Chris@16: } Chris@16: Chris@16: native_buffer_type* buffers() Chris@16: { Chris@16: return buffers_; Chris@16: } Chris@16: Chris@16: std::size_t count() const Chris@16: { Chris@16: return 2; Chris@16: } Chris@16: Chris@16: bool all_empty() const Chris@16: { Chris@16: return total_buffer_size_ == 0; Chris@16: } Chris@16: Chris@16: static bool all_empty(const std::array& buffer_sequence) Chris@16: { Chris@16: return boost::asio::buffer_size(buffer_sequence[0]) == 0 Chris@16: && boost::asio::buffer_size(buffer_sequence[1]) == 0; Chris@16: } Chris@16: Chris@16: static void validate(const std::array& buffer_sequence) Chris@16: { Chris@16: boost::asio::buffer_cast(buffer_sequence[0]); Chris@16: boost::asio::buffer_cast(buffer_sequence[1]); Chris@16: } Chris@16: Chris@16: static Buffer first(const std::array& buffer_sequence) Chris@16: { Chris@16: return Buffer(boost::asio::buffer_size(buffer_sequence[0]) != 0 Chris@16: ? buffer_sequence[0] : buffer_sequence[1]); Chris@16: } Chris@16: Chris@16: private: Chris@16: native_buffer_type buffers_[2]; Chris@16: std::size_t total_buffer_size_; Chris@16: }; Chris@16: Chris@16: #endif // defined(BOOST_ASIO_HAS_STD_ARRAY) Chris@16: Chris@16: } // namespace detail Chris@16: } // namespace asio Chris@16: } // namespace boost Chris@16: Chris@16: #include Chris@16: Chris@16: #if defined(BOOST_ASIO_HEADER_ONLY) Chris@16: # include Chris@16: #endif // defined(BOOST_ASIO_HEADER_ONLY) Chris@16: Chris@16: #endif // BOOST_ASIO_DETAIL_BUFFER_SEQUENCE_ADAPTER_HPP