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