842 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			842 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C++
		
	
	
	
| //
 | |
| // detail/buffer_sequence_adapter.hpp
 | |
| // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | |
| //
 | |
| // Copyright (c) 2003-2023 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 ASIO_DETAIL_BUFFER_SEQUENCE_ADAPTER_HPP
 | |
| #define ASIO_DETAIL_BUFFER_SEQUENCE_ADAPTER_HPP
 | |
| 
 | |
| #if defined(_MSC_VER) && (_MSC_VER >= 1200)
 | |
| # pragma once
 | |
| #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 | |
| 
 | |
| #include "asio/detail/config.hpp"
 | |
| #include "asio/buffer.hpp"
 | |
| #include "asio/detail/array_fwd.hpp"
 | |
| #include "asio/detail/socket_types.hpp"
 | |
| #include "asio/registered_buffer.hpp"
 | |
| 
 | |
| #include "asio/detail/push_options.hpp"
 | |
| 
 | |
| namespace asio {
 | |
| namespace detail {
 | |
| 
 | |
| class buffer_sequence_adapter_base
 | |
| {
 | |
| #if defined(ASIO_WINDOWS_RUNTIME)
 | |
| public:
 | |
|   // The maximum number of buffers to support in a single operation.
 | |
|   enum { max_buffers = 1 };
 | |
| 
 | |
| protected:
 | |
|   typedef Windows::Storage::Streams::IBuffer^ native_buffer_type;
 | |
| 
 | |
|   ASIO_DECL static void init_native_buffer(
 | |
|       native_buffer_type& buf,
 | |
|       const asio::mutable_buffer& buffer);
 | |
| 
 | |
|   ASIO_DECL static void init_native_buffer(
 | |
|       native_buffer_type& buf,
 | |
|       const asio::const_buffer& buffer);
 | |
| #elif defined(ASIO_WINDOWS) || defined(__CYGWIN__)
 | |
| public:
 | |
|   // The maximum number of buffers to support in a single operation.
 | |
|   enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len };
 | |
| 
 | |
| protected:
 | |
|   typedef WSABUF native_buffer_type;
 | |
| 
 | |
|   static void init_native_buffer(WSABUF& buf,
 | |
|       const asio::mutable_buffer& buffer)
 | |
|   {
 | |
|     buf.buf = static_cast<char*>(buffer.data());
 | |
|     buf.len = static_cast<ULONG>(buffer.size());
 | |
|   }
 | |
| 
 | |
|   static void init_native_buffer(WSABUF& buf,
 | |
|       const asio::const_buffer& buffer)
 | |
|   {
 | |
|     buf.buf = const_cast<char*>(static_cast<const char*>(buffer.data()));
 | |
|     buf.len = static_cast<ULONG>(buffer.size());
 | |
|   }
 | |
| #else // defined(ASIO_WINDOWS) || defined(__CYGWIN__)
 | |
| public:
 | |
|   // The maximum number of buffers to support in a single operation.
 | |
|   enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len };
 | |
| 
 | |
| protected:
 | |
|   typedef iovec native_buffer_type;
 | |
| 
 | |
|   static void init_iov_base(void*& base, void* addr)
 | |
|   {
 | |
|     base = addr;
 | |
|   }
 | |
| 
 | |
|   template <typename T>
 | |
|   static void init_iov_base(T& base, void* addr)
 | |
|   {
 | |
|     base = static_cast<T>(addr);
 | |
|   }
 | |
| 
 | |
|   static void init_native_buffer(iovec& iov,
 | |
|       const asio::mutable_buffer& buffer)
 | |
|   {
 | |
|     init_iov_base(iov.iov_base, buffer.data());
 | |
|     iov.iov_len = buffer.size();
 | |
|   }
 | |
| 
 | |
|   static void init_native_buffer(iovec& iov,
 | |
|       const asio::const_buffer& buffer)
 | |
|   {
 | |
|     init_iov_base(iov.iov_base, const_cast<void*>(buffer.data()));
 | |
|     iov.iov_len = buffer.size();
 | |
|   }
 | |
| #endif // defined(ASIO_WINDOWS) || defined(__CYGWIN__)
 | |
| };
 | |
