the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
at master 2142 lines 66 kB view raw
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