2 // detail/buffer_sequence_adapter.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 // Copyright (c) 2003-2017 Christopher M. Kohlhoff (chris at kohlhoff dot com)
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
11 #ifndef BOOST_ASIO_DETAIL_BUFFER_SEQUENCE_ADAPTER_HPP
12 #define BOOST_ASIO_DETAIL_BUFFER_SEQUENCE_ADAPTER_HPP
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
18 #include <boost/asio/detail/config.hpp>
19 #include <boost/asio/buffer.hpp>
20 #include <boost/asio/detail/array_fwd.hpp>
21 #include <boost/asio/detail/socket_types.hpp>
23 #include <boost/asio/detail/push_options.hpp>
29 class buffer_sequence_adapter_base
31 #if defined(BOOST_ASIO_WINDOWS_RUNTIME)
33 // The maximum number of buffers to support in a single operation.
34 enum { max_buffers = 1 };
37 typedef Windows::Storage::Streams::IBuffer^ native_buffer_type;
39 BOOST_ASIO_DECL static void init_native_buffer(
40 native_buffer_type& buf,
41 const boost::asio::mutable_buffer& buffer);
43 BOOST_ASIO_DECL static void init_native_buffer(
44 native_buffer_type& buf,
45 const boost::asio::const_buffer& buffer);
46 #elif defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
48 // The maximum number of buffers to support in a single operation.
49 enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len };
52 typedef WSABUF native_buffer_type;
54 static void init_native_buffer(WSABUF& buf,
55 const boost::asio::mutable_buffer& buffer)
57 buf.buf = static_cast<char*>(buffer.data());
58 buf.len = static_cast<ULONG>(buffer.size());
61 static void init_native_buffer(WSABUF& buf,
62 const boost::asio::const_buffer& buffer)
64 buf.buf = const_cast<char*>(static_cast<const char*>(buffer.data()));
65 buf.len = static_cast<ULONG>(buffer.size());
67 #else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
69 // The maximum number of buffers to support in a single operation.
70 enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len };
73 typedef iovec native_buffer_type;
75 static void init_iov_base(void*& base, void* addr)
81 static void init_iov_base(T& base, void* addr)
83 base = static_cast<T>(addr);
86 static void init_native_buffer(iovec& iov,
87 const boost::asio::mutable_buffer& buffer)
89 init_iov_base(iov.iov_base, buffer.data());
90 iov.iov_len = buffer.size();
93 static void init_native_buffer(iovec& iov,
94 const boost::asio::const_buffer& buffer)
96 init_iov_base(iov.iov_base, const_cast<void*>(buffer.data()));
97 iov.iov_len = buffer.size();
99 #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
102 // Helper class to translate buffers into the native buffer representation.
103 template <typename Buffer, typename Buffers>
104 class buffer_sequence_adapter
105 : buffer_sequence_adapter_base
108 explicit buffer_sequence_adapter(const Buffers& buffer_sequence)
109 : count_(0), total_buffer_size_(0)
111 buffer_sequence_adapter::init(
112 boost::asio::buffer_sequence_begin(buffer_sequence),
113 boost::asio::buffer_sequence_end(buffer_sequence));
116 native_buffer_type* buffers()
121 std::size_t count() const
126 std::size_t total_size() const
128 return total_buffer_size_;
131 bool all_empty() const
133 return total_buffer_size_ == 0;
136 static bool all_empty(const Buffers& buffer_sequence)
138 return buffer_sequence_adapter::all_empty(
139 boost::asio::buffer_sequence_begin(buffer_sequence),
140 boost::asio::buffer_sequence_end(buffer_sequence));
143 static void validate(const Buffers& buffer_sequence)
145 buffer_sequence_adapter::validate(
146 boost::asio::buffer_sequence_begin(buffer_sequence),
147 boost::asio::buffer_sequence_end(buffer_sequence));
150 static Buffer first(const Buffers& buffer_sequence)
152 return buffer_sequence_adapter::first(
153 boost::asio::buffer_sequence_begin(buffer_sequence),
154 boost::asio::buffer_sequence_end(buffer_sequence));
158 template <typename Iterator>
159 void init(Iterator begin, Iterator end)
161 Iterator iter = begin;
162 for (; iter != end && count_ < max_buffers; ++iter, ++count_)
164 Buffer buffer(*iter);
165 init_native_buffer(buffers_[count_], buffer);
166 total_buffer_size_ += buffer.size();
170 template <typename Iterator>
171 static bool all_empty(Iterator begin, Iterator end)
173 Iterator iter = begin;
175 for (; iter != end && i < max_buffers; ++iter, ++i)
176 if (Buffer(*iter).size() > 0)
181 template <typename Iterator>
182 static void validate(Iterator begin, Iterator end)
184 Iterator iter = begin;
185 for (; iter != end; ++iter)
187 Buffer buffer(*iter);
192 template <typename Iterator>
193 static Buffer first(Iterator begin, Iterator end)
195 Iterator iter = begin;
196 for (; iter != end; ++iter)
198 Buffer buffer(*iter);
199 if (buffer.size() != 0)
205 native_buffer_type buffers_[max_buffers];
207 std::size_t total_buffer_size_;
210 template <typename Buffer>
211 class buffer_sequence_adapter<Buffer, boost::asio::mutable_buffer>
212 : buffer_sequence_adapter_base
215 explicit buffer_sequence_adapter(
216 const boost::asio::mutable_buffer& buffer_sequence)
218 init_native_buffer(buffer_, Buffer(buffer_sequence));
219 total_buffer_size_ = buffer_sequence.size();
222 native_buffer_type* buffers()
227 std::size_t count() const
232 std::size_t total_size() const
234 return total_buffer_size_;
237 bool all_empty() const
239 return total_buffer_size_ == 0;
242 static bool all_empty(const boost::asio::mutable_buffer& buffer_sequence)
244 return buffer_sequence.size() == 0;
247 static void validate(const boost::asio::mutable_buffer& buffer_sequence)
249 buffer_sequence.data();
252 static Buffer first(const boost::asio::mutable_buffer& buffer_sequence)
254 return Buffer(buffer_sequence);
258 native_buffer_type buffer_;
259 std::size_t total_buffer_size_;
262 template <typename Buffer>
263 class buffer_sequence_adapter<Buffer, boost::asio::const_buffer>
264 : buffer_sequence_adapter_base
267 explicit buffer_sequence_adapter(
268 const boost::asio::const_buffer& buffer_sequence)
270 init_native_buffer(buffer_, Buffer(buffer_sequence));
271 total_buffer_size_ = buffer_sequence.size();
274 native_buffer_type* buffers()
279 std::size_t count() const
284 std::size_t total_size() const
286 return total_buffer_size_;
289 bool all_empty() const
291 return total_buffer_size_ == 0;
294 static bool all_empty(const boost::asio::const_buffer& buffer_sequence)
296 return buffer_sequence.size() == 0;
299 static void validate(const boost::asio::const_buffer& buffer_sequence)
301 buffer_sequence.data();
304 static Buffer first(const boost::asio::const_buffer& buffer_sequence)
306 return Buffer(buffer_sequence);
310 native_buffer_type buffer_;
311 std::size_t total_buffer_size_;
314 #if !defined(BOOST_ASIO_NO_DEPRECATED)
316 template <typename Buffer>
317 class buffer_sequence_adapter<Buffer, boost::asio::mutable_buffers_1>
318 : buffer_sequence_adapter_base
321 explicit buffer_sequence_adapter(
322 const boost::asio::mutable_buffers_1& buffer_sequence)
324 init_native_buffer(buffer_, Buffer(buffer_sequence));
325 total_buffer_size_ = buffer_sequence.size();
328 native_buffer_type* buffers()
333 std::size_t count() const
338 std::size_t total_size() const
340 return total_buffer_size_;
343 bool all_empty() const
345 return total_buffer_size_ == 0;
348 static bool all_empty(const boost::asio::mutable_buffers_1& buffer_sequence)
350 return buffer_sequence.size() == 0;
353 static void validate(const boost::asio::mutable_buffers_1& buffer_sequence)
355 buffer_sequence.data();
358 static Buffer first(const boost::asio::mutable_buffers_1& buffer_sequence)
360 return Buffer(buffer_sequence);
364 native_buffer_type buffer_;
365 std::size_t total_buffer_size_;
368 template <typename Buffer>
369 class buffer_sequence_adapter<Buffer, boost::asio::const_buffers_1>
370 : buffer_sequence_adapter_base
373 explicit buffer_sequence_adapter(
374 const boost::asio::const_buffers_1& buffer_sequence)
376 init_native_buffer(buffer_, Buffer(buffer_sequence));
377 total_buffer_size_ = buffer_sequence.size();
380 native_buffer_type* buffers()
385 std::size_t count() const
390 std::size_t total_size() const
392 return total_buffer_size_;
395 bool all_empty() const
397 return total_buffer_size_ == 0;
400 static bool all_empty(const boost::asio::const_buffers_1& buffer_sequence)
402 return buffer_sequence.size() == 0;
405 static void validate(const boost::asio::const_buffers_1& buffer_sequence)
407 buffer_sequence.data();
410 static Buffer first(const boost::asio::const_buffers_1& buffer_sequence)
412 return Buffer(buffer_sequence);
416 native_buffer_type buffer_;
417 std::size_t total_buffer_size_;
420 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
422 template <typename Buffer, typename Elem>
423 class buffer_sequence_adapter<Buffer, boost::array<Elem, 2> >
424 : buffer_sequence_adapter_base
427 explicit buffer_sequence_adapter(
428 const boost::array<Elem, 2>& buffer_sequence)
430 init_native_buffer(buffers_[0], Buffer(buffer_sequence[0]));
431 init_native_buffer(buffers_[1], Buffer(buffer_sequence[1]));
432 total_buffer_size_ = buffer_sequence[0].size() + buffer_sequence[1].size();
435 native_buffer_type* buffers()
440 std::size_t count() const
445 std::size_t total_size() const
447 return total_buffer_size_;
450 bool all_empty() const
452 return total_buffer_size_ == 0;
455 static bool all_empty(const boost::array<Elem, 2>& buffer_sequence)
457 return buffer_sequence[0].size() == 0 && buffer_sequence[1].size() == 0;
460 static void validate(const boost::array<Elem, 2>& buffer_sequence)
462 buffer_sequence[0].data();
463 buffer_sequence[1].data();
466 static Buffer first(const boost::array<Elem, 2>& buffer_sequence)
468 return Buffer(buffer_sequence[0].size() != 0
469 ? buffer_sequence[0] : buffer_sequence[1]);
473 native_buffer_type buffers_[2];
474 std::size_t total_buffer_size_;
477 #if defined(BOOST_ASIO_HAS_STD_ARRAY)
479 template <typename Buffer, typename Elem>
480 class buffer_sequence_adapter<Buffer, std::array<Elem, 2> >
481 : buffer_sequence_adapter_base
484 explicit buffer_sequence_adapter(
485 const std::array<Elem, 2>& buffer_sequence)
487 init_native_buffer(buffers_[0], Buffer(buffer_sequence[0]));
488 init_native_buffer(buffers_[1], Buffer(buffer_sequence[1]));
489 total_buffer_size_ = buffer_sequence[0].size() + buffer_sequence[1].size();
492 native_buffer_type* buffers()
497 std::size_t count() const
502 std::size_t total_size() const
504 return total_buffer_size_;
507 bool all_empty() const
509 return total_buffer_size_ == 0;
512 static bool all_empty(const std::array<Elem, 2>& buffer_sequence)
514 return buffer_sequence[0].size() == 0 && buffer_sequence[1].size() == 0;
517 static void validate(const std::array<Elem, 2>& buffer_sequence)
519 buffer_sequence[0].data();
520 buffer_sequence[1].data();
523 static Buffer first(const std::array<Elem, 2>& buffer_sequence)
525 return Buffer(buffer_sequence[0].size() != 0
526 ? buffer_sequence[0] : buffer_sequence[1]);
530 native_buffer_type buffers_[2];
531 std::size_t total_buffer_size_;
534 #endif // defined(BOOST_ASIO_HAS_STD_ARRAY)
536 } // namespace detail
540 #include <boost/asio/detail/pop_options.hpp>
542 #if defined(BOOST_ASIO_HEADER_ONLY)
543 # include <boost/asio/detail/impl/buffer_sequence_adapter.ipp>
544 #endif // defined(BOOST_ASIO_HEADER_ONLY)
546 #endif // BOOST_ASIO_DETAIL_BUFFER_SEQUENCE_ADAPTER_HPP