| 
 | |
| // Helper class to translate buffers into the native buffer representation.
 | |
| template <typename Buffer, typename Buffers>
 | |
| class buffer_sequence_adapter
 | |
|   : buffer_sequence_adapter_base
 | |
| {
 | |
| public:
 | |
|   enum { is_single_buffer = false };
 | |
|   enum { is_registered_buffer = false };
 | |
| 
 | |
|   explicit buffer_sequence_adapter(const Buffers& buffer_sequence)
 | |
|     : count_(0), total_buffer_size_(0)
 | |
|   {
 | |
|     buffer_sequence_adapter::init(
 | |
|         asio::buffer_sequence_begin(buffer_sequence),
 | |
|         asio::buffer_sequence_end(buffer_sequence));
 | |
|   }
 | |
| 
 | |
|   native_buffer_type* buffers()
 | |
|   {
 | |
|     return buffers_;
 | |
|   }
 | |
| 
 | |
|   std::size_t count() const
 | |
|   {
 | |
|     return count_;
 | |
|   }
 | |
| 
 | |
|   std::size_t total_size() const
 | |
|   {
 | |
|     return total_buffer_size_;
 | |
|   }
 | |
| 
 | |
|   registered_buffer_id registered_id() const
 | |
|   {
 | |
|     return registered_buffer_id();
 | |
|   }
 | |
| 
 | |
|   bool all_empty() const
 | |
|   {
 | |
|     return total_buffer_size_ == 0;
 | |
|   }
 | |
| 
 | |
|   static bool all_empty(const Buffers& buffer_sequence)
 | |
|   {
 | |
|     return buffer_sequence_adapter::all_empty(
 | |
|         asio::buffer_sequence_begin(buffer_sequence),
 | |
|         asio::buffer_sequence_end(buffer_sequence));
 | |
|   }
 | |
| 
 | |
|   static void validate(const Buffers& buffer_sequence)
 | |
|   {
 | |
|     buffer_sequence_adapter::validate(
 | |
|         asio::buffer_sequence_begin(buffer_sequence),
 | |
|         asio::buffer_sequence_end(buffer_sequence));
 | |
|   }
 | |
| 
 | |
|   static Buffer first(const Buffers& buffer_sequence)
 | |
|   {
 | |
|     return buffer_sequence_adapter::first(
 | |
|         asio::buffer_sequence_begin(buffer_sequence),
 | |
|         asio::buffer_sequence_end(buffer_sequence));
 | |
|   }
 | |
| 
 | |
|   enum { linearisation_storage_size = 8192 };
 | |
| 
 | |
|   static Buffer linearise(const Buffers& buffer_sequence,
 | |
|       const asio::mutable_buffer& storage)
 | |
|   {
 | |
|     return buffer_sequence_adapter::linearise(
 | |
|         asio::buffer_sequence_begin(buffer_sequence),
 | |
|         asio::buffer_sequence_end(buffer_sequence), storage);
 | |
|   }
 | |
| 
 | |
| private:
 | |
|   template <typename Iterator>
 | |
|   void init(Iterator begin, Iterator end)
 | |
|   {
 | |
|     Iterator iter = begin;
 | |
|     for (; iter != end && count_ < max_buffers; ++iter, ++count_)
 | |
|     {
 | |
|       Buffer buffer(*iter);
 | |
|       init_native_buffer(buffers_[count_], buffer);
 | |
|       total_buffer_size_ += buffer.size();
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   template <typename Iterator>
 | |
|   static bool all_empty(Iterator begin, Iterator end)
 | |
|   {
 | |
|     Iterator iter = begin;
 | |
|     std::size_t i = 0;
 | |
|     for (; iter != end && i < max_buffers; ++iter, ++i)
 | |
|       if (Buffer(*iter).size() > 0)
 | |
|         return false;
 | |
|     return true;
 | |
|   }
 | |
| 
 | |
|   template <typename Iterator>
 | |
|   static void validate(Iterator begin, Iterator end)
 | |
|   {
 | |
|     Iterator iter = begin;
 | |
|     for (; iter != end; ++iter)
 | |
|     {
 | |
|       Buffer buffer(*iter);
 | |
|       buffer.data();
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   template <typename Iterator>
 | |
|   static Buffer first(Iterator begin, Iterator end)
 | |
|   {
 | |
|     Iterator iter = begin;
 | |
|     for (; iter != end; ++iter)
 | |
|     {
 | |
|       Buffer buffer(*iter);
 | |
|       if (buffer.size() != 0)
 | |
|         return buffer;
 | |
|     }
 | |
|     return Buffer();
 | |
|   }
 | |
| 
 | |
|   template <typename Iterator>
 | |
|   static Buffer linearise(Iterator begin, Iterator end,
 | |
|       const asio::mutable_buffer& storage)
 | |
|   {
 | |
|     asio::mutable_buffer unused_storage = storage;
 | |
|     Iterator iter = begin;
 | |
|     while (iter != end && unused_storage.size() != 0)
 | |
|     {
 | |
|       Buffer buffer(*iter);
 | |
|       ++iter;
 | |
|       if (buffer.size() == 0)
 | |
|         continue;
 | |
|       if (unused_storage.size() == storage.size())
 | |
|       {
 | |
|         if (iter == end)
 | |
|           return buffer;
 | |
|         if (buffer.size() >= unused_storage.size())
 | |
|           return buffer;
 | |
|       }
 | |
|       unused_storage += asio::buffer_copy(unused_storage, buffer);
 | |
|     }
 | |
|     return Buffer(storage.data(), storage.size() - unused_storage.size());
 | |
|   }
 | |
| 
 | |
|   native_buffer_type buffers_[max_buffers];
 | |
|   std::size_t count_;
 | |
|   std::size_t total_buffer_size_;
 | |
| };
 | |
| 
 | |
| template <typename Buffer>
 | |
| class buffer_sequence_adapter<Buffer, asio::mutable_buffer>
 | |
|   : buffer_sequence_adapter_base
 | |
| {
 | |
| public:
 | |
|   enum { is_single_buffer = true };
 | |
|   enum { is_registered_buffer = false };
 | |
| 
 | |
|   explicit buffer_sequence_adapter(
 | |
|       const asio::mutable_buffer& buffer_sequence)
 | |
|   {
 | |
|     init_native_buffer(buffer_, Buffer(buffer_sequence));
 | |
|     total_buffer_size_ = buffer_sequence.size();
 | |
|   }
 | |
| 
 | |
|   native_buffer_type* buffers()
 | |
|   {
 | |
|     return &buffer_;
 | |
|   }
 | |
| 
 | |
|   std::size_t count() const
 | |
|   {
 | |
|     return 1;
 | |
|   }
 | |
| 
 | |
|   std::size_t total_size() const
 | |
|   {
 | |
|     return total_buffer_size_;
 | |
|   }
 | |
| 
 | |
|   registered_buffer_id registered_id() const
 | |
|   {
 | |
|     return registered_buffer_id();
 | |
|   }
 | |
| 
 | |
|   bool all_empty() const
 | |
|   {
 | |
|     return total_buffer_size_ == 0;
 | |
|   }
 | |
| 
 | |
|   static bool all_empty(const asio::mutable_buffer& buffer_sequence)
 | |
|   {
 | |
|     return buffer_sequence.size() == 0;
 | |
|   }
 | |
| 
 | |
|   static void validate(const asio::mutable_buffer& buffer_sequence)
 | |
|   {
 | |
|     buffer_sequence.data();
 | |
|   }
 | |
| 
 | |
|   static Buffer first(const asio::mutable_buffer& buffer_sequence)
 | |
|   {
 | |
|     return Buffer(buffer_sequence);
 | |
|   }
 | |
| 
 | |
|   enum { linearisation_storage_size = 1 };
 | |
| 
 | |
|   static Buffer linearise(const asio::mutable_buffer& buffer_sequence,
 | |
|       const Buffer&)
 | |
|   {
 | |
|     return Buffer(buffer_sequence);
 | |
|   }
 | |
| 
 | |
| private:
 | |
|   native_buffer_type buffer_;
 | |
|   std::size_t total_buffer_size_;
 | |
| };
 | |
| 
 | |
| template <typename Buffer>
 | |
| class buffer_sequence_adapter<Buffer, asio::const_buffer>
 | |
|   : buffer_sequence_adapter_base
 | |
| {
 | |
| public:
 | |
|   enum { is_single_buffer = true };
 | |
|   enum { is_registered_buffer = false };
 | |
| 
 | |
|   explicit buffer_sequence_adapter(
 | |
|       const asio::const_buffer& buffer_sequence)
 | |
|   {
 | |
|     init_native_buffer(buffer_, Buffer(buffer_sequence));
 | |
|     total_buffer_size_ = buffer_sequence.size();
 | |
|   }
 | |
| 
 | |
|   native_buffer_type* buffers()
 | |
|   {
 | |
|     return &buffer_;
 | |
|   }
 | |
| 
 | |
|   std::size_t count() const
 | |
|   {
 | |
|     return 1;
 | |
|   }
 | |
| 
 | |
|   std::size_t total_size() const
 | |
|   {
 | |
|     return total_buffer_size_;
 | |
|   }
 | |
| 
 | |
|   registered_buffer_id registered_id() const
 | |
|   {
 | |
|     return registered_buffer_id();
 | |
|   }
 | |
| 
 | |
|   bool all_empty() const
 | |
|   {
 | |
|     return total_buffer_size_ == 0;
 | |
|   }
 | |
| 
 | |
|   static bool all_empty(const asio::const_buffer& buffer_sequence)
 | |
|   {
 | |
|     return buffer_sequence.size() == 0;
 | |
|   }
 | |
| 
 | |
|   static void validate(const asio::const_buffer& buffer_sequence)
 | |
|   {
 | |
|     buffer_sequence.data();
 | |
|   }
 | |
| 
 | |
|   static Buffer first(const asio::const_buffer& buffer_sequence)
 | |
|   {
 | |
|     return Buffer(buffer_sequence);
 | |
|   }
 | |
| 
 | |
|   enum { linearisation_storage_size = 1 };
 | |
| 
 | |
|   static Buffer linearise(const asio::const_buffer& buffer_sequence,
 | |
|       const Buffer&)
 | |
|   {
 | |
|     return Buffer(buffer_sequence);
 | |
|   }
 | |
| 
 | |
| private:
 | |
|   native_buffer_type buffer_;
 | |
|   std::size_t total_buffer_size_;
 | |
| };
 | |
| 
 | |
| #if !defined(ASIO_NO_DEPRECATED)
 | |
| 
 | |
| template <typename Buffer>
 | |
| class buffer_sequence_adapter<Buffer, asio::mutable_buffers_1>
 | |
|   : buffer_sequence_adapter_base
 | |
| {
 | |
| public:
 | |
|   enum { is_single_buffer = true };
 | |
|   enum { is_registered_buffer = false };
 | |
| 
 | |
|   explicit buffer_sequence_adapter(
 | |
|       const asio::mutable_buffers_1& buffer_sequence)
 | |
|   {
 | |
|     init_native_buffer(buffer_, Buffer(buffer_sequence));
 | |
|     total_buffer_size_ = buffer_sequence.size();
 | |
|   }
 | |
| 
 | |
|   native_buffer_type* buffers()
 | |
|   {
 | |
|     return &buffer_;
 | |
|   }
 | |
| 
 | |
|   std::size_t count() const
 | |
|   {
 | |
|     return 1;
 | |
|   }
 | |
| 
 | |
|   std::size_t total_size() const
 | |
|   {
 | |
|     return total_buffer_size_;
 | |
|   }
 | |
| 
 | |
|   registered_buffer_id registered_id() const
 | |
|   {
 | |
|     return registered_buffer_id();
 | |
|   }
 | |
| 
 | |
|   bool all_empty() const
 | |
|   {
 | |
|     return total_buffer_size_ == 0;
 | |
|   }
 | |
| 
 | |
|   static bool all_empty(const asio::mutable_buffers_1& buffer_sequence)
 | |
|   {
 | |
|     return buffer_sequence.size() == 0;
 | |
|   }
 | |
| 
 | |
|   static void validate(const asio::mutable_buffers_1& buffer_sequence)
 | |
|   {
 | |
|     buffer_sequence.data();
 | |
|   }
 | |
| 
 | |
|   static Buffer first(const asio::mutable_buffers_1& buffer_sequence)
 | |
|   {
 | |
|     return Buffer(buffer_sequence);
 | |
|   }
 | |
| 
 | |
|   enum { linearisation_storage_size = 1 };
 | |
| 
 | |
|   static Buffer linearise(const asio::mutable_buffers_1& buffer_sequence,
 | |
|       const Buffer&)
 | |
|   {
 | |
|     return Buffer(buffer_sequence);
 | |
|   }
 | |
| 
 | |
| private:
 | |
|   native_buffer_type buffer_;
 | |
|   std::size_t total_buffer_size_;
 | |
| };
 | |
| 
 | |
| template <typename Buffer>
 | |
| class buffer_sequence_adapter<Buffer, asio::const_buffers_1>
 | |
|   : buffer_sequence_adapter_base
 | |
| {
 | |
| public:
 | |
|   enum { is_single_buffer = true };
 | |
|   enum { is_registered_buffer = false };
 | |
| 
 | |
|   explicit buffer_sequence_adapter(
 | |
|       const asio::const_buffers_1& buffer_sequence)
 | |
|   {
 | |
|     init_native_buffer(buffer_, Buffer(buffer_sequence));
 | |
|     total_buffer_size_ = buffer_sequence.size();
 | |
|   }
 | |
| 
 | |
|   native_buffer_type* buffers()
 | |
|   {
 | |
|     return &buffer_;
 | |
|   }
 | |
| 
 | |
|   std::size_t count() const
 | |
|   {
 | |
|     return 1;
 | |
|   }
 | |
| 
 | |
|   std::size_t total_size() const
 | |
|   {
 | |
|     return total_buffer_size_;
 | |
|   }
 | |
| 
 | |
|   registered_buffer_id registered_id() const
 | |
|   {
 | |
|     return registered_buffer_id();
 | |
|   }
 | |
| 
 | |
|   bool all_empty() const
 | |
|   {
 | |
|     return total_buffer_size_ == 0;
 | |
|   }
 | |
| 
 | |
|   static bool all_empty(const asio::const_buffers_1& buffer_sequence)
 | |
|   {
 | |
|     return buffer_sequence.size() == 0;
 | |
|   }
 | |
| 
 | |
|   static void validate(const asio::const_buffers_1& buffer_sequence)
 | |
|   {
 | |
|     buffer_sequence.data();
 | |
|   }
 | |
| 
 | |
|   static Buffer first(const asio::const_buffers_1& buffer_sequence)
 | |
|   {
 | |
|     return Buffer(buffer_sequence);
 | |
|   }
 | |
| 
 | |
|   enum { linearisation_storage_size = 1 };
 | |
| 
 | |
|   static Buffer linearise(const asio::const_buffers_1& buffer_sequence,
 | |
|       const Buffer&)
 | |
|   {
 | |
|     return Buffer(buffer_sequence);
 | |
|   }
 | |
| 
 | |
| private:
 | |
|   native_buffer_type buffer_;
 | |
|   std::size_t total_buffer_size_;
 | |
| };
 | |
| 
 | |
| #endif // !defined(ASIO_NO_DEPRECATED)
 | |
| 
 | |
| template <typename Buffer>
 | |
| class buffer_sequence_adapter<Buffer, asio::mutable_registered_buffer>
 | |
|   : buffer_sequence_adapter_base
 | |
| {
 | |
| public:
 | |
|   enum { is_single_buffer = true };
 | |
|   enum { is_registered_buffer = true };
 | |
| 
 | |
|   explicit buffer_sequence_adapter(
 | |
|       const asio::mutable_registered_buffer& buffer_sequence)
 | |
|   {
 | |
|     init_native_buffer(buffer_, buffer_sequence.buffer());
 | |
|     total_buffer_size_ = buffer_sequence.size();
 | |
|     registered_id_ = buffer_sequence.id();
 | |
|   }
 | |
| 
 | |
|   native_buffer_type* buffers()
 | |
|   {
 | |
|     return &buffer_;
 | |
|   }
 | |
| 
 | |
|   std::size_t count() const
 | |
|   {
 | |
|     return 1;
 | |
|   }
 | |
| 
 | |
|   std::size_t total_size() const
 | |
|   {
 | |
|     return total_buffer_size_;
 | |
|   }
 | |
| 
 | |
|   registered_buffer_id registered_id() const
 | |
|   {
 | |
|     return registered_id_;
 | |
|   }
 | |
| 
 | |
|   bool all_empty() const
 | |
|   {
 | |
|     return total_buffer_size_ == 0;
 | |
|   }
 | |
| 
 | |
|   static bool all_empty(
 | |
|       const asio::mutable_registered_buffer& buffer_sequence)
 | |
|   {
 | |
|     return buffer_sequence.size() == 0;
 | |
|   }
 | |
| 
 | |
|   static void validate(
 | |
|       const asio::mutable_registered_buffer& buffer_sequence)
 | |
|   {
 | |
|     buffer_sequence.data();
 | |
|   }
 | |
| 
 | |
|   static Buffer first(
 | |
|       const asio::mutable_registered_buffer& buffer_sequence)
 | |
|   {
 | |
|     return Buffer(buffer_sequence.buffer());
 | |
|   }
 | |
| 
 | |
|   enum { linearisation_storage_size = 1 };
 | |
| 
 | |
|   static Buffer linearise(
 | |
|       const asio::mutable_registered_buffer& buffer_sequence,
 | |
|       const Buffer&)
 | |
|   {
 | |
|     return Buffer(buffer_sequence.buffer());
 | |
|   }
 | |
| 
 | |
| private:
 | |
|   native_buffer_type buffer_;
 | |
|   std::size_t total_buffer_size_;
 | |
|   registered_buffer_id registered_id_;
 | |
| };
 | |
| 
 | |
| template <typename Buffer>
 | |
| class buffer_sequence_adapter<Buffer, asio::const_registered_buffer>
 | |
|   : buffer_sequence_adapter_base
 | |
| {
 | |
| public:
 | |
|   enum { is_single_buffer = true };
 | |
|   enum { is_registered_buffer = true };
 | |
| 
 | |
|   explicit buffer_sequence_adapter(
 | |
|       const asio::const_registered_buffer& buffer_sequence)
 | |
|   {
 | |
|     init_native_buffer(buffer_, buffer_sequence.buffer());
 | |
|     total_buffer_size_ = buffer_sequence.size();
 | |
|     registered_id_ = buffer_sequence.id();
 | |
|   }
 | |
| 
 | |
|   native_buffer_type* buffers()
 | |
|   {
 | |
|     return &buffer_;
 | |
|   }
 | |
| 
 | |
|   std::size_t count() const
 | |
|   {
 | |
|     return 1;
 | |
|   }
 | |
| 
 | |
|   std::size_t total_size() const
 | |
|   {
 | |
|     return total_buffer_size_;
 | |
|   }
 | |
| 
 | |
|   registered_buffer_id registered_id() const
 | |
|   {
 | |
|     return registered_id_;
 | |
|   }
 | |
| 
 | |
|   bool all_empty() const
 | |
|   {
 | |
|     return total_buffer_size_ == 0;
 | |
|   }
 | |
| 
 | |
|   static bool all_empty(
 | |
|       const asio::const_registered_buffer& buffer_sequence)
 | |
|   {
 | |
|     return buffer_sequence.size() == 0;
 | |
|   }
 | |
| 
 | |
|   static void validate(
 | |
|       const asio::const_registered_buffer& buffer_sequence)
 | |
|   {
 | |
|     buffer_sequence.data();
 | |
|   }
 | |
| 
 | |
|   static Buffer first(
 | |
|       const asio::const_registered_buffer& buffer_sequence)
 | |
|   {
 | |
|     return Buffer(buffer_sequence.buffer());
 | |
|   }
 | |
| 
 | |
|   enum { linearisation_storage_size = 1 };
 | |
| 
 | |
|   static Buffer linearise(
 | |
|       const asio::const_registered_buffer& buffer_sequence,
 | |
|       const Buffer&)
 | |
|   {
 | |
|     return Buffer(buffer_sequence.buffer());
 | |
|   }
 | |
| 
 | |
| private:
 | |
|   native_buffer_type buffer_;
 | |
|   std::size_t total_buffer_size_;
 | |
|   registered_buffer_id registered_id_;
 | |
| };
 | |
| 
 | |
| template <typename Buffer, typename Elem>
 | |
| class buffer_sequence_adapter<Buffer, boost::array<Elem, 2> >
 | |
|   : buffer_sequence_adapter_base
 | |
| {
 | |
| public:
 | |
|   enum { is_single_buffer = false };
 | |
|   enum { is_registered_buffer = false };
 | |
| 
 | |
|   explicit buffer_sequence_adapter(
 | |
|       const boost::array<Elem, 2>& buffer_sequence)
 | |
|   {
 | |
|     init_native_buffer(buffers_[0], Buffer(buffer_sequence[0]));
 | |
|     init_native_buffer(buffers_[1], Buffer(buffer_sequence[1]));
 | |
|     total_buffer_size_ = buffer_sequence[0].size() + buffer_sequence[1].size();
 | |
|   }
 | |
| 
 | |
|   native_buffer_type* buffers()
 | |
|   {
 | |
|     return buffers_;
 | |
|   }
 | |
| 
 | |
|   std::size_t count() const
 | |
|   {
 | |
|     return 2;
 | |
|   }
 | |
| 
 | |
|   std::size_t total_size() const
 | |
|   {
 | |
|     return total_buffer_size_;
 | |
|   }
 | |
| 
 | |
|   registered_buffer_id registered_id() const
 | |
|   {
 | |
|     return registered_buffer_id();
 | |
|   }
 | |
| 
 | |
|   bool all_empty() const
 | |
|   {
 | |
|     return total_buffer_size_ == 0;
 | |
|   }
 | |
| 
 | |
|   static bool all_empty(const boost::array<Elem, 2>& buffer_sequence)
 | |
|   {
 | |
|     return buffer_sequence[0].size() == 0 && buffer_sequence[1].size() == 0;
 | |
|   }
 | |
| 
 | |
|   static void validate(const boost::array<Elem, 2>& buffer_sequence)
 | |
|   {
 | |
|     buffer_sequence[0].data();
 | |
|     buffer_sequence[1].data();
 | |
|   }
 | |
| 
 | |
|   static Buffer first(const boost::array<Elem, 2>& buffer_sequence)
 | |
|   {
 | |
|     return Buffer(buffer_sequence[0].size() != 0
 | |
|         ? buffer_sequence[0] : buffer_sequence[1]);
 | |
|   }
 | |
| 
 | |
|   enum { linearisation_storage_size = 8192 };
 | |
| 
 | |
|   static Buffer linearise(const boost::array<Elem, 2>& buffer_sequence,
 | |
|       const asio::mutable_buffer& storage)
 | |
|   {
 | |
|     if (buffer_sequence[0].size() == 0)
 | |
|       return Buffer(buffer_sequence[1]);
 | |
|     if (buffer_sequence[1].size() == 0)
 | |
|       return Buffer(buffer_sequence[0]);
 | |
|     return Buffer(storage.data(),
 | |
|         asio::buffer_copy(storage, buffer_sequence));
 | |
|   }
 | |
| 
 | |
| private:
 | |
|   native_buffer_type buffers_[2];
 | |
|   std::size_t total_buffer_size_;
 | |
| };
 | |
| 
 | |
| #if defined(ASIO_HAS_STD_ARRAY)
 | |
| 
 | |
| template <typename Buffer, typename Elem>
 | |
| class buffer_sequence_adapter<Buffer, std::array<Elem, 2> >
 | |
|   : buffer_sequence_adapter_base
 | |
| {
 | |
| public:
 | |
|   enum { is_single_buffer = false };
 | |
|   enum { is_registered_buffer = false };
 | |
| 
 | |
|   explicit buffer_sequence_adapter(
 | |
|       const std::array<Elem, 2>& buffer_sequence)
 | |
|   {
 | |
|     init_native_buffer(buffers_[0], Buffer(buffer_sequence[0]));
 | |
|     init_native_buffer(buffers_[1], Buffer(buffer_sequence[1]));
 | |
|     total_buffer_size_ = buffer_sequence[0].size() + buffer_sequence[1].size();
 | |
|   }
 | |
| 
 | |
|   native_buffer_type* buffers()
 | |
|   {
 | |
|     return buffers_;
 | |
|   }
 | |
| 
 | |
|   std::size_t count() const
 | |
|   {
 | |
|     return 2;
 | |
|   }
 | |
| 
 | |
|   std::size_t total_size() const
 | |
|   {
 | |
|     return total_buffer_size_;
 | |
|   }
 | |
| 
 | |
|   registered_buffer_id registered_id() const
 | |
|   {
 | |
|     return registered_buffer_id();
 | |
|   }
 | |
| 
 | |
|   bool all_empty() const
 | |
|   {
 | |
|     return total_buffer_size_ == 0;
 | |
|   }
 | |
| 
 | |
|   static bool all_empty(const std::array<Elem, 2>& buffer_sequence)
 | |
|   {
 | |
|     return buffer_sequence[0].size() == 0 && buffer_sequence[1].size() == 0;
 | |
|   }
 | |
| 
 | |
|   static void validate(const std::array<Elem, 2>& buffer_sequence)
 | |
|   {
 | |
|     buffer_sequence[0].data();
 | |
|     buffer_sequence[1].data();
 | |
|   }
 | |
| 
 | |
|   static Buffer first(const std::array<Elem, 2>& buffer_sequence)
 | |
|   {
 | |
|     return Buffer(buffer_sequence[0].size() != 0
 | |
|         ? buffer_sequence[0] : buffer_sequence[1]);
 | |
|   }
 | |
| 
 | |
|   enum { linearisation_storage_size = 8192 };
 | |
| 
 | |
|   static Buffer linearise(const std::array<Elem, 2>& buffer_sequence,
 | |
|       const asio::mutable_buffer& storage)
 | |
|   {
 | |
|     if (buffer_sequence[0].size() == 0)
 | |
|       return Buffer(buffer_sequence[1]);
 | |
|     if (buffer_sequence[1].size() == 0)
 | |
|       return Buffer(buffer_sequence[0]);
 | |
|     return Buffer(storage.data(),
 | |
|         asio::buffer_copy(storage, buffer_sequence));
 | |
|   }
 | |
| 
 | |
| private:
 | |
|   native_buffer_type buffers_[2];
 | |
|   std::size_t total_buffer_size_;
 | |
| };
 | |
| 
 | |
| #endif // defined(ASIO_HAS_STD_ARRAY)
 | |
| 
 | |
| } // namespace detail
 | |
| } // namespace asio
 | |
| 
 | |
| #include "asio/detail/pop_options.hpp"
 | |
| 
 | |
| #if defined(ASIO_HEADER_ONLY)
 | |
| # include "asio/detail/impl/buffer_sequence_adapter.ipp"
 | |
| #endif // defined(ASIO_HEADER_ONLY)
 | |
| 
 | |
| #endif // ASIO_DETAIL_BUFFER_SEQUENCE_ADAPTER_HPP
 |