123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652 |
- //
- // detail/buffer_sequence_adapter.hpp
- // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //
- // Copyright (c) 2003-2021 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_DETAIL_BUFFER_SEQUENCE_ADAPTER_HPP
- #define BOOST_ASIO_DETAIL_BUFFER_SEQUENCE_ADAPTER_HPP
- #if defined(_MSC_VER) && (_MSC_VER >= 1200)
- # pragma once
- #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
- #include <boost/asio/detail/config.hpp>
- #include <boost/asio/buffer.hpp>
- #include <boost/asio/detail/array_fwd.hpp>
- #include <boost/asio/detail/socket_types.hpp>
- #include <boost/asio/detail/push_options.hpp>
- namespace boost {
- namespace asio {
- namespace detail {
- class buffer_sequence_adapter_base
- {
- #if defined(BOOST_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;
- BOOST_ASIO_DECL static void init_native_buffer(
- native_buffer_type& buf,
- const boost::asio::mutable_buffer& buffer);
- BOOST_ASIO_DECL static void init_native_buffer(
- native_buffer_type& buf,
- const boost::asio::const_buffer& buffer);
- #elif defined(BOOST_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 boost::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 boost::asio::const_buffer& buffer)
- {
- buf.buf = const_cast<char*>(static_cast<const char*>(buffer.data()));
- buf.len = static_cast<ULONG>(buffer.size());
- }
- #else // defined(BOOST_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 boost::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 boost::asio::const_buffer& buffer)
- {
- init_iov_base(iov.iov_base, const_cast<void*>(buffer.data()));
- iov.iov_len = buffer.size();
- }
- #endif // defined(BOOST_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 };
- explicit buffer_sequence_adapter(const Buffers& buffer_sequence)
- : count_(0), total_buffer_size_(0)
- {
- buffer_sequence_adapter::init(
- boost::asio::buffer_sequence_begin(buffer_sequence),
- boost::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_;
- }
- bool all_empty() const
- {
- return total_buffer_size_ == 0;
- }
- static bool all_empty(const Buffers& buffer_sequence)
- {
- return buffer_sequence_adapter::all_empty(
- boost::asio::buffer_sequence_begin(buffer_sequence),
- boost::asio::buffer_sequence_end(buffer_sequence));
- }
- static void validate(const Buffers& buffer_sequence)
- {
- buffer_sequence_adapter::validate(
- boost::asio::buffer_sequence_begin(buffer_sequence),
- boost::asio::buffer_sequence_end(buffer_sequence));
- }
- static Buffer first(const Buffers& buffer_sequence)
- {
- return buffer_sequence_adapter::first(
- boost::asio::buffer_sequence_begin(buffer_sequence),
- boost::asio::buffer_sequence_end(buffer_sequence));
- }
- enum { linearisation_storage_size = 8192 };
- static Buffer linearise(const Buffers& buffer_sequence,
- const boost::asio::mutable_buffer& storage)
- {
- return buffer_sequence_adapter::linearise(
- boost::asio::buffer_sequence_begin(buffer_sequence),
- boost::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 boost::asio::mutable_buffer& storage)
- {
- boost::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 += boost::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, boost::asio::mutable_buffer>
- : buffer_sequence_adapter_base
- {
- public:
- enum { is_single_buffer = true };
- explicit buffer_sequence_adapter(
- const boost::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_;
- }
- bool all_empty() const
- {
- return total_buffer_size_ == 0;
- }
- static bool all_empty(const boost::asio::mutable_buffer& buffer_sequence)
- {
- return buffer_sequence.size() == 0;
- }
- static void validate(const boost::asio::mutable_buffer& buffer_sequence)
- {
- buffer_sequence.data();
- }
- static Buffer first(const boost::asio::mutable_buffer& buffer_sequence)
- {
- return Buffer(buffer_sequence);
- }
- enum { linearisation_storage_size = 1 };
- static Buffer linearise(const boost::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, boost::asio::const_buffer>
- : buffer_sequence_adapter_base
- {
- public:
- enum { is_single_buffer = true };
- explicit buffer_sequence_adapter(
- const boost::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_;
- }
- bool all_empty() const
- {
- return total_buffer_size_ == 0;
- }
- static bool all_empty(const boost::asio::const_buffer& buffer_sequence)
- {
- return buffer_sequence.size() == 0;
- }
- static void validate(const boost::asio::const_buffer& buffer_sequence)
- {
- buffer_sequence.data();
- }
- static Buffer first(const boost::asio::const_buffer& buffer_sequence)
- {
- return Buffer(buffer_sequence);
- }
- enum { linearisation_storage_size = 1 };
- static Buffer linearise(const boost::asio::const_buffer& buffer_sequence,
- const Buffer&)
- {
- return Buffer(buffer_sequence);
- }
- private:
- native_buffer_type buffer_;
- std::size_t total_buffer_size_;
- };
- #if !defined(BOOST_ASIO_NO_DEPRECATED)
- template <typename Buffer>
- class buffer_sequence_adapter<Buffer, boost::asio::mutable_buffers_1>
- : buffer_sequence_adapter_base
- {
- public:
- enum { is_single_buffer = true };
- explicit buffer_sequence_adapter(
- const boost::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_;
- }
- bool all_empty() const
- {
- return total_buffer_size_ == 0;
- }
- static bool all_empty(const boost::asio::mutable_buffers_1& buffer_sequence)
- {
- return buffer_sequence.size() == 0;
- }
- static void validate(const boost::asio::mutable_buffers_1& buffer_sequence)
- {
- buffer_sequence.data();
- }
- static Buffer first(const boost::asio::mutable_buffers_1& buffer_sequence)
- {
- return Buffer(buffer_sequence);
- }
- enum { linearisation_storage_size = 1 };
- static Buffer linearise(const boost::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, boost::asio::const_buffers_1>
- : buffer_sequence_adapter_base
- {
- public:
- enum { is_single_buffer = true };
- explicit buffer_sequence_adapter(
- const boost::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_;
- }
- bool all_empty() const
- {
- return total_buffer_size_ == 0;
- }
- static bool all_empty(const boost::asio::const_buffers_1& buffer_sequence)
- {
- return buffer_sequence.size() == 0;
- }
- static void validate(const boost::asio::const_buffers_1& buffer_sequence)
- {
- buffer_sequence.data();
- }
- static Buffer first(const boost::asio::const_buffers_1& buffer_sequence)
- {
- return Buffer(buffer_sequence);
- }
- enum { linearisation_storage_size = 1 };
- static Buffer linearise(const boost::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(BOOST_ASIO_NO_DEPRECATED)
- template <typename Buffer, typename Elem>
- class buffer_sequence_adapter<Buffer, boost::array<Elem, 2> >
- : buffer_sequence_adapter_base
- {
- public:
- enum { is_single_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_;
- }
- 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 boost::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(),
- boost::asio::buffer_copy(storage, buffer_sequence));
- }
- private:
- native_buffer_type buffers_[2];
- std::size_t total_buffer_size_;
- };
- #if defined(BOOST_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 };
- 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_;
- }
- 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 boost::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(),
- boost::asio::buffer_copy(storage, buffer_sequence));
- }
- private:
- native_buffer_type buffers_[2];
- std::size_t total_buffer_size_;
- };
- #endif // defined(BOOST_ASIO_HAS_STD_ARRAY)
- } // namespace detail
- } // namespace asio
- } // namespace boost
- #include <boost/asio/detail/pop_options.hpp>
- #if defined(BOOST_ASIO_HEADER_ONLY)
- # include <boost/asio/detail/impl/buffer_sequence_adapter.ipp>
- #endif // defined(BOOST_ASIO_HEADER_ONLY)
- #endif // BOOST_ASIO_DETAIL_BUFFER_SEQUENCE_ADAPTER_HPP
|