]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/asio/include/boost/asio/detail/buffer_sequence_adapter.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / asio / include / boost / asio / detail / buffer_sequence_adapter.hpp
1 //
2 // detail/buffer_sequence_adapter.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
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)
9 //
10
11 #ifndef BOOST_ASIO_DETAIL_BUFFER_SEQUENCE_ADAPTER_HPP
12 #define BOOST_ASIO_DETAIL_BUFFER_SEQUENCE_ADAPTER_HPP
13
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17
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>
22
23 #include <boost/asio/detail/push_options.hpp>
24
25 namespace boost {
26 namespace asio {
27 namespace detail {
28
29 class buffer_sequence_adapter_base
30 {
31 protected:
32 #if defined(BOOST_ASIO_WINDOWS_RUNTIME)
33 // The maximum number of buffers to support in a single operation.
34 enum { max_buffers = 1 };
35
36 typedef Windows::Storage::Streams::IBuffer^ native_buffer_type;
37
38 BOOST_ASIO_DECL static void init_native_buffer(
39 native_buffer_type& buf,
40 const boost::asio::mutable_buffer& buffer);
41
42 BOOST_ASIO_DECL static void init_native_buffer(
43 native_buffer_type& buf,
44 const boost::asio::const_buffer& buffer);
45 #elif defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
46 // The maximum number of buffers to support in a single operation.
47 enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len };
48
49 typedef WSABUF native_buffer_type;
50
51 static void init_native_buffer(WSABUF& buf,
52 const boost::asio::mutable_buffer& buffer)
53 {
54 buf.buf = boost::asio::buffer_cast<char*>(buffer);
55 buf.len = static_cast<ULONG>(boost::asio::buffer_size(buffer));
56 }
57
58 static void init_native_buffer(WSABUF& buf,
59 const boost::asio::const_buffer& buffer)
60 {
61 buf.buf = const_cast<char*>(boost::asio::buffer_cast<const char*>(buffer));
62 buf.len = static_cast<ULONG>(boost::asio::buffer_size(buffer));
63 }
64 #else // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
65 // The maximum number of buffers to support in a single operation.
66 enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len };
67
68 typedef iovec native_buffer_type;
69
70 static void init_iov_base(void*& base, void* addr)
71 {
72 base = addr;
73 }
74
75 template <typename T>
76 static void init_iov_base(T& base, void* addr)
77 {
78 base = static_cast<T>(addr);
79 }
80
81 static void init_native_buffer(iovec& iov,
82 const boost::asio::mutable_buffer& buffer)
83 {
84 init_iov_base(iov.iov_base, boost::asio::buffer_cast<void*>(buffer));
85 iov.iov_len = boost::asio::buffer_size(buffer);
86 }
87
88 static void init_native_buffer(iovec& iov,
89 const boost::asio::const_buffer& buffer)
90 {
91 init_iov_base(iov.iov_base, const_cast<void*>(
92 boost::asio::buffer_cast<const void*>(buffer)));
93 iov.iov_len = boost::asio::buffer_size(buffer);
94 }
95 #endif // defined(BOOST_ASIO_WINDOWS) || defined(__CYGWIN__)
96 };
97
98 // Helper class to translate buffers into the native buffer representation.
99 template <typename Buffer, typename Buffers>
100 class buffer_sequence_adapter
101 : buffer_sequence_adapter_base
102 {
103 public:
104 explicit buffer_sequence_adapter(const Buffers& buffer_sequence)
105 : count_(0), total_buffer_size_(0)
106 {
107 typename Buffers::const_iterator iter = buffer_sequence.begin();
108 typename Buffers::const_iterator end = buffer_sequence.end();
109 for (; iter != end && count_ < max_buffers; ++iter, ++count_)
110 {
111 Buffer buffer(*iter);
112 init_native_buffer(buffers_[count_], buffer);
113 total_buffer_size_ += boost::asio::buffer_size(buffer);
114 }
115 }
116
117 native_buffer_type* buffers()
118 {
119 return buffers_;
120 }
121
122 std::size_t count() const
123 {
124 return count_;
125 }
126
127 bool all_empty() const
128 {
129 return total_buffer_size_ == 0;
130 }
131
132 static bool all_empty(const Buffers& buffer_sequence)
133 {
134 typename Buffers::const_iterator iter = buffer_sequence.begin();
135 typename Buffers::const_iterator end = buffer_sequence.end();
136 std::size_t i = 0;
137 for (; iter != end && i < max_buffers; ++iter, ++i)
138 if (boost::asio::buffer_size(Buffer(*iter)) > 0)
139 return false;
140 return true;
141 }
142
143 static void validate(const Buffers& buffer_sequence)
144 {
145 typename Buffers::const_iterator iter = buffer_sequence.begin();
146 typename Buffers::const_iterator end = buffer_sequence.end();
147 for (; iter != end; ++iter)
148 {
149 Buffer buffer(*iter);
150 boost::asio::buffer_cast<const void*>(buffer);
151 }
152 }
153
154 static Buffer first(const Buffers& buffer_sequence)
155 {
156 typename Buffers::const_iterator iter = buffer_sequence.begin();
157 typename Buffers::const_iterator end = buffer_sequence.end();
158 for (; iter != end; ++iter)
159 {
160 Buffer buffer(*iter);
161 if (boost::asio::buffer_size(buffer) != 0)
162 return buffer;
163 }
164 return Buffer();
165 }
166
167 private:
168 native_buffer_type buffers_[max_buffers];
169 std::size_t count_;
170 std::size_t total_buffer_size_;
171 };
172
173 template <typename Buffer>
174 class buffer_sequence_adapter<Buffer, boost::asio::mutable_buffers_1>
175 : buffer_sequence_adapter_base
176 {
177 public:
178 explicit buffer_sequence_adapter(
179 const boost::asio::mutable_buffers_1& buffer_sequence)
180 {
181 init_native_buffer(buffer_, Buffer(buffer_sequence));
182 total_buffer_size_ = boost::asio::buffer_size(buffer_sequence);
183 }
184
185 native_buffer_type* buffers()
186 {
187 return &buffer_;
188 }
189
190 std::size_t count() const
191 {
192 return 1;
193 }
194
195 bool all_empty() const
196 {
197 return total_buffer_size_ == 0;
198 }
199
200 static bool all_empty(const boost::asio::mutable_buffers_1& buffer_sequence)
201 {
202 return boost::asio::buffer_size(buffer_sequence) == 0;
203 }
204
205 static void validate(const boost::asio::mutable_buffers_1& buffer_sequence)
206 {
207 boost::asio::buffer_cast<const void*>(buffer_sequence);
208 }
209
210 static Buffer first(const boost::asio::mutable_buffers_1& buffer_sequence)
211 {
212 return Buffer(buffer_sequence);
213 }
214
215 private:
216 native_buffer_type buffer_;
217 std::size_t total_buffer_size_;
218 };
219
220 template <typename Buffer>
221 class buffer_sequence_adapter<Buffer, boost::asio::const_buffers_1>
222 : buffer_sequence_adapter_base
223 {
224 public:
225 explicit buffer_sequence_adapter(
226 const boost::asio::const_buffers_1& buffer_sequence)
227 {
228 init_native_buffer(buffer_, Buffer(buffer_sequence));
229 total_buffer_size_ = boost::asio::buffer_size(buffer_sequence);
230 }
231
232 native_buffer_type* buffers()
233 {
234 return &buffer_;
235 }
236
237 std::size_t count() const
238 {
239 return 1;
240 }
241
242 bool all_empty() const
243 {
244 return total_buffer_size_ == 0;
245 }
246
247 static bool all_empty(const boost::asio::const_buffers_1& buffer_sequence)
248 {
249 return boost::asio::buffer_size(buffer_sequence) == 0;
250 }
251
252 static void validate(const boost::asio::const_buffers_1& buffer_sequence)
253 {
254 boost::asio::buffer_cast<const void*>(buffer_sequence);
255 }
256
257 static Buffer first(const boost::asio::const_buffers_1& buffer_sequence)
258 {
259 return Buffer(buffer_sequence);
260 }
261
262 private:
263 native_buffer_type buffer_;
264 std::size_t total_buffer_size_;
265 };
266
267 template <typename Buffer, typename Elem>
268 class buffer_sequence_adapter<Buffer, boost::array<Elem, 2> >
269 : buffer_sequence_adapter_base
270 {
271 public:
272 explicit buffer_sequence_adapter(
273 const boost::array<Elem, 2>& buffer_sequence)
274 {
275 init_native_buffer(buffers_[0], Buffer(buffer_sequence[0]));
276 init_native_buffer(buffers_[1], Buffer(buffer_sequence[1]));
277 total_buffer_size_ = boost::asio::buffer_size(buffer_sequence[0])
278 + boost::asio::buffer_size(buffer_sequence[1]);
279 }
280
281 native_buffer_type* buffers()
282 {
283 return buffers_;
284 }
285
286 std::size_t count() const
287 {
288 return 2;
289 }
290
291 bool all_empty() const
292 {
293 return total_buffer_size_ == 0;
294 }
295
296 static bool all_empty(const boost::array<Elem, 2>& buffer_sequence)
297 {
298 return boost::asio::buffer_size(buffer_sequence[0]) == 0
299 && boost::asio::buffer_size(buffer_sequence[1]) == 0;
300 }
301
302 static void validate(const boost::array<Elem, 2>& buffer_sequence)
303 {
304 boost::asio::buffer_cast<const void*>(buffer_sequence[0]);
305 boost::asio::buffer_cast<const void*>(buffer_sequence[1]);
306 }
307
308 static Buffer first(const boost::array<Elem, 2>& buffer_sequence)
309 {
310 return Buffer(boost::asio::buffer_size(buffer_sequence[0]) != 0
311 ? buffer_sequence[0] : buffer_sequence[1]);
312 }
313
314 private:
315 native_buffer_type buffers_[2];
316 std::size_t total_buffer_size_;
317 };
318
319 #if defined(BOOST_ASIO_HAS_STD_ARRAY)
320
321 template <typename Buffer, typename Elem>
322 class buffer_sequence_adapter<Buffer, std::array<Elem, 2> >
323 : buffer_sequence_adapter_base
324 {
325 public:
326 explicit buffer_sequence_adapter(
327 const std::array<Elem, 2>& buffer_sequence)
328 {
329 init_native_buffer(buffers_[0], Buffer(buffer_sequence[0]));
330 init_native_buffer(buffers_[1], Buffer(buffer_sequence[1]));
331 total_buffer_size_ = boost::asio::buffer_size(buffer_sequence[0])
332 + boost::asio::buffer_size(buffer_sequence[1]);
333 }
334
335 native_buffer_type* buffers()
336 {
337 return buffers_;
338 }
339
340 std::size_t count() const
341 {
342 return 2;
343 }
344
345 bool all_empty() const
346 {
347 return total_buffer_size_ == 0;
348 }
349
350 static bool all_empty(const std::array<Elem, 2>& buffer_sequence)
351 {
352 return boost::asio::buffer_size(buffer_sequence[0]) == 0
353 && boost::asio::buffer_size(buffer_sequence[1]) == 0;
354 }
355
356 static void validate(const std::array<Elem, 2>& buffer_sequence)
357 {
358 boost::asio::buffer_cast<const void*>(buffer_sequence[0]);
359 boost::asio::buffer_cast<const void*>(buffer_sequence[1]);
360 }
361
362 static Buffer first(const std::array<Elem, 2>& buffer_sequence)
363 {
364 return Buffer(boost::asio::buffer_size(buffer_sequence[0]) != 0
365 ? buffer_sequence[0] : buffer_sequence[1]);
366 }
367
368 private:
369 native_buffer_type buffers_[2];
370 std::size_t total_buffer_size_;
371 };
372
373 #endif // defined(BOOST_ASIO_HAS_STD_ARRAY)
374
375 } // namespace detail
376 } // namespace asio
377 } // namespace boost
378
379 #include <boost/asio/detail/pop_options.hpp>
380
381 #if defined(BOOST_ASIO_HEADER_ONLY)
382 # include <boost/asio/detail/impl/buffer_sequence_adapter.ipp>
383 #endif // defined(BOOST_ASIO_HEADER_ONLY)
384
385 #endif // BOOST_ASIO_DETAIL_BUFFER_SEQUENCE_ADAPTER_HPP