Chris@16
|
1 //
|
Chris@16
|
2 // buffer.hpp
|
Chris@16
|
3 // ~~~~~~~~~~
|
Chris@16
|
4 //
|
Chris@101
|
5 // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
Chris@16
|
6 //
|
Chris@16
|
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
|
Chris@16
|
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
9 //
|
Chris@16
|
10
|
Chris@16
|
11 #ifndef BOOST_ASIO_BUFFER_HPP
|
Chris@16
|
12 #define BOOST_ASIO_BUFFER_HPP
|
Chris@16
|
13
|
Chris@16
|
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
Chris@16
|
15 # pragma once
|
Chris@16
|
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
Chris@16
|
17
|
Chris@16
|
18 #include <boost/asio/detail/config.hpp>
|
Chris@16
|
19 #include <cstddef>
|
Chris@16
|
20 #include <cstring>
|
Chris@16
|
21 #include <string>
|
Chris@16
|
22 #include <vector>
|
Chris@16
|
23 #include <boost/asio/detail/array_fwd.hpp>
|
Chris@16
|
24
|
Chris@16
|
25 #if defined(BOOST_ASIO_MSVC)
|
Chris@16
|
26 # if defined(_HAS_ITERATOR_DEBUGGING) && (_HAS_ITERATOR_DEBUGGING != 0)
|
Chris@16
|
27 # if !defined(BOOST_ASIO_DISABLE_BUFFER_DEBUGGING)
|
Chris@16
|
28 # define BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
|
Chris@16
|
29 # endif // !defined(BOOST_ASIO_DISABLE_BUFFER_DEBUGGING)
|
Chris@16
|
30 # endif // defined(_HAS_ITERATOR_DEBUGGING)
|
Chris@16
|
31 #endif // defined(BOOST_ASIO_MSVC)
|
Chris@16
|
32
|
Chris@16
|
33 #if defined(__GNUC__)
|
Chris@16
|
34 # if defined(_GLIBCXX_DEBUG)
|
Chris@16
|
35 # if !defined(BOOST_ASIO_DISABLE_BUFFER_DEBUGGING)
|
Chris@16
|
36 # define BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
|
Chris@16
|
37 # endif // !defined(BOOST_ASIO_DISABLE_BUFFER_DEBUGGING)
|
Chris@16
|
38 # endif // defined(_GLIBCXX_DEBUG)
|
Chris@16
|
39 #endif // defined(__GNUC__)
|
Chris@16
|
40
|
Chris@16
|
41 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
|
Chris@16
|
42 # include <boost/asio/detail/function.hpp>
|
Chris@16
|
43 #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
|
Chris@16
|
44
|
Chris@16
|
45 #if defined(BOOST_ASIO_HAS_BOOST_WORKAROUND)
|
Chris@16
|
46 # include <boost/detail/workaround.hpp>
|
Chris@16
|
47 # if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) \
|
Chris@16
|
48 || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
|
Chris@16
|
49 # define BOOST_ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND
|
Chris@16
|
50 # endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
|
Chris@16
|
51 // || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
|
Chris@16
|
52 #endif // defined(BOOST_ASIO_HAS_BOOST_WORKAROUND)
|
Chris@16
|
53
|
Chris@16
|
54 #if defined(BOOST_ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)
|
Chris@16
|
55 # include <boost/asio/detail/type_traits.hpp>
|
Chris@16
|
56 #endif // defined(BOOST_ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)
|
Chris@16
|
57
|
Chris@16
|
58 #include <boost/asio/detail/push_options.hpp>
|
Chris@16
|
59
|
Chris@16
|
60 namespace boost {
|
Chris@16
|
61 namespace asio {
|
Chris@16
|
62
|
Chris@16
|
63 class mutable_buffer;
|
Chris@16
|
64 class const_buffer;
|
Chris@16
|
65
|
Chris@16
|
66 namespace detail {
|
Chris@16
|
67 void* buffer_cast_helper(const mutable_buffer&);
|
Chris@16
|
68 const void* buffer_cast_helper(const const_buffer&);
|
Chris@16
|
69 std::size_t buffer_size_helper(const mutable_buffer&);
|
Chris@16
|
70 std::size_t buffer_size_helper(const const_buffer&);
|
Chris@16
|
71 } // namespace detail
|
Chris@16
|
72
|
Chris@16
|
73 /// Holds a buffer that can be modified.
|
Chris@16
|
74 /**
|
Chris@16
|
75 * The mutable_buffer class provides a safe representation of a buffer that can
|
Chris@16
|
76 * be modified. It does not own the underlying data, and so is cheap to copy or
|
Chris@16
|
77 * assign.
|
Chris@16
|
78 *
|
Chris@16
|
79 * @par Accessing Buffer Contents
|
Chris@16
|
80 *
|
Chris@16
|
81 * The contents of a buffer may be accessed using the @ref buffer_size
|
Chris@16
|
82 * and @ref buffer_cast functions:
|
Chris@16
|
83 *
|
Chris@16
|
84 * @code boost::asio::mutable_buffer b1 = ...;
|
Chris@16
|
85 * std::size_t s1 = boost::asio::buffer_size(b1);
|
Chris@16
|
86 * unsigned char* p1 = boost::asio::buffer_cast<unsigned char*>(b1);
|
Chris@16
|
87 * @endcode
|
Chris@16
|
88 *
|
Chris@16
|
89 * The boost::asio::buffer_cast function permits violations of type safety, so
|
Chris@16
|
90 * uses of it in application code should be carefully considered.
|
Chris@16
|
91 */
|
Chris@16
|
92 class mutable_buffer
|
Chris@16
|
93 {
|
Chris@16
|
94 public:
|
Chris@16
|
95 /// Construct an empty buffer.
|
Chris@16
|
96 mutable_buffer()
|
Chris@16
|
97 : data_(0),
|
Chris@16
|
98 size_(0)
|
Chris@16
|
99 {
|
Chris@16
|
100 }
|
Chris@16
|
101
|
Chris@16
|
102 /// Construct a buffer to represent a given memory range.
|
Chris@16
|
103 mutable_buffer(void* data, std::size_t size)
|
Chris@16
|
104 : data_(data),
|
Chris@16
|
105 size_(size)
|
Chris@16
|
106 {
|
Chris@16
|
107 }
|
Chris@16
|
108
|
Chris@16
|
109 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
|
Chris@16
|
110 mutable_buffer(void* data, std::size_t size,
|
Chris@16
|
111 boost::asio::detail::function<void()> debug_check)
|
Chris@16
|
112 : data_(data),
|
Chris@16
|
113 size_(size),
|
Chris@16
|
114 debug_check_(debug_check)
|
Chris@16
|
115 {
|
Chris@16
|
116 }
|
Chris@16
|
117
|
Chris@16
|
118 const boost::asio::detail::function<void()>& get_debug_check() const
|
Chris@16
|
119 {
|
Chris@16
|
120 return debug_check_;
|
Chris@16
|
121 }
|
Chris@16
|
122 #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
|
Chris@16
|
123
|
Chris@16
|
124 private:
|
Chris@16
|
125 friend void* boost::asio::detail::buffer_cast_helper(
|
Chris@16
|
126 const mutable_buffer& b);
|
Chris@16
|
127 friend std::size_t boost::asio::detail::buffer_size_helper(
|
Chris@16
|
128 const mutable_buffer& b);
|
Chris@16
|
129
|
Chris@16
|
130 void* data_;
|
Chris@16
|
131 std::size_t size_;
|
Chris@16
|
132
|
Chris@16
|
133 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
|
Chris@16
|
134 boost::asio::detail::function<void()> debug_check_;
|
Chris@16
|
135 #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
|
Chris@16
|
136 };
|
Chris@16
|
137
|
Chris@16
|
138 namespace detail {
|
Chris@16
|
139
|
Chris@16
|
140 inline void* buffer_cast_helper(const mutable_buffer& b)
|
Chris@16
|
141 {
|
Chris@16
|
142 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
|
Chris@16
|
143 if (b.size_ && b.debug_check_)
|
Chris@16
|
144 b.debug_check_();
|
Chris@16
|
145 #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
|
Chris@16
|
146 return b.data_;
|
Chris@16
|
147 }
|
Chris@16
|
148
|
Chris@16
|
149 inline std::size_t buffer_size_helper(const mutable_buffer& b)
|
Chris@16
|
150 {
|
Chris@16
|
151 return b.size_;
|
Chris@16
|
152 }
|
Chris@16
|
153
|
Chris@16
|
154 } // namespace detail
|
Chris@16
|
155
|
Chris@16
|
156 /// Adapts a single modifiable buffer so that it meets the requirements of the
|
Chris@16
|
157 /// MutableBufferSequence concept.
|
Chris@16
|
158 class mutable_buffers_1
|
Chris@16
|
159 : public mutable_buffer
|
Chris@16
|
160 {
|
Chris@16
|
161 public:
|
Chris@16
|
162 /// The type for each element in the list of buffers.
|
Chris@16
|
163 typedef mutable_buffer value_type;
|
Chris@16
|
164
|
Chris@16
|
165 /// A random-access iterator type that may be used to read elements.
|
Chris@16
|
166 typedef const mutable_buffer* const_iterator;
|
Chris@16
|
167
|
Chris@16
|
168 /// Construct to represent a given memory range.
|
Chris@16
|
169 mutable_buffers_1(void* data, std::size_t size)
|
Chris@16
|
170 : mutable_buffer(data, size)
|
Chris@16
|
171 {
|
Chris@16
|
172 }
|
Chris@16
|
173
|
Chris@16
|
174 /// Construct to represent a single modifiable buffer.
|
Chris@16
|
175 explicit mutable_buffers_1(const mutable_buffer& b)
|
Chris@16
|
176 : mutable_buffer(b)
|
Chris@16
|
177 {
|
Chris@16
|
178 }
|
Chris@16
|
179
|
Chris@16
|
180 /// Get a random-access iterator to the first element.
|
Chris@16
|
181 const_iterator begin() const
|
Chris@16
|
182 {
|
Chris@16
|
183 return this;
|
Chris@16
|
184 }
|
Chris@16
|
185
|
Chris@16
|
186 /// Get a random-access iterator for one past the last element.
|
Chris@16
|
187 const_iterator end() const
|
Chris@16
|
188 {
|
Chris@16
|
189 return begin() + 1;
|
Chris@16
|
190 }
|
Chris@16
|
191 };
|
Chris@16
|
192
|
Chris@16
|
193 /// Holds a buffer that cannot be modified.
|
Chris@16
|
194 /**
|
Chris@16
|
195 * The const_buffer class provides a safe representation of a buffer that cannot
|
Chris@16
|
196 * be modified. It does not own the underlying data, and so is cheap to copy or
|
Chris@16
|
197 * assign.
|
Chris@16
|
198 *
|
Chris@16
|
199 * @par Accessing Buffer Contents
|
Chris@16
|
200 *
|
Chris@16
|
201 * The contents of a buffer may be accessed using the @ref buffer_size
|
Chris@16
|
202 * and @ref buffer_cast functions:
|
Chris@16
|
203 *
|
Chris@16
|
204 * @code boost::asio::const_buffer b1 = ...;
|
Chris@16
|
205 * std::size_t s1 = boost::asio::buffer_size(b1);
|
Chris@16
|
206 * const unsigned char* p1 = boost::asio::buffer_cast<const unsigned char*>(b1);
|
Chris@16
|
207 * @endcode
|
Chris@16
|
208 *
|
Chris@16
|
209 * The boost::asio::buffer_cast function permits violations of type safety, so
|
Chris@16
|
210 * uses of it in application code should be carefully considered.
|
Chris@16
|
211 */
|
Chris@16
|
212 class const_buffer
|
Chris@16
|
213 {
|
Chris@16
|
214 public:
|
Chris@16
|
215 /// Construct an empty buffer.
|
Chris@16
|
216 const_buffer()
|
Chris@16
|
217 : data_(0),
|
Chris@16
|
218 size_(0)
|
Chris@16
|
219 {
|
Chris@16
|
220 }
|
Chris@16
|
221
|
Chris@16
|
222 /// Construct a buffer to represent a given memory range.
|
Chris@16
|
223 const_buffer(const void* data, std::size_t size)
|
Chris@16
|
224 : data_(data),
|
Chris@16
|
225 size_(size)
|
Chris@16
|
226 {
|
Chris@16
|
227 }
|
Chris@16
|
228
|
Chris@16
|
229 /// Construct a non-modifiable buffer from a modifiable one.
|
Chris@16
|
230 const_buffer(const mutable_buffer& b)
|
Chris@16
|
231 : data_(boost::asio::detail::buffer_cast_helper(b)),
|
Chris@16
|
232 size_(boost::asio::detail::buffer_size_helper(b))
|
Chris@16
|
233 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
|
Chris@16
|
234 , debug_check_(b.get_debug_check())
|
Chris@16
|
235 #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
|
Chris@16
|
236 {
|
Chris@16
|
237 }
|
Chris@16
|
238
|
Chris@16
|
239 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
|
Chris@16
|
240 const_buffer(const void* data, std::size_t size,
|
Chris@16
|
241 boost::asio::detail::function<void()> debug_check)
|
Chris@16
|
242 : data_(data),
|
Chris@16
|
243 size_(size),
|
Chris@16
|
244 debug_check_(debug_check)
|
Chris@16
|
245 {
|
Chris@16
|
246 }
|
Chris@16
|
247
|
Chris@16
|
248 const boost::asio::detail::function<void()>& get_debug_check() const
|
Chris@16
|
249 {
|
Chris@16
|
250 return debug_check_;
|
Chris@16
|
251 }
|
Chris@16
|
252 #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
|
Chris@16
|
253
|
Chris@16
|
254 private:
|
Chris@16
|
255 friend const void* boost::asio::detail::buffer_cast_helper(
|
Chris@16
|
256 const const_buffer& b);
|
Chris@16
|
257 friend std::size_t boost::asio::detail::buffer_size_helper(
|
Chris@16
|
258 const const_buffer& b);
|
Chris@16
|
259
|
Chris@16
|
260 const void* data_;
|
Chris@16
|
261 std::size_t size_;
|
Chris@16
|
262
|
Chris@16
|
263 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
|
Chris@16
|
264 boost::asio::detail::function<void()> debug_check_;
|
Chris@16
|
265 #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
|
Chris@16
|
266 };
|
Chris@16
|
267
|
Chris@16
|
268 namespace detail {
|
Chris@16
|
269
|
Chris@16
|
270 inline const void* buffer_cast_helper(const const_buffer& b)
|
Chris@16
|
271 {
|
Chris@16
|
272 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
|
Chris@16
|
273 if (b.size_ && b.debug_check_)
|
Chris@16
|
274 b.debug_check_();
|
Chris@16
|
275 #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
|
Chris@16
|
276 return b.data_;
|
Chris@16
|
277 }
|
Chris@16
|
278
|
Chris@16
|
279 inline std::size_t buffer_size_helper(const const_buffer& b)
|
Chris@16
|
280 {
|
Chris@16
|
281 return b.size_;
|
Chris@16
|
282 }
|
Chris@16
|
283
|
Chris@16
|
284 } // namespace detail
|
Chris@16
|
285
|
Chris@16
|
286 /// Adapts a single non-modifiable buffer so that it meets the requirements of
|
Chris@16
|
287 /// the ConstBufferSequence concept.
|
Chris@16
|
288 class const_buffers_1
|
Chris@16
|
289 : public const_buffer
|
Chris@16
|
290 {
|
Chris@16
|
291 public:
|
Chris@16
|
292 /// The type for each element in the list of buffers.
|
Chris@16
|
293 typedef const_buffer value_type;
|
Chris@16
|
294
|
Chris@16
|
295 /// A random-access iterator type that may be used to read elements.
|
Chris@16
|
296 typedef const const_buffer* const_iterator;
|
Chris@16
|
297
|
Chris@16
|
298 /// Construct to represent a given memory range.
|
Chris@16
|
299 const_buffers_1(const void* data, std::size_t size)
|
Chris@16
|
300 : const_buffer(data, size)
|
Chris@16
|
301 {
|
Chris@16
|
302 }
|
Chris@16
|
303
|
Chris@16
|
304 /// Construct to represent a single non-modifiable buffer.
|
Chris@16
|
305 explicit const_buffers_1(const const_buffer& b)
|
Chris@16
|
306 : const_buffer(b)
|
Chris@16
|
307 {
|
Chris@16
|
308 }
|
Chris@16
|
309
|
Chris@16
|
310 /// Get a random-access iterator to the first element.
|
Chris@16
|
311 const_iterator begin() const
|
Chris@16
|
312 {
|
Chris@16
|
313 return this;
|
Chris@16
|
314 }
|
Chris@16
|
315
|
Chris@16
|
316 /// Get a random-access iterator for one past the last element.
|
Chris@16
|
317 const_iterator end() const
|
Chris@16
|
318 {
|
Chris@16
|
319 return begin() + 1;
|
Chris@16
|
320 }
|
Chris@16
|
321 };
|
Chris@16
|
322
|
Chris@16
|
323 /// An implementation of both the ConstBufferSequence and MutableBufferSequence
|
Chris@16
|
324 /// concepts to represent a null buffer sequence.
|
Chris@16
|
325 class null_buffers
|
Chris@16
|
326 {
|
Chris@16
|
327 public:
|
Chris@16
|
328 /// The type for each element in the list of buffers.
|
Chris@16
|
329 typedef mutable_buffer value_type;
|
Chris@16
|
330
|
Chris@16
|
331 /// A random-access iterator type that may be used to read elements.
|
Chris@16
|
332 typedef const mutable_buffer* const_iterator;
|
Chris@16
|
333
|
Chris@16
|
334 /// Get a random-access iterator to the first element.
|
Chris@16
|
335 const_iterator begin() const
|
Chris@16
|
336 {
|
Chris@16
|
337 return &buf_;
|
Chris@16
|
338 }
|
Chris@16
|
339
|
Chris@16
|
340 /// Get a random-access iterator for one past the last element.
|
Chris@16
|
341 const_iterator end() const
|
Chris@16
|
342 {
|
Chris@16
|
343 return &buf_;
|
Chris@16
|
344 }
|
Chris@16
|
345
|
Chris@16
|
346 private:
|
Chris@16
|
347 mutable_buffer buf_;
|
Chris@16
|
348 };
|
Chris@16
|
349
|
Chris@16
|
350 /** @defgroup buffer_size boost::asio::buffer_size
|
Chris@16
|
351 *
|
Chris@16
|
352 * @brief The boost::asio::buffer_size function determines the total number of
|
Chris@16
|
353 * bytes in a buffer or buffer sequence.
|
Chris@16
|
354 */
|
Chris@16
|
355 /*@{*/
|
Chris@16
|
356
|
Chris@16
|
357 /// Get the number of bytes in a modifiable buffer.
|
Chris@16
|
358 inline std::size_t buffer_size(const mutable_buffer& b)
|
Chris@16
|
359 {
|
Chris@16
|
360 return detail::buffer_size_helper(b);
|
Chris@16
|
361 }
|
Chris@16
|
362
|
Chris@16
|
363 /// Get the number of bytes in a modifiable buffer.
|
Chris@16
|
364 inline std::size_t buffer_size(const mutable_buffers_1& b)
|
Chris@16
|
365 {
|
Chris@16
|
366 return detail::buffer_size_helper(b);
|
Chris@16
|
367 }
|
Chris@16
|
368
|
Chris@16
|
369 /// Get the number of bytes in a non-modifiable buffer.
|
Chris@16
|
370 inline std::size_t buffer_size(const const_buffer& b)
|
Chris@16
|
371 {
|
Chris@16
|
372 return detail::buffer_size_helper(b);
|
Chris@16
|
373 }
|
Chris@16
|
374
|
Chris@16
|
375 /// Get the number of bytes in a non-modifiable buffer.
|
Chris@16
|
376 inline std::size_t buffer_size(const const_buffers_1& b)
|
Chris@16
|
377 {
|
Chris@16
|
378 return detail::buffer_size_helper(b);
|
Chris@16
|
379 }
|
Chris@16
|
380
|
Chris@16
|
381 /// Get the total number of bytes in a buffer sequence.
|
Chris@16
|
382 /**
|
Chris@16
|
383 * The @c BufferSequence template parameter may meet either of the @c
|
Chris@16
|
384 * ConstBufferSequence or @c MutableBufferSequence type requirements.
|
Chris@16
|
385 */
|
Chris@16
|
386 template <typename BufferSequence>
|
Chris@16
|
387 inline std::size_t buffer_size(const BufferSequence& b)
|
Chris@16
|
388 {
|
Chris@16
|
389 std::size_t total_buffer_size = 0;
|
Chris@16
|
390
|
Chris@16
|
391 typename BufferSequence::const_iterator iter = b.begin();
|
Chris@16
|
392 typename BufferSequence::const_iterator end = b.end();
|
Chris@16
|
393 for (; iter != end; ++iter)
|
Chris@16
|
394 total_buffer_size += detail::buffer_size_helper(*iter);
|
Chris@16
|
395
|
Chris@16
|
396 return total_buffer_size;
|
Chris@16
|
397 }
|
Chris@16
|
398
|
Chris@16
|
399 /*@}*/
|
Chris@16
|
400
|
Chris@16
|
401 /** @defgroup buffer_cast boost::asio::buffer_cast
|
Chris@16
|
402 *
|
Chris@16
|
403 * @brief The boost::asio::buffer_cast function is used to obtain a pointer to
|
Chris@16
|
404 * the underlying memory region associated with a buffer.
|
Chris@16
|
405 *
|
Chris@16
|
406 * @par Examples:
|
Chris@16
|
407 *
|
Chris@16
|
408 * To access the memory of a non-modifiable buffer, use:
|
Chris@16
|
409 * @code boost::asio::const_buffer b1 = ...;
|
Chris@16
|
410 * const unsigned char* p1 = boost::asio::buffer_cast<const unsigned char*>(b1);
|
Chris@16
|
411 * @endcode
|
Chris@16
|
412 *
|
Chris@16
|
413 * To access the memory of a modifiable buffer, use:
|
Chris@16
|
414 * @code boost::asio::mutable_buffer b2 = ...;
|
Chris@16
|
415 * unsigned char* p2 = boost::asio::buffer_cast<unsigned char*>(b2);
|
Chris@16
|
416 * @endcode
|
Chris@16
|
417 *
|
Chris@16
|
418 * The boost::asio::buffer_cast function permits violations of type safety, so
|
Chris@16
|
419 * uses of it in application code should be carefully considered.
|
Chris@16
|
420 */
|
Chris@16
|
421 /*@{*/
|
Chris@16
|
422
|
Chris@16
|
423 /// Cast a non-modifiable buffer to a specified pointer to POD type.
|
Chris@16
|
424 template <typename PointerToPodType>
|
Chris@16
|
425 inline PointerToPodType buffer_cast(const mutable_buffer& b)
|
Chris@16
|
426 {
|
Chris@16
|
427 return static_cast<PointerToPodType>(detail::buffer_cast_helper(b));
|
Chris@16
|
428 }
|
Chris@16
|
429
|
Chris@16
|
430 /// Cast a non-modifiable buffer to a specified pointer to POD type.
|
Chris@16
|
431 template <typename PointerToPodType>
|
Chris@16
|
432 inline PointerToPodType buffer_cast(const const_buffer& b)
|
Chris@16
|
433 {
|
Chris@16
|
434 return static_cast<PointerToPodType>(detail::buffer_cast_helper(b));
|
Chris@16
|
435 }
|
Chris@16
|
436
|
Chris@16
|
437 /*@}*/
|
Chris@16
|
438
|
Chris@16
|
439 /// Create a new modifiable buffer that is offset from the start of another.
|
Chris@16
|
440 /**
|
Chris@16
|
441 * @relates mutable_buffer
|
Chris@16
|
442 */
|
Chris@16
|
443 inline mutable_buffer operator+(const mutable_buffer& b, std::size_t start)
|
Chris@16
|
444 {
|
Chris@16
|
445 if (start > buffer_size(b))
|
Chris@16
|
446 return mutable_buffer();
|
Chris@16
|
447 char* new_data = buffer_cast<char*>(b) + start;
|
Chris@16
|
448 std::size_t new_size = buffer_size(b) - start;
|
Chris@16
|
449 return mutable_buffer(new_data, new_size
|
Chris@16
|
450 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
|
Chris@16
|
451 , b.get_debug_check()
|
Chris@16
|
452 #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
|
Chris@16
|
453 );
|
Chris@16
|
454 }
|
Chris@16
|
455
|
Chris@16
|
456 /// Create a new modifiable buffer that is offset from the start of another.
|
Chris@16
|
457 /**
|
Chris@16
|
458 * @relates mutable_buffer
|
Chris@16
|
459 */
|
Chris@16
|
460 inline mutable_buffer operator+(std::size_t start, const mutable_buffer& b)
|
Chris@16
|
461 {
|
Chris@16
|
462 if (start > buffer_size(b))
|
Chris@16
|
463 return mutable_buffer();
|
Chris@16
|
464 char* new_data = buffer_cast<char*>(b) + start;
|
Chris@16
|
465 std::size_t new_size = buffer_size(b) - start;
|
Chris@16
|
466 return mutable_buffer(new_data, new_size
|
Chris@16
|
467 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
|
Chris@16
|
468 , b.get_debug_check()
|
Chris@16
|
469 #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
|
Chris@16
|
470 );
|
Chris@16
|
471 }
|
Chris@16
|
472
|
Chris@16
|
473 /// Create a new non-modifiable buffer that is offset from the start of another.
|
Chris@16
|
474 /**
|
Chris@16
|
475 * @relates const_buffer
|
Chris@16
|
476 */
|
Chris@16
|
477 inline const_buffer operator+(const const_buffer& b, std::size_t start)
|
Chris@16
|
478 {
|
Chris@16
|
479 if (start > buffer_size(b))
|
Chris@16
|
480 return const_buffer();
|
Chris@16
|
481 const char* new_data = buffer_cast<const char*>(b) + start;
|
Chris@16
|
482 std::size_t new_size = buffer_size(b) - start;
|
Chris@16
|
483 return const_buffer(new_data, new_size
|
Chris@16
|
484 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
|
Chris@16
|
485 , b.get_debug_check()
|
Chris@16
|
486 #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
|
Chris@16
|
487 );
|
Chris@16
|
488 }
|
Chris@16
|
489
|
Chris@16
|
490 /// Create a new non-modifiable buffer that is offset from the start of another.
|
Chris@16
|
491 /**
|
Chris@16
|
492 * @relates const_buffer
|
Chris@16
|
493 */
|
Chris@16
|
494 inline const_buffer operator+(std::size_t start, const const_buffer& b)
|
Chris@16
|
495 {
|
Chris@16
|
496 if (start > buffer_size(b))
|
Chris@16
|
497 return const_buffer();
|
Chris@16
|
498 const char* new_data = buffer_cast<const char*>(b) + start;
|
Chris@16
|
499 std::size_t new_size = buffer_size(b) - start;
|
Chris@16
|
500 return const_buffer(new_data, new_size
|
Chris@16
|
501 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
|
Chris@16
|
502 , b.get_debug_check()
|
Chris@16
|
503 #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
|
Chris@16
|
504 );
|
Chris@16
|
505 }
|
Chris@16
|
506
|
Chris@16
|
507 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
|
Chris@16
|
508 namespace detail {
|
Chris@16
|
509
|
Chris@16
|
510 template <typename Iterator>
|
Chris@16
|
511 class buffer_debug_check
|
Chris@16
|
512 {
|
Chris@16
|
513 public:
|
Chris@16
|
514 buffer_debug_check(Iterator iter)
|
Chris@16
|
515 : iter_(iter)
|
Chris@16
|
516 {
|
Chris@16
|
517 }
|
Chris@16
|
518
|
Chris@16
|
519 ~buffer_debug_check()
|
Chris@16
|
520 {
|
Chris@16
|
521 #if defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC == 1400)
|
Chris@16
|
522 // MSVC 8's string iterator checking may crash in a std::string::iterator
|
Chris@16
|
523 // object's destructor when the iterator points to an already-destroyed
|
Chris@16
|
524 // std::string object, unless the iterator is cleared first.
|
Chris@16
|
525 iter_ = Iterator();
|
Chris@16
|
526 #endif // defined(BOOST_ASIO_MSVC) && (BOOST_ASIO_MSVC == 1400)
|
Chris@16
|
527 }
|
Chris@16
|
528
|
Chris@16
|
529 void operator()()
|
Chris@16
|
530 {
|
Chris@16
|
531 *iter_;
|
Chris@16
|
532 }
|
Chris@16
|
533
|
Chris@16
|
534 private:
|
Chris@16
|
535 Iterator iter_;
|
Chris@16
|
536 };
|
Chris@16
|
537
|
Chris@16
|
538 } // namespace detail
|
Chris@16
|
539 #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
|
Chris@16
|
540
|
Chris@16
|
541 /** @defgroup buffer boost::asio::buffer
|
Chris@16
|
542 *
|
Chris@16
|
543 * @brief The boost::asio::buffer function is used to create a buffer object to
|
Chris@16
|
544 * represent raw memory, an array of POD elements, a vector of POD elements,
|
Chris@16
|
545 * or a std::string.
|
Chris@16
|
546 *
|
Chris@16
|
547 * A buffer object represents a contiguous region of memory as a 2-tuple
|
Chris@16
|
548 * consisting of a pointer and size in bytes. A tuple of the form <tt>{void*,
|
Chris@16
|
549 * size_t}</tt> specifies a mutable (modifiable) region of memory. Similarly, a
|
Chris@16
|
550 * tuple of the form <tt>{const void*, size_t}</tt> specifies a const
|
Chris@16
|
551 * (non-modifiable) region of memory. These two forms correspond to the classes
|
Chris@16
|
552 * mutable_buffer and const_buffer, respectively. To mirror C++'s conversion
|
Chris@16
|
553 * rules, a mutable_buffer is implicitly convertible to a const_buffer, and the
|
Chris@16
|
554 * opposite conversion is not permitted.
|
Chris@16
|
555 *
|
Chris@16
|
556 * The simplest use case involves reading or writing a single buffer of a
|
Chris@16
|
557 * specified size:
|
Chris@16
|
558 *
|
Chris@16
|
559 * @code sock.send(boost::asio::buffer(data, size)); @endcode
|
Chris@16
|
560 *
|
Chris@16
|
561 * In the above example, the return value of boost::asio::buffer meets the
|
Chris@16
|
562 * requirements of the ConstBufferSequence concept so that it may be directly
|
Chris@16
|
563 * passed to the socket's write function. A buffer created for modifiable
|
Chris@16
|
564 * memory also meets the requirements of the MutableBufferSequence concept.
|
Chris@16
|
565 *
|
Chris@16
|
566 * An individual buffer may be created from a builtin array, std::vector,
|
Chris@16
|
567 * std::array or boost::array of POD elements. This helps prevent buffer
|
Chris@16
|
568 * overruns by automatically determining the size of the buffer:
|
Chris@16
|
569 *
|
Chris@16
|
570 * @code char d1[128];
|
Chris@16
|
571 * size_t bytes_transferred = sock.receive(boost::asio::buffer(d1));
|
Chris@16
|
572 *
|
Chris@16
|
573 * std::vector<char> d2(128);
|
Chris@16
|
574 * bytes_transferred = sock.receive(boost::asio::buffer(d2));
|
Chris@16
|
575 *
|
Chris@16
|
576 * std::array<char, 128> d3;
|
Chris@16
|
577 * bytes_transferred = sock.receive(boost::asio::buffer(d3));
|
Chris@16
|
578 *
|
Chris@16
|
579 * boost::array<char, 128> d4;
|
Chris@16
|
580 * bytes_transferred = sock.receive(boost::asio::buffer(d4)); @endcode
|
Chris@16
|
581 *
|
Chris@16
|
582 * In all three cases above, the buffers created are exactly 128 bytes long.
|
Chris@16
|
583 * Note that a vector is @e never automatically resized when creating or using
|
Chris@16
|
584 * a buffer. The buffer size is determined using the vector's <tt>size()</tt>
|
Chris@16
|
585 * member function, and not its capacity.
|
Chris@16
|
586 *
|
Chris@16
|
587 * @par Accessing Buffer Contents
|
Chris@16
|
588 *
|
Chris@16
|
589 * The contents of a buffer may be accessed using the @ref buffer_size and
|
Chris@16
|
590 * @ref buffer_cast functions:
|
Chris@16
|
591 *
|
Chris@16
|
592 * @code boost::asio::mutable_buffer b1 = ...;
|
Chris@16
|
593 * std::size_t s1 = boost::asio::buffer_size(b1);
|
Chris@16
|
594 * unsigned char* p1 = boost::asio::buffer_cast<unsigned char*>(b1);
|
Chris@16
|
595 *
|
Chris@16
|
596 * boost::asio::const_buffer b2 = ...;
|
Chris@16
|
597 * std::size_t s2 = boost::asio::buffer_size(b2);
|
Chris@16
|
598 * const void* p2 = boost::asio::buffer_cast<const void*>(b2); @endcode
|
Chris@16
|
599 *
|
Chris@16
|
600 * The boost::asio::buffer_cast function permits violations of type safety, so
|
Chris@16
|
601 * uses of it in application code should be carefully considered.
|
Chris@16
|
602 *
|
Chris@16
|
603 * For convenience, the @ref buffer_size function also works on buffer
|
Chris@16
|
604 * sequences (that is, types meeting the ConstBufferSequence or
|
Chris@16
|
605 * MutableBufferSequence type requirements). In this case, the function returns
|
Chris@16
|
606 * the total size of all buffers in the sequence.
|
Chris@16
|
607 *
|
Chris@16
|
608 * @par Buffer Copying
|
Chris@16
|
609 *
|
Chris@16
|
610 * The @ref buffer_copy function may be used to copy raw bytes between
|
Chris@16
|
611 * individual buffers and buffer sequences.
|
Chris@16
|
612 *
|
Chris@16
|
613 * In particular, when used with the @ref buffer_size, the @ref buffer_copy
|
Chris@16
|
614 * function can be used to linearise a sequence of buffers. For example:
|
Chris@16
|
615 *
|
Chris@16
|
616 * @code vector<const_buffer> buffers = ...;
|
Chris@16
|
617 *
|
Chris@16
|
618 * vector<unsigned char> data(boost::asio::buffer_size(buffers));
|
Chris@16
|
619 * boost::asio::buffer_copy(boost::asio::buffer(data), buffers); @endcode
|
Chris@16
|
620 *
|
Chris@101
|
621 * Note that @ref buffer_copy is implemented in terms of @c memcpy, and
|
Chris@101
|
622 * consequently it cannot be used to copy between overlapping memory regions.
|
Chris@101
|
623 *
|
Chris@16
|
624 * @par Buffer Invalidation
|
Chris@16
|
625 *
|
Chris@16
|
626 * A buffer object does not have any ownership of the memory it refers to. It
|
Chris@16
|
627 * is the responsibility of the application to ensure the memory region remains
|
Chris@16
|
628 * valid until it is no longer required for an I/O operation. When the memory
|
Chris@16
|
629 * is no longer available, the buffer is said to have been invalidated.
|
Chris@16
|
630 *
|
Chris@16
|
631 * For the boost::asio::buffer overloads that accept an argument of type
|
Chris@16
|
632 * std::vector, the buffer objects returned are invalidated by any vector
|
Chris@16
|
633 * operation that also invalidates all references, pointers and iterators
|
Chris@16
|
634 * referring to the elements in the sequence (C++ Std, 23.2.4)
|
Chris@16
|
635 *
|
Chris@16
|
636 * For the boost::asio::buffer overloads that accept an argument of type
|
Chris@16
|
637 * std::basic_string, the buffer objects returned are invalidated according to
|
Chris@16
|
638 * the rules defined for invalidation of references, pointers and iterators
|
Chris@16
|
639 * referring to elements of the sequence (C++ Std, 21.3).
|
Chris@16
|
640 *
|
Chris@16
|
641 * @par Buffer Arithmetic
|
Chris@16
|
642 *
|
Chris@16
|
643 * Buffer objects may be manipulated using simple arithmetic in a safe way
|
Chris@16
|
644 * which helps prevent buffer overruns. Consider an array initialised as
|
Chris@16
|
645 * follows:
|
Chris@16
|
646 *
|
Chris@16
|
647 * @code boost::array<char, 6> a = { 'a', 'b', 'c', 'd', 'e' }; @endcode
|
Chris@16
|
648 *
|
Chris@16
|
649 * A buffer object @c b1 created using:
|
Chris@16
|
650 *
|
Chris@16
|
651 * @code b1 = boost::asio::buffer(a); @endcode
|
Chris@16
|
652 *
|
Chris@16
|
653 * represents the entire array, <tt>{ 'a', 'b', 'c', 'd', 'e' }</tt>. An
|
Chris@16
|
654 * optional second argument to the boost::asio::buffer function may be used to
|
Chris@16
|
655 * limit the size, in bytes, of the buffer:
|
Chris@16
|
656 *
|
Chris@16
|
657 * @code b2 = boost::asio::buffer(a, 3); @endcode
|
Chris@16
|
658 *
|
Chris@16
|
659 * such that @c b2 represents the data <tt>{ 'a', 'b', 'c' }</tt>. Even if the
|
Chris@16
|
660 * size argument exceeds the actual size of the array, the size of the buffer
|
Chris@16
|
661 * object created will be limited to the array size.
|
Chris@16
|
662 *
|
Chris@16
|
663 * An offset may be applied to an existing buffer to create a new one:
|
Chris@16
|
664 *
|
Chris@16
|
665 * @code b3 = b1 + 2; @endcode
|
Chris@16
|
666 *
|
Chris@16
|
667 * where @c b3 will set to represent <tt>{ 'c', 'd', 'e' }</tt>. If the offset
|
Chris@16
|
668 * exceeds the size of the existing buffer, the newly created buffer will be
|
Chris@16
|
669 * empty.
|
Chris@16
|
670 *
|
Chris@16
|
671 * Both an offset and size may be specified to create a buffer that corresponds
|
Chris@16
|
672 * to a specific range of bytes within an existing buffer:
|
Chris@16
|
673 *
|
Chris@16
|
674 * @code b4 = boost::asio::buffer(b1 + 1, 3); @endcode
|
Chris@16
|
675 *
|
Chris@16
|
676 * so that @c b4 will refer to the bytes <tt>{ 'b', 'c', 'd' }</tt>.
|
Chris@16
|
677 *
|
Chris@16
|
678 * @par Buffers and Scatter-Gather I/O
|
Chris@16
|
679 *
|
Chris@16
|
680 * To read or write using multiple buffers (i.e. scatter-gather I/O), multiple
|
Chris@16
|
681 * buffer objects may be assigned into a container that supports the
|
Chris@16
|
682 * MutableBufferSequence (for read) or ConstBufferSequence (for write) concepts:
|
Chris@16
|
683 *
|
Chris@16
|
684 * @code
|
Chris@16
|
685 * char d1[128];
|
Chris@16
|
686 * std::vector<char> d2(128);
|
Chris@16
|
687 * boost::array<char, 128> d3;
|
Chris@16
|
688 *
|
Chris@16
|
689 * boost::array<mutable_buffer, 3> bufs1 = {
|
Chris@16
|
690 * boost::asio::buffer(d1),
|
Chris@16
|
691 * boost::asio::buffer(d2),
|
Chris@16
|
692 * boost::asio::buffer(d3) };
|
Chris@16
|
693 * bytes_transferred = sock.receive(bufs1);
|
Chris@16
|
694 *
|
Chris@16
|
695 * std::vector<const_buffer> bufs2;
|
Chris@16
|
696 * bufs2.push_back(boost::asio::buffer(d1));
|
Chris@16
|
697 * bufs2.push_back(boost::asio::buffer(d2));
|
Chris@16
|
698 * bufs2.push_back(boost::asio::buffer(d3));
|
Chris@16
|
699 * bytes_transferred = sock.send(bufs2); @endcode
|
Chris@16
|
700 */
|
Chris@16
|
701 /*@{*/
|
Chris@16
|
702
|
Chris@16
|
703 /// Create a new modifiable buffer from an existing buffer.
|
Chris@16
|
704 /**
|
Chris@16
|
705 * @returns <tt>mutable_buffers_1(b)</tt>.
|
Chris@16
|
706 */
|
Chris@16
|
707 inline mutable_buffers_1 buffer(const mutable_buffer& b)
|
Chris@16
|
708 {
|
Chris@16
|
709 return mutable_buffers_1(b);
|
Chris@16
|
710 }
|
Chris@16
|
711
|
Chris@16
|
712 /// Create a new modifiable buffer from an existing buffer.
|
Chris@16
|
713 /**
|
Chris@16
|
714 * @returns A mutable_buffers_1 value equivalent to:
|
Chris@16
|
715 * @code mutable_buffers_1(
|
Chris@16
|
716 * buffer_cast<void*>(b),
|
Chris@16
|
717 * min(buffer_size(b), max_size_in_bytes)); @endcode
|
Chris@16
|
718 */
|
Chris@16
|
719 inline mutable_buffers_1 buffer(const mutable_buffer& b,
|
Chris@16
|
720 std::size_t max_size_in_bytes)
|
Chris@16
|
721 {
|
Chris@16
|
722 return mutable_buffers_1(
|
Chris@16
|
723 mutable_buffer(buffer_cast<void*>(b),
|
Chris@16
|
724 buffer_size(b) < max_size_in_bytes
|
Chris@16
|
725 ? buffer_size(b) : max_size_in_bytes
|
Chris@16
|
726 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
|
Chris@16
|
727 , b.get_debug_check()
|
Chris@16
|
728 #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
|
Chris@16
|
729 ));
|
Chris@16
|
730 }
|
Chris@16
|
731
|
Chris@16
|
732 /// Create a new non-modifiable buffer from an existing buffer.
|
Chris@16
|
733 /**
|
Chris@16
|
734 * @returns <tt>const_buffers_1(b)</tt>.
|
Chris@16
|
735 */
|
Chris@16
|
736 inline const_buffers_1 buffer(const const_buffer& b)
|
Chris@16
|
737 {
|
Chris@16
|
738 return const_buffers_1(b);
|
Chris@16
|
739 }
|
Chris@16
|
740
|
Chris@16
|
741 /// Create a new non-modifiable buffer from an existing buffer.
|
Chris@16
|
742 /**
|
Chris@16
|
743 * @returns A const_buffers_1 value equivalent to:
|
Chris@16
|
744 * @code const_buffers_1(
|
Chris@16
|
745 * buffer_cast<const void*>(b),
|
Chris@16
|
746 * min(buffer_size(b), max_size_in_bytes)); @endcode
|
Chris@16
|
747 */
|
Chris@16
|
748 inline const_buffers_1 buffer(const const_buffer& b,
|
Chris@16
|
749 std::size_t max_size_in_bytes)
|
Chris@16
|
750 {
|
Chris@16
|
751 return const_buffers_1(
|
Chris@16
|
752 const_buffer(buffer_cast<const void*>(b),
|
Chris@16
|
753 buffer_size(b) < max_size_in_bytes
|
Chris@16
|
754 ? buffer_size(b) : max_size_in_bytes
|
Chris@16
|
755 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
|
Chris@16
|
756 , b.get_debug_check()
|
Chris@16
|
757 #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
|
Chris@16
|
758 ));
|
Chris@16
|
759 }
|
Chris@16
|
760
|
Chris@16
|
761 /// Create a new modifiable buffer that represents the given memory range.
|
Chris@16
|
762 /**
|
Chris@16
|
763 * @returns <tt>mutable_buffers_1(data, size_in_bytes)</tt>.
|
Chris@16
|
764 */
|
Chris@16
|
765 inline mutable_buffers_1 buffer(void* data, std::size_t size_in_bytes)
|
Chris@16
|
766 {
|
Chris@16
|
767 return mutable_buffers_1(mutable_buffer(data, size_in_bytes));
|
Chris@16
|
768 }
|
Chris@16
|
769
|
Chris@16
|
770 /// Create a new non-modifiable buffer that represents the given memory range.
|
Chris@16
|
771 /**
|
Chris@16
|
772 * @returns <tt>const_buffers_1(data, size_in_bytes)</tt>.
|
Chris@16
|
773 */
|
Chris@16
|
774 inline const_buffers_1 buffer(const void* data,
|
Chris@16
|
775 std::size_t size_in_bytes)
|
Chris@16
|
776 {
|
Chris@16
|
777 return const_buffers_1(const_buffer(data, size_in_bytes));
|
Chris@16
|
778 }
|
Chris@16
|
779
|
Chris@16
|
780 /// Create a new modifiable buffer that represents the given POD array.
|
Chris@16
|
781 /**
|
Chris@16
|
782 * @returns A mutable_buffers_1 value equivalent to:
|
Chris@16
|
783 * @code mutable_buffers_1(
|
Chris@16
|
784 * static_cast<void*>(data),
|
Chris@16
|
785 * N * sizeof(PodType)); @endcode
|
Chris@16
|
786 */
|
Chris@16
|
787 template <typename PodType, std::size_t N>
|
Chris@16
|
788 inline mutable_buffers_1 buffer(PodType (&data)[N])
|
Chris@16
|
789 {
|
Chris@16
|
790 return mutable_buffers_1(mutable_buffer(data, N * sizeof(PodType)));
|
Chris@16
|
791 }
|
Chris@16
|
792
|
Chris@16
|
793 /// Create a new modifiable buffer that represents the given POD array.
|
Chris@16
|
794 /**
|
Chris@16
|
795 * @returns A mutable_buffers_1 value equivalent to:
|
Chris@16
|
796 * @code mutable_buffers_1(
|
Chris@16
|
797 * static_cast<void*>(data),
|
Chris@16
|
798 * min(N * sizeof(PodType), max_size_in_bytes)); @endcode
|
Chris@16
|
799 */
|
Chris@16
|
800 template <typename PodType, std::size_t N>
|
Chris@16
|
801 inline mutable_buffers_1 buffer(PodType (&data)[N],
|
Chris@16
|
802 std::size_t max_size_in_bytes)
|
Chris@16
|
803 {
|
Chris@16
|
804 return mutable_buffers_1(
|
Chris@16
|
805 mutable_buffer(data,
|
Chris@16
|
806 N * sizeof(PodType) < max_size_in_bytes
|
Chris@16
|
807 ? N * sizeof(PodType) : max_size_in_bytes));
|
Chris@16
|
808 }
|
Chris@16
|
809
|
Chris@16
|
810 /// Create a new non-modifiable buffer that represents the given POD array.
|
Chris@16
|
811 /**
|
Chris@16
|
812 * @returns A const_buffers_1 value equivalent to:
|
Chris@16
|
813 * @code const_buffers_1(
|
Chris@16
|
814 * static_cast<const void*>(data),
|
Chris@16
|
815 * N * sizeof(PodType)); @endcode
|
Chris@16
|
816 */
|
Chris@16
|
817 template <typename PodType, std::size_t N>
|
Chris@16
|
818 inline const_buffers_1 buffer(const PodType (&data)[N])
|
Chris@16
|
819 {
|
Chris@16
|
820 return const_buffers_1(const_buffer(data, N * sizeof(PodType)));
|
Chris@16
|
821 }
|
Chris@16
|
822
|
Chris@16
|
823 /// Create a new non-modifiable buffer that represents the given POD array.
|
Chris@16
|
824 /**
|
Chris@16
|
825 * @returns A const_buffers_1 value equivalent to:
|
Chris@16
|
826 * @code const_buffers_1(
|
Chris@16
|
827 * static_cast<const void*>(data),
|
Chris@16
|
828 * min(N * sizeof(PodType), max_size_in_bytes)); @endcode
|
Chris@16
|
829 */
|
Chris@16
|
830 template <typename PodType, std::size_t N>
|
Chris@16
|
831 inline const_buffers_1 buffer(const PodType (&data)[N],
|
Chris@16
|
832 std::size_t max_size_in_bytes)
|
Chris@16
|
833 {
|
Chris@16
|
834 return const_buffers_1(
|
Chris@16
|
835 const_buffer(data,
|
Chris@16
|
836 N * sizeof(PodType) < max_size_in_bytes
|
Chris@16
|
837 ? N * sizeof(PodType) : max_size_in_bytes));
|
Chris@16
|
838 }
|
Chris@16
|
839
|
Chris@16
|
840 #if defined(BOOST_ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)
|
Chris@16
|
841
|
Chris@16
|
842 // Borland C++ and Sun Studio think the overloads:
|
Chris@16
|
843 //
|
Chris@16
|
844 // unspecified buffer(boost::array<PodType, N>& array ...);
|
Chris@16
|
845 //
|
Chris@16
|
846 // and
|
Chris@16
|
847 //
|
Chris@16
|
848 // unspecified buffer(boost::array<const PodType, N>& array ...);
|
Chris@16
|
849 //
|
Chris@16
|
850 // are ambiguous. This will be worked around by using a buffer_types traits
|
Chris@16
|
851 // class that contains typedefs for the appropriate buffer and container
|
Chris@16
|
852 // classes, based on whether PodType is const or non-const.
|
Chris@16
|
853
|
Chris@16
|
854 namespace detail {
|
Chris@16
|
855
|
Chris@16
|
856 template <bool IsConst>
|
Chris@16
|
857 struct buffer_types_base;
|
Chris@16
|
858
|
Chris@16
|
859 template <>
|
Chris@16
|
860 struct buffer_types_base<false>
|
Chris@16
|
861 {
|
Chris@16
|
862 typedef mutable_buffer buffer_type;
|
Chris@16
|
863 typedef mutable_buffers_1 container_type;
|
Chris@16
|
864 };
|
Chris@16
|
865
|
Chris@16
|
866 template <>
|
Chris@16
|
867 struct buffer_types_base<true>
|
Chris@16
|
868 {
|
Chris@16
|
869 typedef const_buffer buffer_type;
|
Chris@16
|
870 typedef const_buffers_1 container_type;
|
Chris@16
|
871 };
|
Chris@16
|
872
|
Chris@16
|
873 template <typename PodType>
|
Chris@16
|
874 struct buffer_types
|
Chris@16
|
875 : public buffer_types_base<is_const<PodType>::value>
|
Chris@16
|
876 {
|
Chris@16
|
877 };
|
Chris@16
|
878
|
Chris@16
|
879 } // namespace detail
|
Chris@16
|
880
|
Chris@16
|
881 template <typename PodType, std::size_t N>
|
Chris@16
|
882 inline typename detail::buffer_types<PodType>::container_type
|
Chris@16
|
883 buffer(boost::array<PodType, N>& data)
|
Chris@16
|
884 {
|
Chris@16
|
885 typedef typename boost::asio::detail::buffer_types<PodType>::buffer_type
|
Chris@16
|
886 buffer_type;
|
Chris@16
|
887 typedef typename boost::asio::detail::buffer_types<PodType>::container_type
|
Chris@16
|
888 container_type;
|
Chris@16
|
889 return container_type(
|
Chris@16
|
890 buffer_type(data.c_array(), data.size() * sizeof(PodType)));
|
Chris@16
|
891 }
|
Chris@16
|
892
|
Chris@16
|
893 template <typename PodType, std::size_t N>
|
Chris@16
|
894 inline typename detail::buffer_types<PodType>::container_type
|
Chris@16
|
895 buffer(boost::array<PodType, N>& data, std::size_t max_size_in_bytes)
|
Chris@16
|
896 {
|
Chris@16
|
897 typedef typename boost::asio::detail::buffer_types<PodType>::buffer_type
|
Chris@16
|
898 buffer_type;
|
Chris@16
|
899 typedef typename boost::asio::detail::buffer_types<PodType>::container_type
|
Chris@16
|
900 container_type;
|
Chris@16
|
901 return container_type(
|
Chris@16
|
902 buffer_type(data.c_array(),
|
Chris@16
|
903 data.size() * sizeof(PodType) < max_size_in_bytes
|
Chris@16
|
904 ? data.size() * sizeof(PodType) : max_size_in_bytes));
|
Chris@16
|
905 }
|
Chris@16
|
906
|
Chris@16
|
907 #else // defined(BOOST_ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)
|
Chris@16
|
908
|
Chris@16
|
909 /// Create a new modifiable buffer that represents the given POD array.
|
Chris@16
|
910 /**
|
Chris@16
|
911 * @returns A mutable_buffers_1 value equivalent to:
|
Chris@16
|
912 * @code mutable_buffers_1(
|
Chris@16
|
913 * data.data(),
|
Chris@16
|
914 * data.size() * sizeof(PodType)); @endcode
|
Chris@16
|
915 */
|
Chris@16
|
916 template <typename PodType, std::size_t N>
|
Chris@16
|
917 inline mutable_buffers_1 buffer(boost::array<PodType, N>& data)
|
Chris@16
|
918 {
|
Chris@16
|
919 return mutable_buffers_1(
|
Chris@16
|
920 mutable_buffer(data.c_array(), data.size() * sizeof(PodType)));
|
Chris@16
|
921 }
|
Chris@16
|
922
|
Chris@16
|
923 /// Create a new modifiable buffer that represents the given POD array.
|
Chris@16
|
924 /**
|
Chris@16
|
925 * @returns A mutable_buffers_1 value equivalent to:
|
Chris@16
|
926 * @code mutable_buffers_1(
|
Chris@16
|
927 * data.data(),
|
Chris@16
|
928 * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
|
Chris@16
|
929 */
|
Chris@16
|
930 template <typename PodType, std::size_t N>
|
Chris@16
|
931 inline mutable_buffers_1 buffer(boost::array<PodType, N>& data,
|
Chris@16
|
932 std::size_t max_size_in_bytes)
|
Chris@16
|
933 {
|
Chris@16
|
934 return mutable_buffers_1(
|
Chris@16
|
935 mutable_buffer(data.c_array(),
|
Chris@16
|
936 data.size() * sizeof(PodType) < max_size_in_bytes
|
Chris@16
|
937 ? data.size() * sizeof(PodType) : max_size_in_bytes));
|
Chris@16
|
938 }
|
Chris@16
|
939
|
Chris@16
|
940 /// Create a new non-modifiable buffer that represents the given POD array.
|
Chris@16
|
941 /**
|
Chris@16
|
942 * @returns A const_buffers_1 value equivalent to:
|
Chris@16
|
943 * @code const_buffers_1(
|
Chris@16
|
944 * data.data(),
|
Chris@16
|
945 * data.size() * sizeof(PodType)); @endcode
|
Chris@16
|
946 */
|
Chris@16
|
947 template <typename PodType, std::size_t N>
|
Chris@16
|
948 inline const_buffers_1 buffer(boost::array<const PodType, N>& data)
|
Chris@16
|
949 {
|
Chris@16
|
950 return const_buffers_1(
|
Chris@16
|
951 const_buffer(data.data(), data.size() * sizeof(PodType)));
|
Chris@16
|
952 }
|
Chris@16
|
953
|
Chris@16
|
954 /// Create a new non-modifiable buffer that represents the given POD array.
|
Chris@16
|
955 /**
|
Chris@16
|
956 * @returns A const_buffers_1 value equivalent to:
|
Chris@16
|
957 * @code const_buffers_1(
|
Chris@16
|
958 * data.data(),
|
Chris@16
|
959 * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
|
Chris@16
|
960 */
|
Chris@16
|
961 template <typename PodType, std::size_t N>
|
Chris@16
|
962 inline const_buffers_1 buffer(boost::array<const PodType, N>& data,
|
Chris@16
|
963 std::size_t max_size_in_bytes)
|
Chris@16
|
964 {
|
Chris@16
|
965 return const_buffers_1(
|
Chris@16
|
966 const_buffer(data.data(),
|
Chris@16
|
967 data.size() * sizeof(PodType) < max_size_in_bytes
|
Chris@16
|
968 ? data.size() * sizeof(PodType) : max_size_in_bytes));
|
Chris@16
|
969 }
|
Chris@16
|
970
|
Chris@16
|
971 #endif // defined(BOOST_ASIO_ENABLE_ARRAY_BUFFER_WORKAROUND)
|
Chris@16
|
972
|
Chris@16
|
973 /// Create a new non-modifiable buffer that represents the given POD array.
|
Chris@16
|
974 /**
|
Chris@16
|
975 * @returns A const_buffers_1 value equivalent to:
|
Chris@16
|
976 * @code const_buffers_1(
|
Chris@16
|
977 * data.data(),
|
Chris@16
|
978 * data.size() * sizeof(PodType)); @endcode
|
Chris@16
|
979 */
|
Chris@16
|
980 template <typename PodType, std::size_t N>
|
Chris@16
|
981 inline const_buffers_1 buffer(const boost::array<PodType, N>& data)
|
Chris@16
|
982 {
|
Chris@16
|
983 return const_buffers_1(
|
Chris@16
|
984 const_buffer(data.data(), data.size() * sizeof(PodType)));
|
Chris@16
|
985 }
|
Chris@16
|
986
|
Chris@16
|
987 /// Create a new non-modifiable buffer that represents the given POD array.
|
Chris@16
|
988 /**
|
Chris@16
|
989 * @returns A const_buffers_1 value equivalent to:
|
Chris@16
|
990 * @code const_buffers_1(
|
Chris@16
|
991 * data.data(),
|
Chris@16
|
992 * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
|
Chris@16
|
993 */
|
Chris@16
|
994 template <typename PodType, std::size_t N>
|
Chris@16
|
995 inline const_buffers_1 buffer(const boost::array<PodType, N>& data,
|
Chris@16
|
996 std::size_t max_size_in_bytes)
|
Chris@16
|
997 {
|
Chris@16
|
998 return const_buffers_1(
|
Chris@16
|
999 const_buffer(data.data(),
|
Chris@16
|
1000 data.size() * sizeof(PodType) < max_size_in_bytes
|
Chris@16
|
1001 ? data.size() * sizeof(PodType) : max_size_in_bytes));
|
Chris@16
|
1002 }
|
Chris@16
|
1003
|
Chris@16
|
1004 #if defined(BOOST_ASIO_HAS_STD_ARRAY) || defined(GENERATING_DOCUMENTATION)
|
Chris@16
|
1005
|
Chris@16
|
1006 /// Create a new modifiable buffer that represents the given POD array.
|
Chris@16
|
1007 /**
|
Chris@16
|
1008 * @returns A mutable_buffers_1 value equivalent to:
|
Chris@16
|
1009 * @code mutable_buffers_1(
|
Chris@16
|
1010 * data.data(),
|
Chris@16
|
1011 * data.size() * sizeof(PodType)); @endcode
|
Chris@16
|
1012 */
|
Chris@16
|
1013 template <typename PodType, std::size_t N>
|
Chris@16
|
1014 inline mutable_buffers_1 buffer(std::array<PodType, N>& data)
|
Chris@16
|
1015 {
|
Chris@16
|
1016 return mutable_buffers_1(
|
Chris@16
|
1017 mutable_buffer(data.data(), data.size() * sizeof(PodType)));
|
Chris@16
|
1018 }
|
Chris@16
|
1019
|
Chris@16
|
1020 /// Create a new modifiable buffer that represents the given POD array.
|
Chris@16
|
1021 /**
|
Chris@16
|
1022 * @returns A mutable_buffers_1 value equivalent to:
|
Chris@16
|
1023 * @code mutable_buffers_1(
|
Chris@16
|
1024 * data.data(),
|
Chris@16
|
1025 * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
|
Chris@16
|
1026 */
|
Chris@16
|
1027 template <typename PodType, std::size_t N>
|
Chris@16
|
1028 inline mutable_buffers_1 buffer(std::array<PodType, N>& data,
|
Chris@16
|
1029 std::size_t max_size_in_bytes)
|
Chris@16
|
1030 {
|
Chris@16
|
1031 return mutable_buffers_1(
|
Chris@16
|
1032 mutable_buffer(data.data(),
|
Chris@16
|
1033 data.size() * sizeof(PodType) < max_size_in_bytes
|
Chris@16
|
1034 ? data.size() * sizeof(PodType) : max_size_in_bytes));
|
Chris@16
|
1035 }
|
Chris@16
|
1036
|
Chris@16
|
1037 /// Create a new non-modifiable buffer that represents the given POD array.
|
Chris@16
|
1038 /**
|
Chris@16
|
1039 * @returns A const_buffers_1 value equivalent to:
|
Chris@16
|
1040 * @code const_buffers_1(
|
Chris@16
|
1041 * data.data(),
|
Chris@16
|
1042 * data.size() * sizeof(PodType)); @endcode
|
Chris@16
|
1043 */
|
Chris@16
|
1044 template <typename PodType, std::size_t N>
|
Chris@16
|
1045 inline const_buffers_1 buffer(std::array<const PodType, N>& data)
|
Chris@16
|
1046 {
|
Chris@16
|
1047 return const_buffers_1(
|
Chris@16
|
1048 const_buffer(data.data(), data.size() * sizeof(PodType)));
|
Chris@16
|
1049 }
|
Chris@16
|
1050
|
Chris@16
|
1051 /// Create a new non-modifiable buffer that represents the given POD array.
|
Chris@16
|
1052 /**
|
Chris@16
|
1053 * @returns A const_buffers_1 value equivalent to:
|
Chris@16
|
1054 * @code const_buffers_1(
|
Chris@16
|
1055 * data.data(),
|
Chris@16
|
1056 * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
|
Chris@16
|
1057 */
|
Chris@16
|
1058 template <typename PodType, std::size_t N>
|
Chris@16
|
1059 inline const_buffers_1 buffer(std::array<const PodType, N>& data,
|
Chris@16
|
1060 std::size_t max_size_in_bytes)
|
Chris@16
|
1061 {
|
Chris@16
|
1062 return const_buffers_1(
|
Chris@16
|
1063 const_buffer(data.data(),
|
Chris@16
|
1064 data.size() * sizeof(PodType) < max_size_in_bytes
|
Chris@16
|
1065 ? data.size() * sizeof(PodType) : max_size_in_bytes));
|
Chris@16
|
1066 }
|
Chris@16
|
1067
|
Chris@16
|
1068 /// Create a new non-modifiable buffer that represents the given POD array.
|
Chris@16
|
1069 /**
|
Chris@16
|
1070 * @returns A const_buffers_1 value equivalent to:
|
Chris@16
|
1071 * @code const_buffers_1(
|
Chris@16
|
1072 * data.data(),
|
Chris@16
|
1073 * data.size() * sizeof(PodType)); @endcode
|
Chris@16
|
1074 */
|
Chris@16
|
1075 template <typename PodType, std::size_t N>
|
Chris@16
|
1076 inline const_buffers_1 buffer(const std::array<PodType, N>& data)
|
Chris@16
|
1077 {
|
Chris@16
|
1078 return const_buffers_1(
|
Chris@16
|
1079 const_buffer(data.data(), data.size() * sizeof(PodType)));
|
Chris@16
|
1080 }
|
Chris@16
|
1081
|
Chris@16
|
1082 /// Create a new non-modifiable buffer that represents the given POD array.
|
Chris@16
|
1083 /**
|
Chris@16
|
1084 * @returns A const_buffers_1 value equivalent to:
|
Chris@16
|
1085 * @code const_buffers_1(
|
Chris@16
|
1086 * data.data(),
|
Chris@16
|
1087 * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
|
Chris@16
|
1088 */
|
Chris@16
|
1089 template <typename PodType, std::size_t N>
|
Chris@16
|
1090 inline const_buffers_1 buffer(const std::array<PodType, N>& data,
|
Chris@16
|
1091 std::size_t max_size_in_bytes)
|
Chris@16
|
1092 {
|
Chris@16
|
1093 return const_buffers_1(
|
Chris@16
|
1094 const_buffer(data.data(),
|
Chris@16
|
1095 data.size() * sizeof(PodType) < max_size_in_bytes
|
Chris@16
|
1096 ? data.size() * sizeof(PodType) : max_size_in_bytes));
|
Chris@16
|
1097 }
|
Chris@16
|
1098
|
Chris@16
|
1099 #endif // defined(BOOST_ASIO_HAS_STD_ARRAY) || defined(GENERATING_DOCUMENTATION)
|
Chris@16
|
1100
|
Chris@16
|
1101 /// Create a new modifiable buffer that represents the given POD vector.
|
Chris@16
|
1102 /**
|
Chris@16
|
1103 * @returns A mutable_buffers_1 value equivalent to:
|
Chris@16
|
1104 * @code mutable_buffers_1(
|
Chris@16
|
1105 * data.size() ? &data[0] : 0,
|
Chris@16
|
1106 * data.size() * sizeof(PodType)); @endcode
|
Chris@16
|
1107 *
|
Chris@16
|
1108 * @note The buffer is invalidated by any vector operation that would also
|
Chris@16
|
1109 * invalidate iterators.
|
Chris@16
|
1110 */
|
Chris@16
|
1111 template <typename PodType, typename Allocator>
|
Chris@16
|
1112 inline mutable_buffers_1 buffer(std::vector<PodType, Allocator>& data)
|
Chris@16
|
1113 {
|
Chris@16
|
1114 return mutable_buffers_1(
|
Chris@16
|
1115 mutable_buffer(data.size() ? &data[0] : 0, data.size() * sizeof(PodType)
|
Chris@16
|
1116 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
|
Chris@16
|
1117 , detail::buffer_debug_check<
|
Chris@16
|
1118 typename std::vector<PodType, Allocator>::iterator
|
Chris@16
|
1119 >(data.begin())
|
Chris@16
|
1120 #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
|
Chris@16
|
1121 ));
|
Chris@16
|
1122 }
|
Chris@16
|
1123
|
Chris@16
|
1124 /// Create a new modifiable buffer that represents the given POD vector.
|
Chris@16
|
1125 /**
|
Chris@16
|
1126 * @returns A mutable_buffers_1 value equivalent to:
|
Chris@16
|
1127 * @code mutable_buffers_1(
|
Chris@16
|
1128 * data.size() ? &data[0] : 0,
|
Chris@16
|
1129 * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
|
Chris@16
|
1130 *
|
Chris@16
|
1131 * @note The buffer is invalidated by any vector operation that would also
|
Chris@16
|
1132 * invalidate iterators.
|
Chris@16
|
1133 */
|
Chris@16
|
1134 template <typename PodType, typename Allocator>
|
Chris@16
|
1135 inline mutable_buffers_1 buffer(std::vector<PodType, Allocator>& data,
|
Chris@16
|
1136 std::size_t max_size_in_bytes)
|
Chris@16
|
1137 {
|
Chris@16
|
1138 return mutable_buffers_1(
|
Chris@16
|
1139 mutable_buffer(data.size() ? &data[0] : 0,
|
Chris@16
|
1140 data.size() * sizeof(PodType) < max_size_in_bytes
|
Chris@16
|
1141 ? data.size() * sizeof(PodType) : max_size_in_bytes
|
Chris@16
|
1142 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
|
Chris@16
|
1143 , detail::buffer_debug_check<
|
Chris@16
|
1144 typename std::vector<PodType, Allocator>::iterator
|
Chris@16
|
1145 >(data.begin())
|
Chris@16
|
1146 #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
|
Chris@16
|
1147 ));
|
Chris@16
|
1148 }
|
Chris@16
|
1149
|
Chris@16
|
1150 /// Create a new non-modifiable buffer that represents the given POD vector.
|
Chris@16
|
1151 /**
|
Chris@16
|
1152 * @returns A const_buffers_1 value equivalent to:
|
Chris@16
|
1153 * @code const_buffers_1(
|
Chris@16
|
1154 * data.size() ? &data[0] : 0,
|
Chris@16
|
1155 * data.size() * sizeof(PodType)); @endcode
|
Chris@16
|
1156 *
|
Chris@16
|
1157 * @note The buffer is invalidated by any vector operation that would also
|
Chris@16
|
1158 * invalidate iterators.
|
Chris@16
|
1159 */
|
Chris@16
|
1160 template <typename PodType, typename Allocator>
|
Chris@16
|
1161 inline const_buffers_1 buffer(
|
Chris@16
|
1162 const std::vector<PodType, Allocator>& data)
|
Chris@16
|
1163 {
|
Chris@16
|
1164 return const_buffers_1(
|
Chris@16
|
1165 const_buffer(data.size() ? &data[0] : 0, data.size() * sizeof(PodType)
|
Chris@16
|
1166 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
|
Chris@16
|
1167 , detail::buffer_debug_check<
|
Chris@16
|
1168 typename std::vector<PodType, Allocator>::const_iterator
|
Chris@16
|
1169 >(data.begin())
|
Chris@16
|
1170 #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
|
Chris@16
|
1171 ));
|
Chris@16
|
1172 }
|
Chris@16
|
1173
|
Chris@16
|
1174 /// Create a new non-modifiable buffer that represents the given POD vector.
|
Chris@16
|
1175 /**
|
Chris@16
|
1176 * @returns A const_buffers_1 value equivalent to:
|
Chris@16
|
1177 * @code const_buffers_1(
|
Chris@16
|
1178 * data.size() ? &data[0] : 0,
|
Chris@16
|
1179 * min(data.size() * sizeof(PodType), max_size_in_bytes)); @endcode
|
Chris@16
|
1180 *
|
Chris@16
|
1181 * @note The buffer is invalidated by any vector operation that would also
|
Chris@16
|
1182 * invalidate iterators.
|
Chris@16
|
1183 */
|
Chris@16
|
1184 template <typename PodType, typename Allocator>
|
Chris@16
|
1185 inline const_buffers_1 buffer(
|
Chris@16
|
1186 const std::vector<PodType, Allocator>& data, std::size_t max_size_in_bytes)
|
Chris@16
|
1187 {
|
Chris@16
|
1188 return const_buffers_1(
|
Chris@16
|
1189 const_buffer(data.size() ? &data[0] : 0,
|
Chris@16
|
1190 data.size() * sizeof(PodType) < max_size_in_bytes
|
Chris@16
|
1191 ? data.size() * sizeof(PodType) : max_size_in_bytes
|
Chris@16
|
1192 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
|
Chris@16
|
1193 , detail::buffer_debug_check<
|
Chris@16
|
1194 typename std::vector<PodType, Allocator>::const_iterator
|
Chris@16
|
1195 >(data.begin())
|
Chris@16
|
1196 #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
|
Chris@16
|
1197 ));
|
Chris@16
|
1198 }
|
Chris@16
|
1199
|
Chris@16
|
1200 /// Create a new non-modifiable buffer that represents the given string.
|
Chris@16
|
1201 /**
|
Chris@16
|
1202 * @returns <tt>const_buffers_1(data.data(), data.size() * sizeof(Elem))</tt>.
|
Chris@16
|
1203 *
|
Chris@16
|
1204 * @note The buffer is invalidated by any non-const operation called on the
|
Chris@16
|
1205 * given string object.
|
Chris@16
|
1206 */
|
Chris@16
|
1207 template <typename Elem, typename Traits, typename Allocator>
|
Chris@16
|
1208 inline const_buffers_1 buffer(
|
Chris@16
|
1209 const std::basic_string<Elem, Traits, Allocator>& data)
|
Chris@16
|
1210 {
|
Chris@16
|
1211 return const_buffers_1(const_buffer(data.data(), data.size() * sizeof(Elem)
|
Chris@16
|
1212 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
|
Chris@16
|
1213 , detail::buffer_debug_check<
|
Chris@16
|
1214 typename std::basic_string<Elem, Traits, Allocator>::const_iterator
|
Chris@16
|
1215 >(data.begin())
|
Chris@16
|
1216 #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
|
Chris@16
|
1217 ));
|
Chris@16
|
1218 }
|
Chris@16
|
1219
|
Chris@16
|
1220 /// Create a new non-modifiable buffer that represents the given string.
|
Chris@16
|
1221 /**
|
Chris@16
|
1222 * @returns A const_buffers_1 value equivalent to:
|
Chris@16
|
1223 * @code const_buffers_1(
|
Chris@16
|
1224 * data.data(),
|
Chris@16
|
1225 * min(data.size() * sizeof(Elem), max_size_in_bytes)); @endcode
|
Chris@16
|
1226 *
|
Chris@16
|
1227 * @note The buffer is invalidated by any non-const operation called on the
|
Chris@16
|
1228 * given string object.
|
Chris@16
|
1229 */
|
Chris@16
|
1230 template <typename Elem, typename Traits, typename Allocator>
|
Chris@16
|
1231 inline const_buffers_1 buffer(
|
Chris@16
|
1232 const std::basic_string<Elem, Traits, Allocator>& data,
|
Chris@16
|
1233 std::size_t max_size_in_bytes)
|
Chris@16
|
1234 {
|
Chris@16
|
1235 return const_buffers_1(
|
Chris@16
|
1236 const_buffer(data.data(),
|
Chris@16
|
1237 data.size() * sizeof(Elem) < max_size_in_bytes
|
Chris@16
|
1238 ? data.size() * sizeof(Elem) : max_size_in_bytes
|
Chris@16
|
1239 #if defined(BOOST_ASIO_ENABLE_BUFFER_DEBUGGING)
|
Chris@16
|
1240 , detail::buffer_debug_check<
|
Chris@16
|
1241 typename std::basic_string<Elem, Traits, Allocator>::const_iterator
|
Chris@16
|
1242 >(data.begin())
|
Chris@16
|
1243 #endif // BOOST_ASIO_ENABLE_BUFFER_DEBUGGING
|
Chris@16
|
1244 ));
|
Chris@16
|
1245 }
|
Chris@16
|
1246
|
Chris@16
|
1247 /*@}*/
|
Chris@16
|
1248
|
Chris@16
|
1249 /** @defgroup buffer_copy boost::asio::buffer_copy
|
Chris@16
|
1250 *
|
Chris@16
|
1251 * @brief The boost::asio::buffer_copy function is used to copy bytes from a
|
Chris@16
|
1252 * source buffer (or buffer sequence) to a target buffer (or buffer sequence).
|
Chris@16
|
1253 *
|
Chris@16
|
1254 * The @c buffer_copy function is available in two forms:
|
Chris@16
|
1255 *
|
Chris@16
|
1256 * @li A 2-argument form: @c buffer_copy(target, source)
|
Chris@16
|
1257 *
|
Chris@16
|
1258 * @li A 3-argument form: @c buffer_copy(target, source, max_bytes_to_copy)
|
Chris@16
|
1259
|
Chris@16
|
1260 * Both forms return the number of bytes actually copied. The number of bytes
|
Chris@16
|
1261 * copied is the lesser of:
|
Chris@16
|
1262 *
|
Chris@16
|
1263 * @li @c buffer_size(target)
|
Chris@16
|
1264 *
|
Chris@16
|
1265 * @li @c buffer_size(source)
|
Chris@16
|
1266 *
|
Chris@16
|
1267 * @li @c If specified, @c max_bytes_to_copy.
|
Chris@16
|
1268 *
|
Chris@16
|
1269 * This prevents buffer overflow, regardless of the buffer sizes used in the
|
Chris@16
|
1270 * copy operation.
|
Chris@101
|
1271 *
|
Chris@101
|
1272 * Note that @ref buffer_copy is implemented in terms of @c memcpy, and
|
Chris@101
|
1273 * consequently it cannot be used to copy between overlapping memory regions.
|
Chris@16
|
1274 */
|
Chris@16
|
1275 /*@{*/
|
Chris@16
|
1276
|
Chris@16
|
1277 /// Copies bytes from a source buffer to a target buffer.
|
Chris@16
|
1278 /**
|
Chris@16
|
1279 * @param target A modifiable buffer representing the memory region to which
|
Chris@16
|
1280 * the bytes will be copied.
|
Chris@16
|
1281 *
|
Chris@16
|
1282 * @param source A non-modifiable buffer representing the memory region from
|
Chris@16
|
1283 * which the bytes will be copied.
|
Chris@16
|
1284 *
|
Chris@16
|
1285 * @returns The number of bytes copied.
|
Chris@16
|
1286 *
|
Chris@16
|
1287 * @note The number of bytes copied is the lesser of:
|
Chris@16
|
1288 *
|
Chris@16
|
1289 * @li @c buffer_size(target)
|
Chris@16
|
1290 *
|
Chris@16
|
1291 * @li @c buffer_size(source)
|
Chris@101
|
1292 *
|
Chris@101
|
1293 * This function is implemented in terms of @c memcpy, and consequently it
|
Chris@101
|
1294 * cannot be used to copy between overlapping memory regions.
|
Chris@16
|
1295 */
|
Chris@16
|
1296 inline std::size_t buffer_copy(const mutable_buffer& target,
|
Chris@16
|
1297 const const_buffer& source)
|
Chris@16
|
1298 {
|
Chris@16
|
1299 using namespace std; // For memcpy.
|
Chris@16
|
1300 std::size_t target_size = buffer_size(target);
|
Chris@16
|
1301 std::size_t source_size = buffer_size(source);
|
Chris@16
|
1302 std::size_t n = target_size < source_size ? target_size : source_size;
|
Chris@16
|
1303 memcpy(buffer_cast<void*>(target), buffer_cast<const void*>(source), n);
|
Chris@16
|
1304 return n;
|
Chris@16
|
1305 }
|
Chris@16
|
1306
|
Chris@16
|
1307 /// Copies bytes from a source buffer to a target buffer.
|
Chris@16
|
1308 /**
|
Chris@16
|
1309 * @param target A modifiable buffer representing the memory region to which
|
Chris@16
|
1310 * the bytes will be copied.
|
Chris@16
|
1311 *
|
Chris@16
|
1312 * @param source A non-modifiable buffer representing the memory region from
|
Chris@16
|
1313 * which the bytes will be copied.
|
Chris@16
|
1314 *
|
Chris@16
|
1315 * @returns The number of bytes copied.
|
Chris@16
|
1316 *
|
Chris@16
|
1317 * @note The number of bytes copied is the lesser of:
|
Chris@16
|
1318 *
|
Chris@16
|
1319 * @li @c buffer_size(target)
|
Chris@16
|
1320 *
|
Chris@16
|
1321 * @li @c buffer_size(source)
|
Chris@101
|
1322 *
|
Chris@101
|
1323 * This function is implemented in terms of @c memcpy, and consequently it
|
Chris@101
|
1324 * cannot be used to copy between overlapping memory regions.
|
Chris@16
|
1325 */
|
Chris@16
|
1326 inline std::size_t buffer_copy(const mutable_buffer& target,
|
Chris@16
|
1327 const const_buffers_1& source)
|
Chris@16
|
1328 {
|
Chris@16
|
1329 return buffer_copy(target, static_cast<const const_buffer&>(source));
|
Chris@16
|
1330 }
|
Chris@16
|
1331
|
Chris@16
|
1332 /// Copies bytes from a source buffer to a target buffer.
|
Chris@16
|
1333 /**
|
Chris@16
|
1334 * @param target A modifiable buffer representing the memory region to which
|
Chris@16
|
1335 * the bytes will be copied.
|
Chris@16
|
1336 *
|
Chris@16
|
1337 * @param source A modifiable buffer representing the memory region from which
|
Chris@16
|
1338 * the bytes will be copied. The contents of the source buffer will not be
|
Chris@16
|
1339 * modified.
|
Chris@16
|
1340 *
|
Chris@16
|
1341 * @returns The number of bytes copied.
|
Chris@16
|
1342 *
|
Chris@16
|
1343 * @note The number of bytes copied is the lesser of:
|
Chris@16
|
1344 *
|
Chris@16
|
1345 * @li @c buffer_size(target)
|
Chris@16
|
1346 *
|
Chris@16
|
1347 * @li @c buffer_size(source)
|
Chris@101
|
1348 *
|
Chris@101
|
1349 * This function is implemented in terms of @c memcpy, and consequently it
|
Chris@101
|
1350 * cannot be used to copy between overlapping memory regions.
|
Chris@16
|
1351 */
|
Chris@16
|
1352 inline std::size_t buffer_copy(const mutable_buffer& target,
|
Chris@16
|
1353 const mutable_buffer& source)
|
Chris@16
|
1354 {
|
Chris@16
|
1355 return buffer_copy(target, const_buffer(source));
|
Chris@16
|
1356 }
|
Chris@16
|
1357
|
Chris@16
|
1358 /// Copies bytes from a source buffer to a target buffer.
|
Chris@16
|
1359 /**
|
Chris@16
|
1360 * @param target A modifiable buffer representing the memory region to which
|
Chris@16
|
1361 * the bytes will be copied.
|
Chris@16
|
1362 *
|
Chris@16
|
1363 * @param source A modifiable buffer representing the memory region from which
|
Chris@16
|
1364 * the bytes will be copied. The contents of the source buffer will not be
|
Chris@16
|
1365 * modified.
|
Chris@16
|
1366 *
|
Chris@16
|
1367 * @returns The number of bytes copied.
|
Chris@16
|
1368 *
|
Chris@16
|
1369 * @note The number of bytes copied is the lesser of:
|
Chris@16
|
1370 *
|
Chris@16
|
1371 * @li @c buffer_size(target)
|
Chris@16
|
1372 *
|
Chris@16
|
1373 * @li @c buffer_size(source)
|
Chris@101
|
1374 *
|
Chris@101
|
1375 * This function is implemented in terms of @c memcpy, and consequently it
|
Chris@101
|
1376 * cannot be used to copy between overlapping memory regions.
|
Chris@16
|
1377 */
|
Chris@16
|
1378 inline std::size_t buffer_copy(const mutable_buffer& target,
|
Chris@16
|
1379 const mutable_buffers_1& source)
|
Chris@16
|
1380 {
|
Chris@16
|
1381 return buffer_copy(target, const_buffer(source));
|
Chris@16
|
1382 }
|
Chris@16
|
1383
|
Chris@16
|
1384 /// Copies bytes from a source buffer sequence to a target buffer.
|
Chris@16
|
1385 /**
|
Chris@16
|
1386 * @param target A modifiable buffer representing the memory region to which
|
Chris@16
|
1387 * the bytes will be copied.
|
Chris@16
|
1388 *
|
Chris@16
|
1389 * @param source A non-modifiable buffer sequence representing the memory
|
Chris@16
|
1390 * regions from which the bytes will be copied.
|
Chris@16
|
1391 *
|
Chris@16
|
1392 * @returns The number of bytes copied.
|
Chris@16
|
1393 *
|
Chris@16
|
1394 * @note The number of bytes copied is the lesser of:
|
Chris@16
|
1395 *
|
Chris@16
|
1396 * @li @c buffer_size(target)
|
Chris@16
|
1397 *
|
Chris@16
|
1398 * @li @c buffer_size(source)
|
Chris@101
|
1399 *
|
Chris@101
|
1400 * This function is implemented in terms of @c memcpy, and consequently it
|
Chris@101
|
1401 * cannot be used to copy between overlapping memory regions.
|
Chris@16
|
1402 */
|
Chris@16
|
1403 template <typename ConstBufferSequence>
|
Chris@16
|
1404 std::size_t buffer_copy(const mutable_buffer& target,
|
Chris@16
|
1405 const ConstBufferSequence& source)
|
Chris@16
|
1406 {
|
Chris@16
|
1407 std::size_t total_bytes_copied = 0;
|
Chris@16
|
1408
|
Chris@16
|
1409 typename ConstBufferSequence::const_iterator source_iter = source.begin();
|
Chris@16
|
1410 typename ConstBufferSequence::const_iterator source_end = source.end();
|
Chris@16
|
1411
|
Chris@16
|
1412 for (mutable_buffer target_buffer(target);
|
Chris@16
|
1413 buffer_size(target_buffer) && source_iter != source_end; ++source_iter)
|
Chris@16
|
1414 {
|
Chris@16
|
1415 const_buffer source_buffer(*source_iter);
|
Chris@16
|
1416 std::size_t bytes_copied = buffer_copy(target_buffer, source_buffer);
|
Chris@16
|
1417 total_bytes_copied += bytes_copied;
|
Chris@16
|
1418 target_buffer = target_buffer + bytes_copied;
|
Chris@16
|
1419 }
|
Chris@16
|
1420
|
Chris@16
|
1421 return total_bytes_copied;
|
Chris@16
|
1422 }
|
Chris@16
|
1423
|
Chris@16
|
1424 /// Copies bytes from a source buffer to a target buffer.
|
Chris@16
|
1425 /**
|
Chris@16
|
1426 * @param target A modifiable buffer representing the memory region to which
|
Chris@16
|
1427 * the bytes will be copied.
|
Chris@16
|
1428 *
|
Chris@16
|
1429 * @param source A non-modifiable buffer representing the memory region from
|
Chris@16
|
1430 * which the bytes will be copied.
|
Chris@16
|
1431 *
|
Chris@16
|
1432 * @returns The number of bytes copied.
|
Chris@16
|
1433 *
|
Chris@16
|
1434 * @note The number of bytes copied is the lesser of:
|
Chris@16
|
1435 *
|
Chris@16
|
1436 * @li @c buffer_size(target)
|
Chris@16
|
1437 *
|
Chris@16
|
1438 * @li @c buffer_size(source)
|
Chris@101
|
1439 *
|
Chris@101
|
1440 * This function is implemented in terms of @c memcpy, and consequently it
|
Chris@101
|
1441 * cannot be used to copy between overlapping memory regions.
|
Chris@16
|
1442 */
|
Chris@16
|
1443 inline std::size_t buffer_copy(const mutable_buffers_1& target,
|
Chris@16
|
1444 const const_buffer& source)
|
Chris@16
|
1445 {
|
Chris@16
|
1446 return buffer_copy(static_cast<const mutable_buffer&>(target), source);
|
Chris@16
|
1447 }
|
Chris@16
|
1448
|
Chris@16
|
1449 /// Copies bytes from a source buffer to a target buffer.
|
Chris@16
|
1450 /**
|
Chris@16
|
1451 * @param target A modifiable buffer representing the memory region to which
|
Chris@16
|
1452 * the bytes will be copied.
|
Chris@16
|
1453 *
|
Chris@16
|
1454 * @param source A non-modifiable buffer representing the memory region from
|
Chris@16
|
1455 * which the bytes will be copied.
|
Chris@16
|
1456 *
|
Chris@16
|
1457 * @returns The number of bytes copied.
|
Chris@16
|
1458 *
|
Chris@16
|
1459 * @note The number of bytes copied is the lesser of:
|
Chris@16
|
1460 *
|
Chris@16
|
1461 * @li @c buffer_size(target)
|
Chris@16
|
1462 *
|
Chris@16
|
1463 * @li @c buffer_size(source)
|
Chris@101
|
1464 *
|
Chris@101
|
1465 * This function is implemented in terms of @c memcpy, and consequently it
|
Chris@101
|
1466 * cannot be used to copy between overlapping memory regions.
|
Chris@16
|
1467 */
|
Chris@16
|
1468 inline std::size_t buffer_copy(const mutable_buffers_1& target,
|
Chris@16
|
1469 const const_buffers_1& source)
|
Chris@16
|
1470 {
|
Chris@16
|
1471 return buffer_copy(static_cast<const mutable_buffer&>(target),
|
Chris@16
|
1472 static_cast<const const_buffer&>(source));
|
Chris@16
|
1473 }
|
Chris@16
|
1474
|
Chris@16
|
1475 /// Copies bytes from a source buffer to a target buffer.
|
Chris@16
|
1476 /**
|
Chris@16
|
1477 * @param target A modifiable buffer representing the memory region to which
|
Chris@16
|
1478 * the bytes will be copied.
|
Chris@16
|
1479 *
|
Chris@16
|
1480 * @param source A modifiable buffer representing the memory region from which
|
Chris@16
|
1481 * the bytes will be copied. The contents of the source buffer will not be
|
Chris@16
|
1482 * modified.
|
Chris@16
|
1483 *
|
Chris@16
|
1484 * @returns The number of bytes copied.
|
Chris@16
|
1485 *
|
Chris@16
|
1486 * @note The number of bytes copied is the lesser of:
|
Chris@16
|
1487 *
|
Chris@16
|
1488 * @li @c buffer_size(target)
|
Chris@16
|
1489 *
|
Chris@16
|
1490 * @li @c buffer_size(source)
|
Chris@101
|
1491 *
|
Chris@101
|
1492 * This function is implemented in terms of @c memcpy, and consequently it
|
Chris@101
|
1493 * cannot be used to copy between overlapping memory regions.
|
Chris@16
|
1494 */
|
Chris@16
|
1495 inline std::size_t buffer_copy(const mutable_buffers_1& target,
|
Chris@16
|
1496 const mutable_buffer& source)
|
Chris@16
|
1497 {
|
Chris@16
|
1498 return buffer_copy(static_cast<const mutable_buffer&>(target),
|
Chris@16
|
1499 const_buffer(source));
|
Chris@16
|
1500 }
|
Chris@16
|
1501
|
Chris@16
|
1502 /// Copies bytes from a source buffer to a target buffer.
|
Chris@16
|
1503 /**
|
Chris@16
|
1504 * @param target A modifiable buffer representing the memory region to which
|
Chris@16
|
1505 * the bytes will be copied.
|
Chris@16
|
1506 *
|
Chris@16
|
1507 * @param source A modifiable buffer representing the memory region from which
|
Chris@16
|
1508 * the bytes will be copied. The contents of the source buffer will not be
|
Chris@16
|
1509 * modified.
|
Chris@16
|
1510 *
|
Chris@16
|
1511 * @returns The number of bytes copied.
|
Chris@16
|
1512 *
|
Chris@16
|
1513 * @note The number of bytes copied is the lesser of:
|
Chris@16
|
1514 *
|
Chris@16
|
1515 * @li @c buffer_size(target)
|
Chris@16
|
1516 *
|
Chris@16
|
1517 * @li @c buffer_size(source)
|
Chris@101
|
1518 *
|
Chris@101
|
1519 * This function is implemented in terms of @c memcpy, and consequently it
|
Chris@101
|
1520 * cannot be used to copy between overlapping memory regions.
|
Chris@16
|
1521 */
|
Chris@16
|
1522 inline std::size_t buffer_copy(const mutable_buffers_1& target,
|
Chris@16
|
1523 const mutable_buffers_1& source)
|
Chris@16
|
1524 {
|
Chris@16
|
1525 return buffer_copy(static_cast<const mutable_buffer&>(target),
|
Chris@16
|
1526 const_buffer(source));
|
Chris@16
|
1527 }
|
Chris@16
|
1528
|
Chris@16
|
1529 /// Copies bytes from a source buffer sequence to a target buffer.
|
Chris@16
|
1530 /**
|
Chris@16
|
1531 * @param target A modifiable buffer representing the memory region to which
|
Chris@16
|
1532 * the bytes will be copied.
|
Chris@16
|
1533 *
|
Chris@16
|
1534 * @param source A non-modifiable buffer sequence representing the memory
|
Chris@16
|
1535 * regions from which the bytes will be copied.
|
Chris@16
|
1536 *
|
Chris@16
|
1537 * @returns The number of bytes copied.
|
Chris@16
|
1538 *
|
Chris@16
|
1539 * @note The number of bytes copied is the lesser of:
|
Chris@16
|
1540 *
|
Chris@16
|
1541 * @li @c buffer_size(target)
|
Chris@16
|
1542 *
|
Chris@16
|
1543 * @li @c buffer_size(source)
|
Chris@101
|
1544 *
|
Chris@101
|
1545 * This function is implemented in terms of @c memcpy, and consequently it
|
Chris@101
|
1546 * cannot be used to copy between overlapping memory regions.
|
Chris@16
|
1547 */
|
Chris@16
|
1548 template <typename ConstBufferSequence>
|
Chris@16
|
1549 inline std::size_t buffer_copy(const mutable_buffers_1& target,
|
Chris@16
|
1550 const ConstBufferSequence& source)
|
Chris@16
|
1551 {
|
Chris@16
|
1552 return buffer_copy(static_cast<const mutable_buffer&>(target), source);
|
Chris@16
|
1553 }
|
Chris@16
|
1554
|
Chris@16
|
1555 /// Copies bytes from a source buffer to a target buffer sequence.
|
Chris@16
|
1556 /**
|
Chris@16
|
1557 * @param target A modifiable buffer sequence representing the memory regions to
|
Chris@16
|
1558 * which the bytes will be copied.
|
Chris@16
|
1559 *
|
Chris@16
|
1560 * @param source A non-modifiable buffer representing the memory region from
|
Chris@16
|
1561 * which the bytes will be copied.
|
Chris@16
|
1562 *
|
Chris@16
|
1563 * @returns The number of bytes copied.
|
Chris@16
|
1564 *
|
Chris@16
|
1565 * @note The number of bytes copied is the lesser of:
|
Chris@16
|
1566 *
|
Chris@16
|
1567 * @li @c buffer_size(target)
|
Chris@16
|
1568 *
|
Chris@16
|
1569 * @li @c buffer_size(source)
|
Chris@101
|
1570 *
|
Chris@101
|
1571 * This function is implemented in terms of @c memcpy, and consequently it
|
Chris@101
|
1572 * cannot be used to copy between overlapping memory regions.
|
Chris@16
|
1573 */
|
Chris@16
|
1574 template <typename MutableBufferSequence>
|
Chris@16
|
1575 std::size_t buffer_copy(const MutableBufferSequence& target,
|
Chris@16
|
1576 const const_buffer& source)
|
Chris@16
|
1577 {
|
Chris@16
|
1578 std::size_t total_bytes_copied = 0;
|
Chris@16
|
1579
|
Chris@16
|
1580 typename MutableBufferSequence::const_iterator target_iter = target.begin();
|
Chris@16
|
1581 typename MutableBufferSequence::const_iterator target_end = target.end();
|
Chris@16
|
1582
|
Chris@16
|
1583 for (const_buffer source_buffer(source);
|
Chris@16
|
1584 buffer_size(source_buffer) && target_iter != target_end; ++target_iter)
|
Chris@16
|
1585 {
|
Chris@16
|
1586 mutable_buffer target_buffer(*target_iter);
|
Chris@16
|
1587 std::size_t bytes_copied = buffer_copy(target_buffer, source_buffer);
|
Chris@16
|
1588 total_bytes_copied += bytes_copied;
|
Chris@16
|
1589 source_buffer = source_buffer + bytes_copied;
|
Chris@16
|
1590 }
|
Chris@16
|
1591
|
Chris@16
|
1592 return total_bytes_copied;
|
Chris@16
|
1593 }
|
Chris@16
|
1594
|
Chris@16
|
1595 /// Copies bytes from a source buffer to a target buffer sequence.
|
Chris@16
|
1596 /**
|
Chris@16
|
1597 * @param target A modifiable buffer sequence representing the memory regions to
|
Chris@16
|
1598 * which the bytes will be copied.
|
Chris@16
|
1599 *
|
Chris@16
|
1600 * @param source A non-modifiable buffer representing the memory region from
|
Chris@16
|
1601 * which the bytes will be copied.
|
Chris@16
|
1602 *
|
Chris@16
|
1603 * @returns The number of bytes copied.
|
Chris@16
|
1604 *
|
Chris@16
|
1605 * @note The number of bytes copied is the lesser of:
|
Chris@16
|
1606 *
|
Chris@16
|
1607 * @li @c buffer_size(target)
|
Chris@16
|
1608 *
|
Chris@16
|
1609 * @li @c buffer_size(source)
|
Chris@101
|
1610 *
|
Chris@101
|
1611 * This function is implemented in terms of @c memcpy, and consequently it
|
Chris@101
|
1612 * cannot be used to copy between overlapping memory regions.
|
Chris@16
|
1613 */
|
Chris@16
|
1614 template <typename MutableBufferSequence>
|
Chris@16
|
1615 inline std::size_t buffer_copy(const MutableBufferSequence& target,
|
Chris@16
|
1616 const const_buffers_1& source)
|
Chris@16
|
1617 {
|
Chris@16
|
1618 return buffer_copy(target, static_cast<const const_buffer&>(source));
|
Chris@16
|
1619 }
|
Chris@16
|
1620
|
Chris@16
|
1621 /// Copies bytes from a source buffer to a target buffer sequence.
|
Chris@16
|
1622 /**
|
Chris@16
|
1623 * @param target A modifiable buffer sequence representing the memory regions to
|
Chris@16
|
1624 * which the bytes will be copied.
|
Chris@16
|
1625 *
|
Chris@16
|
1626 * @param source A modifiable buffer representing the memory region from which
|
Chris@16
|
1627 * the bytes will be copied. The contents of the source buffer will not be
|
Chris@16
|
1628 * modified.
|
Chris@16
|
1629 *
|
Chris@16
|
1630 * @returns The number of bytes copied.
|
Chris@16
|
1631 *
|
Chris@16
|
1632 * @note The number of bytes copied is the lesser of:
|
Chris@16
|
1633 *
|
Chris@16
|
1634 * @li @c buffer_size(target)
|
Chris@16
|
1635 *
|
Chris@16
|
1636 * @li @c buffer_size(source)
|
Chris@101
|
1637 *
|
Chris@101
|
1638 * This function is implemented in terms of @c memcpy, and consequently it
|
Chris@101
|
1639 * cannot be used to copy between overlapping memory regions.
|
Chris@16
|
1640 */
|
Chris@16
|
1641 template <typename MutableBufferSequence>
|
Chris@16
|
1642 inline std::size_t buffer_copy(const MutableBufferSequence& target,
|
Chris@16
|
1643 const mutable_buffer& source)
|
Chris@16
|
1644 {
|
Chris@16
|
1645 return buffer_copy(target, const_buffer(source));
|
Chris@16
|
1646 }
|
Chris@16
|
1647
|
Chris@16
|
1648 /// Copies bytes from a source buffer to a target buffer sequence.
|
Chris@16
|
1649 /**
|
Chris@16
|
1650 * @param target A modifiable buffer sequence representing the memory regions to
|
Chris@16
|
1651 * which the bytes will be copied.
|
Chris@16
|
1652 *
|
Chris@16
|
1653 * @param source A modifiable buffer representing the memory region from which
|
Chris@16
|
1654 * the bytes will be copied. The contents of the source buffer will not be
|
Chris@16
|
1655 * modified.
|
Chris@16
|
1656 *
|
Chris@16
|
1657 * @returns The number of bytes copied.
|
Chris@16
|
1658 *
|
Chris@16
|
1659 * @note The number of bytes copied is the lesser of:
|
Chris@16
|
1660 *
|
Chris@16
|
1661 * @li @c buffer_size(target)
|
Chris@16
|
1662 *
|
Chris@16
|
1663 * @li @c buffer_size(source)
|
Chris@101
|
1664 *
|
Chris@101
|
1665 * This function is implemented in terms of @c memcpy, and consequently it
|
Chris@101
|
1666 * cannot be used to copy between overlapping memory regions.
|
Chris@16
|
1667 */
|
Chris@16
|
1668 template <typename MutableBufferSequence>
|
Chris@16
|
1669 inline std::size_t buffer_copy(const MutableBufferSequence& target,
|
Chris@16
|
1670 const mutable_buffers_1& source)
|
Chris@16
|
1671 {
|
Chris@16
|
1672 return buffer_copy(target, const_buffer(source));
|
Chris@16
|
1673 }
|
Chris@16
|
1674
|
Chris@16
|
1675 /// Copies bytes from a source buffer sequence to a target buffer sequence.
|
Chris@16
|
1676 /**
|
Chris@16
|
1677 * @param target A modifiable buffer sequence representing the memory regions to
|
Chris@16
|
1678 * which the bytes will be copied.
|
Chris@16
|
1679 *
|
Chris@16
|
1680 * @param source A non-modifiable buffer sequence representing the memory
|
Chris@16
|
1681 * regions from which the bytes will be copied.
|
Chris@16
|
1682 *
|
Chris@16
|
1683 * @returns The number of bytes copied.
|
Chris@16
|
1684 *
|
Chris@16
|
1685 * @note The number of bytes copied is the lesser of:
|
Chris@16
|
1686 *
|
Chris@16
|
1687 * @li @c buffer_size(target)
|
Chris@16
|
1688 *
|
Chris@16
|
1689 * @li @c buffer_size(source)
|
Chris@101
|
1690 *
|
Chris@101
|
1691 * This function is implemented in terms of @c memcpy, and consequently it
|
Chris@101
|
1692 * cannot be used to copy between overlapping memory regions.
|
Chris@16
|
1693 */
|
Chris@16
|
1694 template <typename MutableBufferSequence, typename ConstBufferSequence>
|
Chris@16
|
1695 std::size_t buffer_copy(const MutableBufferSequence& target,
|
Chris@16
|
1696 const ConstBufferSequence& source)
|
Chris@16
|
1697 {
|
Chris@16
|
1698 std::size_t total_bytes_copied = 0;
|
Chris@16
|
1699
|
Chris@16
|
1700 typename MutableBufferSequence::const_iterator target_iter = target.begin();
|
Chris@16
|
1701 typename MutableBufferSequence::const_iterator target_end = target.end();
|
Chris@16
|
1702 std::size_t target_buffer_offset = 0;
|
Chris@16
|
1703
|
Chris@16
|
1704 typename ConstBufferSequence::const_iterator source_iter = source.begin();
|
Chris@16
|
1705 typename ConstBufferSequence::const_iterator source_end = source.end();
|
Chris@16
|
1706 std::size_t source_buffer_offset = 0;
|
Chris@16
|
1707
|
Chris@16
|
1708 while (target_iter != target_end && source_iter != source_end)
|
Chris@16
|
1709 {
|
Chris@16
|
1710 mutable_buffer target_buffer =
|
Chris@16
|
1711 mutable_buffer(*target_iter) + target_buffer_offset;
|
Chris@16
|
1712
|
Chris@16
|
1713 const_buffer source_buffer =
|
Chris@16
|
1714 const_buffer(*source_iter) + source_buffer_offset;
|
Chris@16
|
1715
|
Chris@16
|
1716 std::size_t bytes_copied = buffer_copy(target_buffer, source_buffer);
|
Chris@16
|
1717 total_bytes_copied += bytes_copied;
|
Chris@16
|
1718
|
Chris@16
|
1719 if (bytes_copied == buffer_size(target_buffer))
|
Chris@16
|
1720 {
|
Chris@16
|
1721 ++target_iter;
|
Chris@16
|
1722 target_buffer_offset = 0;
|
Chris@16
|
1723 }
|
Chris@16
|
1724 else
|
Chris@16
|
1725 target_buffer_offset += bytes_copied;
|
Chris@16
|
1726
|
Chris@16
|
1727 if (bytes_copied == buffer_size(source_buffer))
|
Chris@16
|
1728 {
|
Chris@16
|
1729 ++source_iter;
|
Chris@16
|
1730 source_buffer_offset = 0;
|
Chris@16
|
1731 }
|
Chris@16
|
1732 else
|
Chris@16
|
1733 source_buffer_offset += bytes_copied;
|
Chris@16
|
1734 }
|
Chris@16
|
1735
|
Chris@16
|
1736 return total_bytes_copied;
|
Chris@16
|
1737 }
|
Chris@16
|
1738
|
Chris@16
|
1739 /// Copies a limited number of bytes from a source buffer to a target buffer.
|
Chris@16
|
1740 /**
|
Chris@16
|
1741 * @param target A modifiable buffer representing the memory region to which
|
Chris@16
|
1742 * the bytes will be copied.
|
Chris@16
|
1743 *
|
Chris@16
|
1744 * @param source A non-modifiable buffer representing the memory region from
|
Chris@16
|
1745 * which the bytes will be copied.
|
Chris@16
|
1746 *
|
Chris@16
|
1747 * @param max_bytes_to_copy The maximum number of bytes to be copied.
|
Chris@16
|
1748 *
|
Chris@16
|
1749 * @returns The number of bytes copied.
|
Chris@16
|
1750 *
|
Chris@16
|
1751 * @note The number of bytes copied is the lesser of:
|
Chris@16
|
1752 *
|
Chris@16
|
1753 * @li @c buffer_size(target)
|
Chris@16
|
1754 *
|
Chris@16
|
1755 * @li @c buffer_size(source)
|
Chris@16
|
1756 *
|
Chris@16
|
1757 * @li @c max_bytes_to_copy
|
Chris@101
|
1758 *
|
Chris@101
|
1759 * This function is implemented in terms of @c memcpy, and consequently it
|
Chris@101
|
1760 * cannot be used to copy between overlapping memory regions.
|
Chris@16
|
1761 */
|
Chris@16
|
1762 inline std::size_t buffer_copy(const mutable_buffer& target,
|
Chris@16
|
1763 const const_buffer& source, std::size_t max_bytes_to_copy)
|
Chris@16
|
1764 {
|
Chris@16
|
1765 return buffer_copy(buffer(target, max_bytes_to_copy), source);
|
Chris@16
|
1766 }
|
Chris@16
|
1767
|
Chris@16
|
1768 /// Copies a limited number of bytes from a source buffer to a target buffer.
|
Chris@16
|
1769 /**
|
Chris@16
|
1770 * @param target A modifiable buffer representing the memory region to which
|
Chris@16
|
1771 * the bytes will be copied.
|
Chris@16
|
1772 *
|
Chris@16
|
1773 * @param source A non-modifiable buffer representing the memory region from
|
Chris@16
|
1774 * which the bytes will be copied.
|
Chris@16
|
1775 *
|
Chris@16
|
1776 * @param max_bytes_to_copy The maximum number of bytes to be copied.
|
Chris@16
|
1777 *
|
Chris@16
|
1778 * @returns The number of bytes copied.
|
Chris@16
|
1779 *
|
Chris@16
|
1780 * @note The number of bytes copied is the lesser of:
|
Chris@16
|
1781 *
|
Chris@16
|
1782 * @li @c buffer_size(target)
|
Chris@16
|
1783 *
|
Chris@16
|
1784 * @li @c buffer_size(source)
|
Chris@16
|
1785 *
|
Chris@16
|
1786 * @li @c max_bytes_to_copy
|
Chris@101
|
1787 *
|
Chris@101
|
1788 * This function is implemented in terms of @c memcpy, and consequently it
|
Chris@101
|
1789 * cannot be used to copy between overlapping memory regions.
|
Chris@16
|
1790 */
|
Chris@16
|
1791 inline std::size_t buffer_copy(const mutable_buffer& target,
|
Chris@16
|
1792 const const_buffers_1& source, std::size_t max_bytes_to_copy)
|
Chris@16
|
1793 {
|
Chris@16
|
1794 return buffer_copy(buffer(target, max_bytes_to_copy), source);
|
Chris@16
|
1795 }
|
Chris@16
|
1796
|
Chris@16
|
1797 /// Copies a limited number of bytes from a source buffer to a target buffer.
|
Chris@16
|
1798 /**
|
Chris@16
|
1799 * @param target A modifiable buffer representing the memory region to which
|
Chris@16
|
1800 * the bytes will be copied.
|
Chris@16
|
1801 *
|
Chris@16
|
1802 * @param source A modifiable buffer representing the memory region from which
|
Chris@16
|
1803 * the bytes will be copied. The contents of the source buffer will not be
|
Chris@16
|
1804 * modified.
|
Chris@16
|
1805 *
|
Chris@16
|
1806 * @param max_bytes_to_copy The maximum number of bytes to be copied.
|
Chris@16
|
1807 *
|
Chris@16
|
1808 * @returns The number of bytes copied.
|
Chris@16
|
1809 *
|
Chris@16
|
1810 * @note The number of bytes copied is the lesser of:
|
Chris@16
|
1811 *
|
Chris@16
|
1812 * @li @c buffer_size(target)
|
Chris@16
|
1813 *
|
Chris@16
|
1814 * @li @c buffer_size(source)
|
Chris@16
|
1815 *
|
Chris@16
|
1816 * @li @c max_bytes_to_copy
|
Chris@101
|
1817 *
|
Chris@101
|
1818 * This function is implemented in terms of @c memcpy, and consequently it
|
Chris@101
|
1819 * cannot be used to copy between overlapping memory regions.
|
Chris@16
|
1820 */
|
Chris@16
|
1821 inline std::size_t buffer_copy(const mutable_buffer& target,
|
Chris@16
|
1822 const mutable_buffer& source, std::size_t max_bytes_to_copy)
|
Chris@16
|
1823 {
|
Chris@16
|
1824 return buffer_copy(buffer(target, max_bytes_to_copy), source);
|
Chris@16
|
1825 }
|
Chris@16
|
1826
|
Chris@16
|
1827 /// Copies a limited number of bytes from a source buffer to a target buffer.
|
Chris@16
|
1828 /**
|
Chris@16
|
1829 * @param target A modifiable buffer representing the memory region to which
|
Chris@16
|
1830 * the bytes will be copied.
|
Chris@16
|
1831 *
|
Chris@16
|
1832 * @param source A modifiable buffer representing the memory region from which
|
Chris@16
|
1833 * the bytes will be copied. The contents of the source buffer will not be
|
Chris@16
|
1834 * modified.
|
Chris@16
|
1835 *
|
Chris@16
|
1836 * @param max_bytes_to_copy The maximum number of bytes to be copied.
|
Chris@16
|
1837 *
|
Chris@16
|
1838 * @returns The number of bytes copied.
|
Chris@16
|
1839 *
|
Chris@16
|
1840 * @note The number of bytes copied is the lesser of:
|
Chris@16
|
1841 *
|
Chris@16
|
1842 * @li @c buffer_size(target)
|
Chris@16
|
1843 *
|
Chris@16
|
1844 * @li @c buffer_size(source)
|
Chris@16
|
1845 *
|
Chris@16
|
1846 * @li @c max_bytes_to_copy
|
Chris@101
|
1847 *
|
Chris@101
|
1848 * This function is implemented in terms of @c memcpy, and consequently it
|
Chris@101
|
1849 * cannot be used to copy between overlapping memory regions.
|
Chris@16
|
1850 */
|
Chris@16
|
1851 inline std::size_t buffer_copy(const mutable_buffer& target,
|
Chris@16
|
1852 const mutable_buffers_1& source, std::size_t max_bytes_to_copy)
|
Chris@16
|
1853 {
|
Chris@16
|
1854 return buffer_copy(buffer(target, max_bytes_to_copy), source);
|
Chris@16
|
1855 }
|
Chris@16
|
1856
|
Chris@16
|
1857 /// Copies a limited number of bytes from a source buffer sequence to a target
|
Chris@16
|
1858 /// buffer.
|
Chris@16
|
1859 /**
|
Chris@16
|
1860 * @param target A modifiable buffer representing the memory region to which
|
Chris@16
|
1861 * the bytes will be copied.
|
Chris@16
|
1862 *
|
Chris@16
|
1863 * @param source A non-modifiable buffer sequence representing the memory
|
Chris@16
|
1864 * regions from which the bytes will be copied.
|
Chris@16
|
1865 *
|
Chris@16
|
1866 * @param max_bytes_to_copy The maximum number of bytes to be copied.
|
Chris@16
|
1867 *
|
Chris@16
|
1868 * @returns The number of bytes copied.
|
Chris@16
|
1869 *
|
Chris@16
|
1870 * @note The number of bytes copied is the lesser of:
|
Chris@16
|
1871 *
|
Chris@16
|
1872 * @li @c buffer_size(target)
|
Chris@16
|
1873 *
|
Chris@16
|
1874 * @li @c buffer_size(source)
|
Chris@16
|
1875 *
|
Chris@16
|
1876 * @li @c max_bytes_to_copy
|
Chris@101
|
1877 *
|
Chris@101
|
1878 * This function is implemented in terms of @c memcpy, and consequently it
|
Chris@101
|
1879 * cannot be used to copy between overlapping memory regions.
|
Chris@16
|
1880 */
|
Chris@16
|
1881 template <typename ConstBufferSequence>
|
Chris@16
|
1882 inline std::size_t buffer_copy(const mutable_buffer& target,
|
Chris@16
|
1883 const ConstBufferSequence& source, std::size_t max_bytes_to_copy)
|
Chris@16
|
1884 {
|
Chris@16
|
1885 return buffer_copy(buffer(target, max_bytes_to_copy), source);
|
Chris@16
|
1886 }
|
Chris@16
|
1887
|
Chris@16
|
1888 /// Copies a limited number of bytes from a source buffer to a target buffer.
|
Chris@16
|
1889 /**
|
Chris@16
|
1890 * @param target A modifiable buffer representing the memory region to which
|
Chris@16
|
1891 * the bytes will be copied.
|
Chris@16
|
1892 *
|
Chris@16
|
1893 * @param source A non-modifiable buffer representing the memory region from
|
Chris@16
|
1894 * which the bytes will be copied.
|
Chris@16
|
1895 *
|
Chris@16
|
1896 * @param max_bytes_to_copy The maximum number of bytes to be copied.
|
Chris@16
|
1897 *
|
Chris@16
|
1898 * @returns The number of bytes copied.
|
Chris@16
|
1899 *
|
Chris@16
|
1900 * @note The number of bytes copied is the lesser of:
|
Chris@16
|
1901 *
|
Chris@16
|
1902 * @li @c buffer_size(target)
|
Chris@16
|
1903 *
|
Chris@16
|
1904 * @li @c buffer_size(source)
|
Chris@16
|
1905 *
|
Chris@16
|
1906 * @li @c max_bytes_to_copy
|
Chris@101
|
1907 *
|
Chris@101
|
1908 * This function is implemented in terms of @c memcpy, and consequently it
|
Chris@101
|
1909 * cannot be used to copy between overlapping memory regions.
|
Chris@16
|
1910 */
|
Chris@16
|
1911 inline std::size_t buffer_copy(const mutable_buffers_1& target,
|
Chris@16
|
1912 const const_buffer& source, std::size_t max_bytes_to_copy)
|
Chris@16
|
1913 {
|
Chris@16
|
1914 return buffer_copy(buffer(target, max_bytes_to_copy), source);
|
Chris@16
|
1915 }
|
Chris@16
|
1916
|
Chris@16
|
1917 /// Copies a limited number of bytes from a source buffer to a target buffer.
|
Chris@16
|
1918 /**
|
Chris@16
|
1919 * @param target A modifiable buffer representing the memory region to which
|
Chris@16
|
1920 * the bytes will be copied.
|
Chris@16
|
1921 *
|
Chris@16
|
1922 * @param source A non-modifiable buffer representing the memory region from
|
Chris@16
|
1923 * which the bytes will be copied.
|
Chris@16
|
1924 *
|
Chris@16
|
1925 * @param max_bytes_to_copy The maximum number of bytes to be copied.
|
Chris@16
|
1926 *
|
Chris@16
|
1927 * @returns The number of bytes copied.
|
Chris@16
|
1928 *
|
Chris@16
|
1929 * @note The number of bytes copied is the lesser of:
|
Chris@16
|
1930 *
|
Chris@16
|
1931 * @li @c buffer_size(target)
|
Chris@16
|
1932 *
|
Chris@16
|
1933 * @li @c buffer_size(source)
|
Chris@16
|
1934 *
|
Chris@16
|
1935 * @li @c max_bytes_to_copy
|
Chris@101
|
1936 *
|
Chris@101
|
1937 * This function is implemented in terms of @c memcpy, and consequently it
|
Chris@101
|
1938 * cannot be used to copy between overlapping memory regions.
|
Chris@16
|
1939 */
|
Chris@16
|
1940 inline std::size_t buffer_copy(const mutable_buffers_1& target,
|
Chris@16
|
1941 const const_buffers_1& source, std::size_t max_bytes_to_copy)
|
Chris@16
|
1942 {
|
Chris@16
|
1943 return buffer_copy(buffer(target, max_bytes_to_copy), source);
|
Chris@16
|
1944 }
|
Chris@16
|
1945
|
Chris@16
|
1946 /// Copies a limited number of bytes from a source buffer to a target buffer.
|
Chris@16
|
1947 /**
|
Chris@16
|
1948 * @param target A modifiable buffer representing the memory region to which
|
Chris@16
|
1949 * the bytes will be copied.
|
Chris@16
|
1950 *
|
Chris@16
|
1951 * @param source A modifiable buffer representing the memory region from which
|
Chris@16
|
1952 * the bytes will be copied. The contents of the source buffer will not be
|
Chris@16
|
1953 * modified.
|
Chris@16
|
1954 *
|
Chris@16
|
1955 * @param max_bytes_to_copy The maximum number of bytes to be copied.
|
Chris@16
|
1956 *
|
Chris@16
|
1957 * @returns The number of bytes copied.
|
Chris@16
|
1958 *
|
Chris@16
|
1959 * @note The number of bytes copied is the lesser of:
|
Chris@16
|
1960 *
|
Chris@16
|
1961 * @li @c buffer_size(target)
|
Chris@16
|
1962 *
|
Chris@16
|
1963 * @li @c buffer_size(source)
|
Chris@16
|
1964 *
|
Chris@16
|
1965 * @li @c max_bytes_to_copy
|
Chris@101
|
1966 *
|
Chris@101
|
1967 * This function is implemented in terms of @c memcpy, and consequently it
|
Chris@101
|
1968 * cannot be used to copy between overlapping memory regions.
|
Chris@16
|
1969 */
|
Chris@16
|
1970 inline std::size_t buffer_copy(const mutable_buffers_1& target,
|
Chris@16
|
1971 const mutable_buffer& source, std::size_t max_bytes_to_copy)
|
Chris@16
|
1972 {
|
Chris@16
|
1973 return buffer_copy(buffer(target, max_bytes_to_copy), source);
|
Chris@16
|
1974 }
|
Chris@16
|
1975
|
Chris@16
|
1976 /// Copies a limited number of bytes from a source buffer to a target buffer.
|
Chris@16
|
1977 /**
|
Chris@16
|
1978 * @param target A modifiable buffer representing the memory region to which
|
Chris@16
|
1979 * the bytes will be copied.
|
Chris@16
|
1980 *
|
Chris@16
|
1981 * @param source A modifiable buffer representing the memory region from which
|
Chris@16
|
1982 * the bytes will be copied. The contents of the source buffer will not be
|
Chris@16
|
1983 * modified.
|
Chris@16
|
1984 *
|
Chris@16
|
1985 * @param max_bytes_to_copy The maximum number of bytes to be copied.
|
Chris@16
|
1986 *
|
Chris@16
|
1987 * @returns The number of bytes copied.
|
Chris@16
|
1988 *
|
Chris@16
|
1989 * @note The number of bytes copied is the lesser of:
|
Chris@16
|
1990 *
|
Chris@16
|
1991 * @li @c buffer_size(target)
|
Chris@16
|
1992 *
|
Chris@16
|
1993 * @li @c buffer_size(source)
|
Chris@16
|
1994 *
|
Chris@16
|
1995 * @li @c max_bytes_to_copy
|
Chris@101
|
1996 *
|
Chris@101
|
1997 * This function is implemented in terms of @c memcpy, and consequently it
|
Chris@101
|
1998 * cannot be used to copy between overlapping memory regions.
|
Chris@16
|
1999 */
|
Chris@16
|
2000 inline std::size_t buffer_copy(const mutable_buffers_1& target,
|
Chris@16
|
2001 const mutable_buffers_1& source, std::size_t max_bytes_to_copy)
|
Chris@16
|
2002 {
|
Chris@16
|
2003 return buffer_copy(buffer(target, max_bytes_to_copy), source);
|
Chris@16
|
2004 }
|
Chris@16
|
2005
|
Chris@16
|
2006 /// Copies a limited number of bytes from a source buffer sequence to a target
|
Chris@16
|
2007 /// buffer.
|
Chris@16
|
2008 /**
|
Chris@16
|
2009 * @param target A modifiable buffer representing the memory region to which
|
Chris@16
|
2010 * the bytes will be copied.
|
Chris@16
|
2011 *
|
Chris@16
|
2012 * @param source A non-modifiable buffer sequence representing the memory
|
Chris@16
|
2013 * regions from which the bytes will be copied.
|
Chris@16
|
2014 *
|
Chris@16
|
2015 * @param max_bytes_to_copy The maximum number of bytes to be copied.
|
Chris@16
|
2016 *
|
Chris@16
|
2017 * @returns The number of bytes copied.
|
Chris@16
|
2018 *
|
Chris@16
|
2019 * @note The number of bytes copied is the lesser of:
|
Chris@16
|
2020 *
|
Chris@16
|
2021 * @li @c buffer_size(target)
|
Chris@16
|
2022 *
|
Chris@16
|
2023 * @li @c buffer_size(source)
|
Chris@16
|
2024 *
|
Chris@16
|
2025 * @li @c max_bytes_to_copy
|
Chris@101
|
2026 *
|
Chris@101
|
2027 * This function is implemented in terms of @c memcpy, and consequently it
|
Chris@101
|
2028 * cannot be used to copy between overlapping memory regions.
|
Chris@16
|
2029 */
|
Chris@16
|
2030 template <typename ConstBufferSequence>
|
Chris@16
|
2031 inline std::size_t buffer_copy(const mutable_buffers_1& target,
|
Chris@16
|
2032 const ConstBufferSequence& source, std::size_t max_bytes_to_copy)
|
Chris@16
|
2033 {
|
Chris@16
|
2034 return buffer_copy(buffer(target, max_bytes_to_copy), source);
|
Chris@16
|
2035 }
|
Chris@16
|
2036
|
Chris@16
|
2037 /// Copies a limited number of bytes from a source buffer to a target buffer
|
Chris@16
|
2038 /// sequence.
|
Chris@16
|
2039 /**
|
Chris@16
|
2040 * @param target A modifiable buffer sequence representing the memory regions to
|
Chris@16
|
2041 * which the bytes will be copied.
|
Chris@16
|
2042 *
|
Chris@16
|
2043 * @param source A non-modifiable buffer representing the memory region from
|
Chris@16
|
2044 * which the bytes will be copied.
|
Chris@16
|
2045 *
|
Chris@16
|
2046 * @param max_bytes_to_copy The maximum number of bytes to be copied.
|
Chris@16
|
2047 *
|
Chris@16
|
2048 * @returns The number of bytes copied.
|
Chris@16
|
2049 *
|
Chris@16
|
2050 * @note The number of bytes copied is the lesser of:
|
Chris@16
|
2051 *
|
Chris@16
|
2052 * @li @c buffer_size(target)
|
Chris@16
|
2053 *
|
Chris@16
|
2054 * @li @c buffer_size(source)
|
Chris@16
|
2055 *
|
Chris@16
|
2056 * @li @c max_bytes_to_copy
|
Chris@101
|
2057 *
|
Chris@101
|
2058 * This function is implemented in terms of @c memcpy, and consequently it
|
Chris@101
|
2059 * cannot be used to copy between overlapping memory regions.
|
Chris@16
|
2060 */
|
Chris@16
|
2061 template <typename MutableBufferSequence>
|
Chris@16
|
2062 inline std::size_t buffer_copy(const MutableBufferSequence& target,
|
Chris@16
|
2063 const const_buffer& source, std::size_t max_bytes_to_copy)
|
Chris@16
|
2064 {
|
Chris@16
|
2065 return buffer_copy(target, buffer(source, max_bytes_to_copy));
|
Chris@16
|
2066 }
|
Chris@16
|
2067
|
Chris@16
|
2068 /// Copies a limited number of bytes from a source buffer to a target buffer
|
Chris@16
|
2069 /// sequence.
|
Chris@16
|
2070 /**
|
Chris@16
|
2071 * @param target A modifiable buffer sequence representing the memory regions to
|
Chris@16
|
2072 * which the bytes will be copied.
|
Chris@16
|
2073 *
|
Chris@16
|
2074 * @param source A non-modifiable buffer representing the memory region from
|
Chris@16
|
2075 * which the bytes will be copied.
|
Chris@16
|
2076 *
|
Chris@16
|
2077 * @param max_bytes_to_copy The maximum number of bytes to be copied.
|
Chris@16
|
2078 *
|
Chris@16
|
2079 * @returns The number of bytes copied.
|
Chris@16
|
2080 *
|
Chris@16
|
2081 * @note The number of bytes copied is the lesser of:
|
Chris@16
|
2082 *
|
Chris@16
|
2083 * @li @c buffer_size(target)
|
Chris@16
|
2084 *
|
Chris@16
|
2085 * @li @c buffer_size(source)
|
Chris@16
|
2086 *
|
Chris@16
|
2087 * @li @c max_bytes_to_copy
|
Chris@101
|
2088 *
|
Chris@101
|
2089 * This function is implemented in terms of @c memcpy, and consequently it
|
Chris@101
|
2090 * cannot be used to copy between overlapping memory regions.
|
Chris@16
|
2091 */
|
Chris@16
|
2092 template <typename MutableBufferSequence>
|
Chris@16
|
2093 inline std::size_t buffer_copy(const MutableBufferSequence& target,
|
Chris@16
|
2094 const const_buffers_1& source, std::size_t max_bytes_to_copy)
|
Chris@16
|
2095 {
|
Chris@16
|
2096 return buffer_copy(target, buffer(source, max_bytes_to_copy));
|
Chris@16
|
2097 }
|
Chris@16
|
2098
|
Chris@16
|
2099 /// Copies a limited number of bytes from a source buffer to a target buffer
|
Chris@16
|
2100 /// sequence.
|
Chris@16
|
2101 /**
|
Chris@16
|
2102 * @param target A modifiable buffer sequence representing the memory regions to
|
Chris@16
|
2103 * which the bytes will be copied.
|
Chris@16
|
2104 *
|
Chris@16
|
2105 * @param source A modifiable buffer representing the memory region from which
|
Chris@16
|
2106 * the bytes will be copied. The contents of the source buffer will not be
|
Chris@16
|
2107 * modified.
|
Chris@16
|
2108 *
|
Chris@16
|
2109 * @param max_bytes_to_copy The maximum number of bytes to be copied.
|
Chris@16
|
2110 *
|
Chris@16
|
2111 * @returns The number of bytes copied.
|
Chris@16
|
2112 *
|
Chris@16
|
2113 * @note The number of bytes copied is the lesser of:
|
Chris@16
|
2114 *
|
Chris@16
|
2115 * @li @c buffer_size(target)
|
Chris@16
|
2116 *
|
Chris@16
|
2117 * @li @c buffer_size(source)
|
Chris@16
|
2118 *
|
Chris@16
|
2119 * @li @c max_bytes_to_copy
|
Chris@101
|
2120 *
|
Chris@101
|
2121 * This function is implemented in terms of @c memcpy, and consequently it
|
Chris@101
|
2122 * cannot be used to copy between overlapping memory regions.
|
Chris@16
|
2123 */
|
Chris@16
|
2124 template <typename MutableBufferSequence>
|
Chris@16
|
2125 inline std::size_t buffer_copy(const MutableBufferSequence& target,
|
Chris@16
|
2126 const mutable_buffer& source, std::size_t max_bytes_to_copy)
|
Chris@16
|
2127 {
|
Chris@16
|
2128 return buffer_copy(target, buffer(source, max_bytes_to_copy));
|
Chris@16
|
2129 }
|
Chris@16
|
2130
|
Chris@16
|
2131 /// Copies a limited number of bytes from a source buffer to a target buffer
|
Chris@16
|
2132 /// sequence.
|
Chris@16
|
2133 /**
|
Chris@16
|
2134 * @param target A modifiable buffer sequence representing the memory regions to
|
Chris@16
|
2135 * which the bytes will be copied.
|
Chris@16
|
2136 *
|
Chris@16
|
2137 * @param source A modifiable buffer representing the memory region from which
|
Chris@16
|
2138 * the bytes will be copied. The contents of the source buffer will not be
|
Chris@16
|
2139 * modified.
|
Chris@16
|
2140 *
|
Chris@16
|
2141 * @param max_bytes_to_copy The maximum number of bytes to be copied.
|
Chris@16
|
2142 *
|
Chris@16
|
2143 * @returns The number of bytes copied.
|
Chris@16
|
2144 *
|
Chris@16
|
2145 * @note The number of bytes copied is the lesser of:
|
Chris@16
|
2146 *
|
Chris@16
|
2147 * @li @c buffer_size(target)
|
Chris@16
|
2148 *
|
Chris@16
|
2149 * @li @c buffer_size(source)
|
Chris@16
|
2150 *
|
Chris@16
|
2151 * @li @c max_bytes_to_copy
|
Chris@101
|
2152 *
|
Chris@101
|
2153 * This function is implemented in terms of @c memcpy, and consequently it
|
Chris@101
|
2154 * cannot be used to copy between overlapping memory regions.
|
Chris@16
|
2155 */
|
Chris@16
|
2156 template <typename MutableBufferSequence>
|
Chris@16
|
2157 inline std::size_t buffer_copy(const MutableBufferSequence& target,
|
Chris@16
|
2158 const mutable_buffers_1& source, std::size_t max_bytes_to_copy)
|
Chris@16
|
2159 {
|
Chris@16
|
2160 return buffer_copy(target, buffer(source, max_bytes_to_copy));
|
Chris@16
|
2161 }
|
Chris@16
|
2162
|
Chris@16
|
2163 /// Copies a limited number of bytes from a source buffer sequence to a target
|
Chris@16
|
2164 /// buffer sequence.
|
Chris@16
|
2165 /**
|
Chris@16
|
2166 * @param target A modifiable buffer sequence representing the memory regions to
|
Chris@16
|
2167 * which the bytes will be copied.
|
Chris@16
|
2168 *
|
Chris@16
|
2169 * @param source A non-modifiable buffer sequence representing the memory
|
Chris@16
|
2170 * regions from which the bytes will be copied.
|
Chris@16
|
2171 *
|
Chris@16
|
2172 * @param max_bytes_to_copy The maximum number of bytes to be copied.
|
Chris@16
|
2173 *
|
Chris@16
|
2174 * @returns The number of bytes copied.
|
Chris@16
|
2175 *
|
Chris@16
|
2176 * @note The number of bytes copied is the lesser of:
|
Chris@16
|
2177 *
|
Chris@16
|
2178 * @li @c buffer_size(target)
|
Chris@16
|
2179 *
|
Chris@16
|
2180 * @li @c buffer_size(source)
|
Chris@16
|
2181 *
|
Chris@16
|
2182 * @li @c max_bytes_to_copy
|
Chris@101
|
2183 *
|
Chris@101
|
2184 * This function is implemented in terms of @c memcpy, and consequently it
|
Chris@101
|
2185 * cannot be used to copy between overlapping memory regions.
|
Chris@16
|
2186 */
|
Chris@16
|
2187 template <typename MutableBufferSequence, typename ConstBufferSequence>
|
Chris@16
|
2188 std::size_t buffer_copy(const MutableBufferSequence& target,
|
Chris@16
|
2189 const ConstBufferSequence& source, std::size_t max_bytes_to_copy)
|
Chris@16
|
2190 {
|
Chris@16
|
2191 std::size_t total_bytes_copied = 0;
|
Chris@16
|
2192
|
Chris@16
|
2193 typename MutableBufferSequence::const_iterator target_iter = target.begin();
|
Chris@16
|
2194 typename MutableBufferSequence::const_iterator target_end = target.end();
|
Chris@16
|
2195 std::size_t target_buffer_offset = 0;
|
Chris@16
|
2196
|
Chris@16
|
2197 typename ConstBufferSequence::const_iterator source_iter = source.begin();
|
Chris@16
|
2198 typename ConstBufferSequence::const_iterator source_end = source.end();
|
Chris@16
|
2199 std::size_t source_buffer_offset = 0;
|
Chris@16
|
2200
|
Chris@16
|
2201 while (total_bytes_copied != max_bytes_to_copy
|
Chris@16
|
2202 && target_iter != target_end && source_iter != source_end)
|
Chris@16
|
2203 {
|
Chris@16
|
2204 mutable_buffer target_buffer =
|
Chris@16
|
2205 mutable_buffer(*target_iter) + target_buffer_offset;
|
Chris@16
|
2206
|
Chris@16
|
2207 const_buffer source_buffer =
|
Chris@16
|
2208 const_buffer(*source_iter) + source_buffer_offset;
|
Chris@16
|
2209
|
Chris@16
|
2210 std::size_t bytes_copied = buffer_copy(target_buffer,
|
Chris@16
|
2211 source_buffer, max_bytes_to_copy - total_bytes_copied);
|
Chris@16
|
2212 total_bytes_copied += bytes_copied;
|
Chris@16
|
2213
|
Chris@16
|
2214 if (bytes_copied == buffer_size(target_buffer))
|
Chris@16
|
2215 {
|
Chris@16
|
2216 ++target_iter;
|
Chris@16
|
2217 target_buffer_offset = 0;
|
Chris@16
|
2218 }
|
Chris@16
|
2219 else
|
Chris@16
|
2220 target_buffer_offset += bytes_copied;
|
Chris@16
|
2221
|
Chris@16
|
2222 if (bytes_copied == buffer_size(source_buffer))
|
Chris@16
|
2223 {
|
Chris@16
|
2224 ++source_iter;
|
Chris@16
|
2225 source_buffer_offset = 0;
|
Chris@16
|
2226 }
|
Chris@16
|
2227 else
|
Chris@16
|
2228 source_buffer_offset += bytes_copied;
|
Chris@16
|
2229 }
|
Chris@16
|
2230
|
Chris@16
|
2231 return total_bytes_copied;
|
Chris@16
|
2232 }
|
Chris@16
|
2233
|
Chris@16
|
2234 /*@}*/
|
Chris@16
|
2235
|
Chris@16
|
2236 } // namespace asio
|
Chris@16
|
2237 } // namespace boost
|
Chris@16
|
2238
|
Chris@16
|
2239 #include <boost/asio/detail/pop_options.hpp>
|
Chris@16
|
2240
|
Chris@16
|
2241 #endif // BOOST_ASIO_BUFFER_HPP
|