diff --git a/asio/include/asio/buffer.hpp b/asio/include/asio/buffer.hpp index 6810fca6..24b159d1 100644 --- a/asio/include/asio/buffer.hpp +++ b/asio/include/asio/buffer.hpp @@ -17,6 +17,7 @@ #include "asio/detail/config.hpp" #include +#include #include #include #include @@ -67,6 +68,19 @@ std::size_t buffer_size_helper(const const_buffer&); * The mutable_buffer class provides a safe representation of a buffer that can * be modified. It does not own the underlying data, and so is cheap to copy or * assign. + * + * @par Accessing Buffer Contents + * + * The contents of a buffer may be accessed using the @ref buffer_size + * and @ref buffer_cast functions: + * + * @code asio::mutable_buffer b1 = ...; + * std::size_t s1 = asio::buffer_size(b1); + * unsigned char* p1 = asio::buffer_cast(b1); + * @endcode + * + * The asio::buffer_cast function permits violations of type safety, so + * uses of it in application code should be carefully considered. */ class mutable_buffer { @@ -132,59 +146,6 @@ inline std::size_t buffer_size_helper(const mutable_buffer& b) } // namespace detail -/// Cast a non-modifiable buffer to a specified pointer to POD type. -/** - * @relates mutable_buffer - */ -template -inline PointerToPodType buffer_cast(const mutable_buffer& b) -{ - return static_cast(detail::buffer_cast_helper(b)); -} - -/// Get the number of bytes in a non-modifiable buffer. -/** - * @relates mutable_buffer - */ -inline std::size_t buffer_size(const mutable_buffer& b) -{ - return detail::buffer_size_helper(b); -} - -/// Create a new modifiable buffer that is offset from the start of another. -/** - * @relates mutable_buffer - */ -inline mutable_buffer operator+(const mutable_buffer& b, std::size_t start) -{ - if (start > buffer_size(b)) - return mutable_buffer(); - char* new_data = buffer_cast(b) + start; - std::size_t new_size = buffer_size(b) - start; - return mutable_buffer(new_data, new_size -#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) - , b.get_debug_check() -#endif // ASIO_ENABLE_BUFFER_DEBUGGING - ); -} - -/// Create a new modifiable buffer that is offset from the start of another. -/** - * @relates mutable_buffer - */ -inline mutable_buffer operator+(std::size_t start, const mutable_buffer& b) -{ - if (start > buffer_size(b)) - return mutable_buffer(); - char* new_data = buffer_cast(b) + start; - std::size_t new_size = buffer_size(b) - start; - return mutable_buffer(new_data, new_size -#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) - , b.get_debug_check() -#endif // ASIO_ENABLE_BUFFER_DEBUGGING - ); -} - /// Adapts a single modifiable buffer so that it meets the requirements of the /// MutableBufferSequence concept. class mutable_buffers_1 @@ -227,6 +188,19 @@ public: * The const_buffer class provides a safe representation of a buffer that cannot * be modified. It does not own the underlying data, and so is cheap to copy or * assign. + * + * @par Accessing Buffer Contents + * + * The contents of a buffer may be accessed using the @ref buffer_size + * and @ref buffer_cast functions: + * + * @code asio::const_buffer b1 = ...; + * std::size_t s1 = asio::buffer_size(b1); + * const unsigned char* p1 = asio::buffer_cast(b1); + * @endcode + * + * The asio::buffer_cast function permits violations of type safety, so + * uses of it in application code should be carefully considered. */ class const_buffer { @@ -302,59 +276,6 @@ inline std::size_t buffer_size_helper(const const_buffer& b) } // namespace detail -/// Cast a non-modifiable buffer to a specified pointer to POD type. -/** - * @relates const_buffer - */ -template -inline PointerToPodType buffer_cast(const const_buffer& b) -{ - return static_cast(detail::buffer_cast_helper(b)); -} - -/// Get the number of bytes in a non-modifiable buffer. -/** - * @relates const_buffer - */ -inline std::size_t buffer_size(const const_buffer& b) -{ - return detail::buffer_size_helper(b); -} - -/// Create a new non-modifiable buffer that is offset from the start of another. -/** - * @relates const_buffer - */ -inline const_buffer operator+(const const_buffer& b, std::size_t start) -{ - if (start > buffer_size(b)) - return const_buffer(); - const char* new_data = buffer_cast(b) + start; - std::size_t new_size = buffer_size(b) - start; - return const_buffer(new_data, new_size -#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) - , b.get_debug_check() -#endif // ASIO_ENABLE_BUFFER_DEBUGGING - ); -} - -/// Create a new non-modifiable buffer that is offset from the start of another. -/** - * @relates const_buffer - */ -inline const_buffer operator+(std::size_t start, const const_buffer& b) -{ - if (start > buffer_size(b)) - return const_buffer(); - const char* new_data = buffer_cast(b) + start; - std::size_t new_size = buffer_size(b) - start; - return const_buffer(new_data, new_size -#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) - , b.get_debug_check() -#endif // ASIO_ENABLE_BUFFER_DEBUGGING - ); -} - /// Adapts a single non-modifiable buffer so that it meets the requirements of /// the ConstBufferSequence concept. class const_buffers_1 @@ -419,6 +340,163 @@ private: mutable_buffer buf_; }; +/** @defgroup buffer_size asio::buffer_size + * + * @brief The asio::buffer_size function determines the total number of + * bytes in a buffer or buffer sequence. + */ +/*@{*/ + +/// Get the number of bytes in a modifiable buffer. +inline std::size_t buffer_size(const mutable_buffer& b) +{ + return detail::buffer_size_helper(b); +} + +/// Get the number of bytes in a modifiable buffer. +inline std::size_t buffer_size(const mutable_buffers_1& b) +{ + return detail::buffer_size_helper(b); +} + +/// Get the number of bytes in a non-modifiable buffer. +inline std::size_t buffer_size(const const_buffer& b) +{ + return detail::buffer_size_helper(b); +} + +/// Get the number of bytes in a non-modifiable buffer. +inline std::size_t buffer_size(const const_buffers_1& b) +{ + return detail::buffer_size_helper(b); +} + +/// Get the total number of bytes in a buffer sequence. +/** + * The @c BufferSequence template parameter may meet either of the @c + * ConstBufferSequence or @c MutableBufferSequence type requirements. + */ +template +inline std::size_t buffer_size(const BufferSequence& b) +{ + std::size_t total_buffer_size = 0; + + typename BufferSequence::const_iterator iter = b.begin(); + typename BufferSequence::const_iterator end = b.end(); + for (; iter != end; ++iter) + total_buffer_size += detail::buffer_size_helper(*iter); + + return total_buffer_size; +} + +/*@}*/ + +/** @defgroup buffer_cast asio::buffer_cast + * + * @brief The asio::buffer_cast function is used to obtain a pointer to + * the underlying memory region associated with a buffer. + * + * @par Examples: + * + * To access the memory of a non-modifiable buffer, use: + * @code asio::const_buffer b1 = ...; + * const unsigned char* p1 = asio::buffer_cast(b1); + * @endcode + * + * To access the memory of a modifiable buffer, use: + * @code asio::mutable_buffer b2 = ...; + * unsigned char* p2 = asio::buffer_cast(b2); + * @endcode + * + * The asio::buffer_cast function permits violations of type safety, so + * uses of it in application code should be carefully considered. + */ +/*@{*/ + +/// Cast a non-modifiable buffer to a specified pointer to POD type. +template +inline PointerToPodType buffer_cast(const mutable_buffer& b) +{ + return static_cast(detail::buffer_cast_helper(b)); +} + +/// Cast a non-modifiable buffer to a specified pointer to POD type. +template +inline PointerToPodType buffer_cast(const const_buffer& b) +{ + return static_cast(detail::buffer_cast_helper(b)); +} + +/*@}*/ + +/// Create a new modifiable buffer that is offset from the start of another. +/** + * @relates mutable_buffer + */ +inline mutable_buffer operator+(const mutable_buffer& b, std::size_t start) +{ + if (start > buffer_size(b)) + return mutable_buffer(); + char* new_data = buffer_cast(b) + start; + std::size_t new_size = buffer_size(b) - start; + return mutable_buffer(new_data, new_size +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , b.get_debug_check() +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + ); +} + +/// Create a new modifiable buffer that is offset from the start of another. +/** + * @relates mutable_buffer + */ +inline mutable_buffer operator+(std::size_t start, const mutable_buffer& b) +{ + if (start > buffer_size(b)) + return mutable_buffer(); + char* new_data = buffer_cast(b) + start; + std::size_t new_size = buffer_size(b) - start; + return mutable_buffer(new_data, new_size +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , b.get_debug_check() +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + ); +} + +/// Create a new non-modifiable buffer that is offset from the start of another. +/** + * @relates const_buffer + */ +inline const_buffer operator+(const const_buffer& b, std::size_t start) +{ + if (start > buffer_size(b)) + return const_buffer(); + const char* new_data = buffer_cast(b) + start; + std::size_t new_size = buffer_size(b) - start; + return const_buffer(new_data, new_size +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , b.get_debug_check() +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + ); +} + +/// Create a new non-modifiable buffer that is offset from the start of another. +/** + * @relates const_buffer + */ +inline const_buffer operator+(std::size_t start, const const_buffer& b) +{ + if (start > buffer_size(b)) + return const_buffer(); + const char* new_data = buffer_cast(b) + start; + std::size_t new_size = buffer_size(b) - start; + return const_buffer(new_data, new_size +#if defined(ASIO_ENABLE_BUFFER_DEBUGGING) + , b.get_debug_check() +#endif // ASIO_ENABLE_BUFFER_DEBUGGING + ); +} + #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) namespace detail { @@ -498,8 +576,8 @@ private: * * @par Accessing Buffer Contents * - * The contents of a buffer may be accessed using the asio::buffer_size - * and asio::buffer_cast functions: + * The contents of a buffer may be accessed using the @ref buffer_size and + * @ref buffer_cast functions: * * @code asio::mutable_buffer b1 = ...; * std::size_t s1 = asio::buffer_size(b1); @@ -525,8 +603,8 @@ private: * referring to the elements in the sequence (C++ Std, 23.2.4) * * For the asio::buffer overloads that accept an argument of type - * std::string, the buffer objects returned are invalidated according to the - * rules defined for invalidation of references, pointers and iterators + * std::basic_string, the buffer objects returned are invalidated according to + * the rules defined for invalidation of references, pointers and iterators * referring to elements of the sequence (C++ Std, 21.3). * * @par Buffer Arithmetic @@ -996,16 +1074,20 @@ inline const_buffers_1 buffer( /// Create a new non-modifiable buffer that represents the given string. /** - * @returns const_buffers_1(data.data(), data.size()). + * @returns const_buffers_1(data.data(), data.size() * sizeof(Elem)). * * @note The buffer is invalidated by any non-const operation called on the * given string object. */ -inline const_buffers_1 buffer(const std::string& data) +template +inline const_buffers_1 buffer( + const std::basic_string& data) { - return const_buffers_1(const_buffer(data.data(), data.size() + return const_buffers_1(const_buffer(data.data(), data.size() * sizeof(Elem) #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) - , detail::buffer_debug_check(data.begin()) + , detail::buffer_debug_check< + typename std::basic_string::const_iterator + >(data.begin()) #endif // ASIO_ENABLE_BUFFER_DEBUGGING )); } @@ -1015,26 +1097,924 @@ inline const_buffers_1 buffer(const std::string& data) * @returns A const_buffers_1 value equivalent to: * @code const_buffers_1( * data.data(), - * min(data.size(), max_size_in_bytes)); @endcode + * min(data.size() * sizeof(Elem), max_size_in_bytes)); @endcode * * @note The buffer is invalidated by any non-const operation called on the * given string object. */ -inline const_buffers_1 buffer(const std::string& data, +template +inline const_buffers_1 buffer( + const std::basic_string& data, std::size_t max_size_in_bytes) { return const_buffers_1( const_buffer(data.data(), - data.size() < max_size_in_bytes - ? data.size() : max_size_in_bytes + data.size() * sizeof(Elem) < max_size_in_bytes + ? data.size() * sizeof(Elem) : max_size_in_bytes #if defined(ASIO_ENABLE_BUFFER_DEBUGGING) - , detail::buffer_debug_check(data.begin()) + , detail::buffer_debug_check< + typename std::basic_string::const_iterator + >(data.begin()) #endif // ASIO_ENABLE_BUFFER_DEBUGGING )); } /*@}*/ +/** @defgroup buffer_copy asio::buffer_copy + * + * @brief The asio::buffer_copy function is used to copy bytes from a + * source buffer (or buffer sequence) to a target buffer (or buffer sequence). + * + * The @c buffer_copy function is available in two forms: + * + * @li A 2-argument form: @c buffer_copy(target, source) + * + * @li A 3-argument form: @c buffer_copy(target, source, max_bytes_to_copy) + + * Both forms return the number of bytes actually copied. The number of bytes + * copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + * + * @li @c If specified, @c max_bytes_to_copy. + * + * This prevents buffer overflow, regardless of the buffer sizes used in the + * copy operation. + */ +/*@{*/ + +/// Copies bytes from a source buffer to a target buffer. +/** + * @param target A modifiable buffer representing the memory region to which + * the bytes will be copied. + * + * @param source A non-modifiable buffer representing the memory region from + * which the bytes will be copied. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + */ +inline std::size_t buffer_copy(const mutable_buffer& target, + const const_buffer& source) +{ + using namespace std; // For memcpy. + std::size_t target_size = buffer_size(target); + std::size_t source_size = buffer_size(source); + std::size_t n = target_size < source_size ? target_size : source_size; + memcpy(buffer_cast(target), buffer_cast(source), n); + return n; +} + +/// Copies bytes from a source buffer to a target buffer. +/** + * @param target A modifiable buffer representing the memory region to which + * the bytes will be copied. + * + * @param source A non-modifiable buffer representing the memory region from + * which the bytes will be copied. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + */ +inline std::size_t buffer_copy(const mutable_buffer& target, + const const_buffers_1& source) +{ + return buffer_copy(target, static_cast(source)); +} + +/// Copies bytes from a source buffer to a target buffer. +/** + * @param target A modifiable buffer representing the memory region to which + * the bytes will be copied. + * + * @param source A modifiable buffer representing the memory region from which + * the bytes will be copied. The contents of the source buffer will not be + * modified. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + */ +inline std::size_t buffer_copy(const mutable_buffer& target, + const mutable_buffer& source) +{ + return buffer_copy(target, const_buffer(source)); +} + +/// Copies bytes from a source buffer to a target buffer. +/** + * @param target A modifiable buffer representing the memory region to which + * the bytes will be copied. + * + * @param source A modifiable buffer representing the memory region from which + * the bytes will be copied. The contents of the source buffer will not be + * modified. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + */ +inline std::size_t buffer_copy(const mutable_buffer& target, + const mutable_buffers_1& source) +{ + return buffer_copy(target, const_buffer(source)); +} + +/// Copies bytes from a source buffer sequence to a target buffer. +/** + * @param target A modifiable buffer representing the memory region to which + * the bytes will be copied. + * + * @param source A non-modifiable buffer sequence representing the memory + * regions from which the bytes will be copied. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + */ +template +std::size_t buffer_copy(const mutable_buffer& target, + const ConstBufferSequence& source) +{ + std::size_t total_bytes_copied = 0; + + typename ConstBufferSequence::const_iterator source_iter = source.begin(); + typename ConstBufferSequence::const_iterator source_end = source.end(); + + for (mutable_buffer target_buffer(target); + buffer_size(target_buffer) && source_iter != source_end; ++source_iter) + { + const_buffer source_buffer(*source_iter); + std::size_t bytes_copied = buffer_copy(target_buffer, source_buffer); + total_bytes_copied += bytes_copied; + target_buffer = target_buffer + bytes_copied; + } + + return total_bytes_copied; +} + +/// Copies bytes from a source buffer to a target buffer. +/** + * @param target A modifiable buffer representing the memory region to which + * the bytes will be copied. + * + * @param source A non-modifiable buffer representing the memory region from + * which the bytes will be copied. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + */ +inline std::size_t buffer_copy(const mutable_buffers_1& target, + const const_buffer& source) +{ + return buffer_copy(static_cast(target), source); +} + +/// Copies bytes from a source buffer to a target buffer. +/** + * @param target A modifiable buffer representing the memory region to which + * the bytes will be copied. + * + * @param source A non-modifiable buffer representing the memory region from + * which the bytes will be copied. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + */ +inline std::size_t buffer_copy(const mutable_buffers_1& target, + const const_buffers_1& source) +{ + return buffer_copy(static_cast(target), + static_cast(source)); +} + +/// Copies bytes from a source buffer to a target buffer. +/** + * @param target A modifiable buffer representing the memory region to which + * the bytes will be copied. + * + * @param source A modifiable buffer representing the memory region from which + * the bytes will be copied. The contents of the source buffer will not be + * modified. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + */ +inline std::size_t buffer_copy(const mutable_buffers_1& target, + const mutable_buffer& source) +{ + return buffer_copy(static_cast(target), + const_buffer(source)); +} + +/// Copies bytes from a source buffer to a target buffer. +/** + * @param target A modifiable buffer representing the memory region to which + * the bytes will be copied. + * + * @param source A modifiable buffer representing the memory region from which + * the bytes will be copied. The contents of the source buffer will not be + * modified. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + */ +inline std::size_t buffer_copy(const mutable_buffers_1& target, + const mutable_buffers_1& source) +{ + return buffer_copy(static_cast(target), + const_buffer(source)); +} + +/// Copies bytes from a source buffer sequence to a target buffer. +/** + * @param target A modifiable buffer representing the memory region to which + * the bytes will be copied. + * + * @param source A non-modifiable buffer sequence representing the memory + * regions from which the bytes will be copied. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + */ +template +inline std::size_t buffer_copy(const mutable_buffers_1& target, + const ConstBufferSequence& source) +{ + return buffer_copy(static_cast(target), source); +} + +/// Copies bytes from a source buffer to a target buffer sequence. +/** + * @param target A modifiable buffer sequence representing the memory regions to + * which the bytes will be copied. + * + * @param source A non-modifiable buffer representing the memory region from + * which the bytes will be copied. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + */ +template +std::size_t buffer_copy(const MutableBufferSequence& target, + const const_buffer& source) +{ + std::size_t total_bytes_copied = 0; + + typename MutableBufferSequence::const_iterator target_iter = target.begin(); + typename MutableBufferSequence::const_iterator target_end = target.end(); + + for (const_buffer source_buffer(source); + buffer_size(source_buffer) && target_iter != target_end; ++target_iter) + { + mutable_buffer target_buffer(*target_iter); + std::size_t bytes_copied = buffer_copy(target_buffer, source_buffer); + total_bytes_copied += bytes_copied; + source_buffer = source_buffer + bytes_copied; + } + + return total_bytes_copied; +} + +/// Copies bytes from a source buffer to a target buffer sequence. +/** + * @param target A modifiable buffer sequence representing the memory regions to + * which the bytes will be copied. + * + * @param source A non-modifiable buffer representing the memory region from + * which the bytes will be copied. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + */ +template +inline std::size_t buffer_copy(const MutableBufferSequence& target, + const const_buffers_1& source) +{ + return buffer_copy(target, static_cast(source)); +} + +/// Copies bytes from a source buffer to a target buffer sequence. +/** + * @param target A modifiable buffer sequence representing the memory regions to + * which the bytes will be copied. + * + * @param source A modifiable buffer representing the memory region from which + * the bytes will be copied. The contents of the source buffer will not be + * modified. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + */ +template +inline std::size_t buffer_copy(const MutableBufferSequence& target, + const mutable_buffer& source) +{ + return buffer_copy(target, const_buffer(source)); +} + +/// Copies bytes from a source buffer to a target buffer sequence. +/** + * @param target A modifiable buffer sequence representing the memory regions to + * which the bytes will be copied. + * + * @param source A modifiable buffer representing the memory region from which + * the bytes will be copied. The contents of the source buffer will not be + * modified. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + */ +template +inline std::size_t buffer_copy(const MutableBufferSequence& target, + const mutable_buffers_1& source) +{ + return buffer_copy(target, const_buffer(source)); +} + +/// Copies bytes from a source buffer sequence to a target buffer sequence. +/** + * @param target A modifiable buffer sequence representing the memory regions to + * which the bytes will be copied. + * + * @param source A non-modifiable buffer sequence representing the memory + * regions from which the bytes will be copied. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + */ +template +std::size_t buffer_copy(const MutableBufferSequence& target, + const ConstBufferSequence& source) +{ + std::size_t total_bytes_copied = 0; + + typename MutableBufferSequence::const_iterator target_iter = target.begin(); + typename MutableBufferSequence::const_iterator target_end = target.end(); + std::size_t target_buffer_offset = 0; + + typename ConstBufferSequence::const_iterator source_iter = source.begin(); + typename ConstBufferSequence::const_iterator source_end = source.end(); + std::size_t source_buffer_offset = 0; + + while (target_iter != target_end && source_iter != source_end) + { + mutable_buffer target_buffer = + mutable_buffer(*target_iter) + target_buffer_offset; + + const_buffer source_buffer = + const_buffer(*source_iter) + source_buffer_offset; + + std::size_t bytes_copied = buffer_copy(target_buffer, source_buffer); + total_bytes_copied += bytes_copied; + + if (bytes_copied == buffer_size(target_buffer)) + { + ++target_iter; + target_buffer_offset = 0; + } + else + target_buffer_offset += bytes_copied; + + if (bytes_copied == buffer_size(source_buffer)) + { + ++source_iter; + source_buffer_offset = 0; + } + else + source_buffer_offset += bytes_copied; + } + + return total_bytes_copied; +} + +/// Copies a limited number of bytes from a source buffer to a target buffer. +/** + * @param target A modifiable buffer representing the memory region to which + * the bytes will be copied. + * + * @param source A non-modifiable buffer representing the memory region from + * which the bytes will be copied. + * + * @param max_bytes_to_copy The maximum number of bytes to be copied. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + * + * @li @c max_bytes_to_copy + */ +inline std::size_t buffer_copy(const mutable_buffer& target, + const const_buffer& source, std::size_t max_bytes_to_copy) +{ + return buffer_copy(buffer(target, max_bytes_to_copy), source); +} + +/// Copies a limited number of bytes from a source buffer to a target buffer. +/** + * @param target A modifiable buffer representing the memory region to which + * the bytes will be copied. + * + * @param source A non-modifiable buffer representing the memory region from + * which the bytes will be copied. + * + * @param max_bytes_to_copy The maximum number of bytes to be copied. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + * + * @li @c max_bytes_to_copy + */ +inline std::size_t buffer_copy(const mutable_buffer& target, + const const_buffers_1& source, std::size_t max_bytes_to_copy) +{ + return buffer_copy(buffer(target, max_bytes_to_copy), source); +} + +/// Copies a limited number of bytes from a source buffer to a target buffer. +/** + * @param target A modifiable buffer representing the memory region to which + * the bytes will be copied. + * + * @param source A modifiable buffer representing the memory region from which + * the bytes will be copied. The contents of the source buffer will not be + * modified. + * + * @param max_bytes_to_copy The maximum number of bytes to be copied. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + * + * @li @c max_bytes_to_copy + */ +inline std::size_t buffer_copy(const mutable_buffer& target, + const mutable_buffer& source, std::size_t max_bytes_to_copy) +{ + return buffer_copy(buffer(target, max_bytes_to_copy), source); +} + +/// Copies a limited number of bytes from a source buffer to a target buffer. +/** + * @param target A modifiable buffer representing the memory region to which + * the bytes will be copied. + * + * @param source A modifiable buffer representing the memory region from which + * the bytes will be copied. The contents of the source buffer will not be + * modified. + * + * @param max_bytes_to_copy The maximum number of bytes to be copied. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + * + * @li @c max_bytes_to_copy + */ +inline std::size_t buffer_copy(const mutable_buffer& target, + const mutable_buffers_1& source, std::size_t max_bytes_to_copy) +{ + return buffer_copy(buffer(target, max_bytes_to_copy), source); +} + +/// Copies a limited number of bytes from a source buffer sequence to a target +/// buffer. +/** + * @param target A modifiable buffer representing the memory region to which + * the bytes will be copied. + * + * @param source A non-modifiable buffer sequence representing the memory + * regions from which the bytes will be copied. + * + * @param max_bytes_to_copy The maximum number of bytes to be copied. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + * + * @li @c max_bytes_to_copy + */ +template +inline std::size_t buffer_copy(const mutable_buffer& target, + const ConstBufferSequence& source, std::size_t max_bytes_to_copy) +{ + return buffer_copy(buffer(target, max_bytes_to_copy), source); +} + +/// Copies a limited number of bytes from a source buffer to a target buffer. +/** + * @param target A modifiable buffer representing the memory region to which + * the bytes will be copied. + * + * @param source A non-modifiable buffer representing the memory region from + * which the bytes will be copied. + * + * @param max_bytes_to_copy The maximum number of bytes to be copied. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + * + * @li @c max_bytes_to_copy + */ +inline std::size_t buffer_copy(const mutable_buffers_1& target, + const const_buffer& source, std::size_t max_bytes_to_copy) +{ + return buffer_copy(buffer(target, max_bytes_to_copy), source); +} + +/// Copies a limited number of bytes from a source buffer to a target buffer. +/** + * @param target A modifiable buffer representing the memory region to which + * the bytes will be copied. + * + * @param source A non-modifiable buffer representing the memory region from + * which the bytes will be copied. + * + * @param max_bytes_to_copy The maximum number of bytes to be copied. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + * + * @li @c max_bytes_to_copy + */ +inline std::size_t buffer_copy(const mutable_buffers_1& target, + const const_buffers_1& source, std::size_t max_bytes_to_copy) +{ + return buffer_copy(buffer(target, max_bytes_to_copy), source); +} + +/// Copies a limited number of bytes from a source buffer to a target buffer. +/** + * @param target A modifiable buffer representing the memory region to which + * the bytes will be copied. + * + * @param source A modifiable buffer representing the memory region from which + * the bytes will be copied. The contents of the source buffer will not be + * modified. + * + * @param max_bytes_to_copy The maximum number of bytes to be copied. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + * + * @li @c max_bytes_to_copy + */ +inline std::size_t buffer_copy(const mutable_buffers_1& target, + const mutable_buffer& source, std::size_t max_bytes_to_copy) +{ + return buffer_copy(buffer(target, max_bytes_to_copy), source); +} + +/// Copies a limited number of bytes from a source buffer to a target buffer. +/** + * @param target A modifiable buffer representing the memory region to which + * the bytes will be copied. + * + * @param source A modifiable buffer representing the memory region from which + * the bytes will be copied. The contents of the source buffer will not be + * modified. + * + * @param max_bytes_to_copy The maximum number of bytes to be copied. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + * + * @li @c max_bytes_to_copy + */ +inline std::size_t buffer_copy(const mutable_buffers_1& target, + const mutable_buffers_1& source, std::size_t max_bytes_to_copy) +{ + return buffer_copy(buffer(target, max_bytes_to_copy), source); +} + +/// Copies a limited number of bytes from a source buffer sequence to a target +/// buffer. +/** + * @param target A modifiable buffer representing the memory region to which + * the bytes will be copied. + * + * @param source A non-modifiable buffer sequence representing the memory + * regions from which the bytes will be copied. + * + * @param max_bytes_to_copy The maximum number of bytes to be copied. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + * + * @li @c max_bytes_to_copy + */ +template +inline std::size_t buffer_copy(const mutable_buffers_1& target, + const ConstBufferSequence& source, std::size_t max_bytes_to_copy) +{ + return buffer_copy(buffer(target, max_bytes_to_copy), source); +} + +/// Copies a limited number of bytes from a source buffer to a target buffer +/// sequence. +/** + * @param target A modifiable buffer sequence representing the memory regions to + * which the bytes will be copied. + * + * @param source A non-modifiable buffer representing the memory region from + * which the bytes will be copied. + * + * @param max_bytes_to_copy The maximum number of bytes to be copied. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + * + * @li @c max_bytes_to_copy + */ +template +inline std::size_t buffer_copy(const MutableBufferSequence& target, + const const_buffer& source, std::size_t max_bytes_to_copy) +{ + return buffer_copy(target, buffer(source, max_bytes_to_copy)); +} + +/// Copies a limited number of bytes from a source buffer to a target buffer +/// sequence. +/** + * @param target A modifiable buffer sequence representing the memory regions to + * which the bytes will be copied. + * + * @param source A non-modifiable buffer representing the memory region from + * which the bytes will be copied. + * + * @param max_bytes_to_copy The maximum number of bytes to be copied. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + * + * @li @c max_bytes_to_copy + */ +template +inline std::size_t buffer_copy(const MutableBufferSequence& target, + const const_buffers_1& source, std::size_t max_bytes_to_copy) +{ + return buffer_copy(target, buffer(source, max_bytes_to_copy)); +} + +/// Copies a limited number of bytes from a source buffer to a target buffer +/// sequence. +/** + * @param target A modifiable buffer sequence representing the memory regions to + * which the bytes will be copied. + * + * @param source A modifiable buffer representing the memory region from which + * the bytes will be copied. The contents of the source buffer will not be + * modified. + * + * @param max_bytes_to_copy The maximum number of bytes to be copied. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + * + * @li @c max_bytes_to_copy + */ +template +inline std::size_t buffer_copy(const MutableBufferSequence& target, + const mutable_buffer& source, std::size_t max_bytes_to_copy) +{ + return buffer_copy(target, buffer(source, max_bytes_to_copy)); +} + +/// Copies a limited number of bytes from a source buffer to a target buffer +/// sequence. +/** + * @param target A modifiable buffer sequence representing the memory regions to + * which the bytes will be copied. + * + * @param source A modifiable buffer representing the memory region from which + * the bytes will be copied. The contents of the source buffer will not be + * modified. + * + * @param max_bytes_to_copy The maximum number of bytes to be copied. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + * + * @li @c max_bytes_to_copy + */ +template +inline std::size_t buffer_copy(const MutableBufferSequence& target, + const mutable_buffers_1& source, std::size_t max_bytes_to_copy) +{ + return buffer_copy(target, buffer(source, max_bytes_to_copy)); +} + +/// Copies a limited number of bytes from a source buffer sequence to a target +/// buffer sequence. +/** + * @param target A modifiable buffer sequence representing the memory regions to + * which the bytes will be copied. + * + * @param source A non-modifiable buffer sequence representing the memory + * regions from which the bytes will be copied. + * + * @param max_bytes_to_copy The maximum number of bytes to be copied. + * + * @returns The number of bytes copied. + * + * @note The number of bytes copied is the lesser of: + * + * @li @c buffer_size(target) + * + * @li @c buffer_size(source) + * + * @li @c max_bytes_to_copy + */ +template +std::size_t buffer_copy(const MutableBufferSequence& target, + const ConstBufferSequence& source, std::size_t max_bytes_to_copy) +{ + std::size_t total_bytes_copied = 0; + + typename MutableBufferSequence::const_iterator target_iter = target.begin(); + typename MutableBufferSequence::const_iterator target_end = target.end(); + std::size_t target_buffer_offset = 0; + + typename ConstBufferSequence::const_iterator source_iter = source.begin(); + typename ConstBufferSequence::const_iterator source_end = source.end(); + std::size_t source_buffer_offset = 0; + + while (total_bytes_copied != max_bytes_to_copy + && target_iter != target_end && source_iter != source_end) + { + mutable_buffer target_buffer = + mutable_buffer(*target_iter) + target_buffer_offset; + + const_buffer source_buffer = + const_buffer(*source_iter) + source_buffer_offset; + + std::size_t bytes_copied = buffer_copy(target_buffer, + source_buffer, max_bytes_to_copy - total_bytes_copied); + total_bytes_copied += bytes_copied; + + if (bytes_copied == buffer_size(target_buffer)) + { + ++target_iter; + target_buffer_offset = 0; + } + else + target_buffer_offset += bytes_copied; + + if (bytes_copied == buffer_size(source_buffer)) + { + ++source_iter; + source_buffer_offset = 0; + } + else + source_buffer_offset += bytes_copied; + } + + return total_bytes_copied; +} + +/*@}*/ + } // namespace asio #include "asio/detail/pop_options.hpp" diff --git a/asio/include/asio/buffered_read_stream.hpp b/asio/include/asio/buffered_read_stream.hpp index be7e1a39..37133401 100644 --- a/asio/include/asio/buffered_read_stream.hpp +++ b/asio/include/asio/buffered_read_stream.hpp @@ -17,7 +17,6 @@ #include "asio/detail/config.hpp" #include -#include #include #include "asio/buffered_read_stream_fwd.hpp" #include "asio/buffer.hpp" @@ -219,16 +218,7 @@ public: template std::size_t read_some(const MutableBufferSequence& buffers) { - typename MutableBufferSequence::const_iterator iter = buffers.begin(); - typename MutableBufferSequence::const_iterator end = buffers.end(); - size_t total_buffer_size = 0; - for (; iter != end; ++iter) - { - asio::mutable_buffer buffer(*iter); - total_buffer_size += asio::buffer_size(buffer); - } - - if (total_buffer_size == 0) + if (asio::buffer_size(buffers) == 0) return 0; if (storage_.empty()) @@ -245,16 +235,7 @@ public: { ec = asio::error_code(); - typename MutableBufferSequence::const_iterator iter = buffers.begin(); - typename MutableBufferSequence::const_iterator end = buffers.end(); - size_t total_buffer_size = 0; - for (; iter != end; ++iter) - { - asio::mutable_buffer buffer(*iter); - total_buffer_size += asio::buffer_size(buffer); - } - - if (total_buffer_size == 0) + if (asio::buffer_size(buffers) == 0) return 0; if (storage_.empty() && !fill(ec)) @@ -286,24 +267,8 @@ public: } else { - using namespace std; // For memcpy. - - std::size_t bytes_avail = storage_.size(); - std::size_t bytes_copied = 0; - - typename MutableBufferSequence::const_iterator iter = buffers_.begin(); - typename MutableBufferSequence::const_iterator end = buffers_.end(); - for (; iter != end && bytes_avail > 0; ++iter) - { - std::size_t max_length = buffer_size(*iter); - std::size_t length = (max_length < bytes_avail) - ? max_length : bytes_avail; - memcpy(buffer_cast(*iter), - storage_.data() + bytes_copied, length); - bytes_copied += length; - bytes_avail -= length; - } - + std::size_t bytes_copied = asio::buffer_copy( + buffers_, storage_.data(), storage_.size()); storage_.consume(bytes_copied); io_service_.dispatch(detail::bind_handler(handler_, ec, bytes_copied)); } @@ -322,16 +287,7 @@ public: void async_read_some(const MutableBufferSequence& buffers, ReadHandler handler) { - typename MutableBufferSequence::const_iterator iter = buffers.begin(); - typename MutableBufferSequence::const_iterator end = buffers.end(); - size_t total_buffer_size = 0; - for (; iter != end; ++iter) - { - asio::mutable_buffer buffer(*iter); - total_buffer_size += asio::buffer_size(buffer); - } - - if (total_buffer_size == 0) + if (asio::buffer_size(buffers) == 0) { get_io_service().post(detail::bind_handler( handler, asio::error_code(), 0)); @@ -390,23 +346,8 @@ private: template std::size_t copy(const MutableBufferSequence& buffers) { - using namespace std; // For memcpy. - - std::size_t bytes_avail = storage_.size(); - std::size_t bytes_copied = 0; - - typename MutableBufferSequence::const_iterator iter = buffers.begin(); - typename MutableBufferSequence::const_iterator end = buffers.end(); - for (; iter != end && bytes_avail > 0; ++iter) - { - std::size_t max_length = buffer_size(*iter); - std::size_t length = (max_length < bytes_avail) - ? max_length : bytes_avail; - memcpy(buffer_cast(*iter), storage_.data() + bytes_copied, length); - bytes_copied += length; - bytes_avail -= length; - } - + std::size_t bytes_copied = asio::buffer_copy( + buffers, storage_.data(), storage_.size()); storage_.consume(bytes_copied); return bytes_copied; } @@ -417,24 +358,7 @@ private: template std::size_t peek_copy(const MutableBufferSequence& buffers) { - using namespace std; // For memcpy. - - std::size_t bytes_avail = storage_.size(); - std::size_t bytes_copied = 0; - - typename MutableBufferSequence::const_iterator iter = buffers.begin(); - typename MutableBufferSequence::const_iterator end = buffers.end(); - for (; iter != end && bytes_avail > 0; ++iter) - { - std::size_t max_length = buffer_size(*iter); - std::size_t length = (max_length < bytes_avail) - ? max_length : bytes_avail; - memcpy(buffer_cast(*iter), storage_.data() + bytes_copied, length); - bytes_copied += length; - bytes_avail -= length; - } - - return bytes_copied; + return asio::buffer_copy(buffers, storage_.data(), storage_.size()); } /// The next layer. diff --git a/asio/include/asio/buffered_write_stream.hpp b/asio/include/asio/buffered_write_stream.hpp index d2024d66..a472644b 100644 --- a/asio/include/asio/buffered_write_stream.hpp +++ b/asio/include/asio/buffered_write_stream.hpp @@ -17,7 +17,6 @@ #include "asio/detail/config.hpp" #include -#include #include #include "asio/buffered_write_stream_fwd.hpp" #include "asio/buffer.hpp" @@ -176,16 +175,7 @@ public: template std::size_t write_some(const ConstBufferSequence& buffers) { - typename ConstBufferSequence::const_iterator iter = buffers.begin(); - typename ConstBufferSequence::const_iterator end = buffers.end(); - size_t total_buffer_size = 0; - for (; iter != end; ++iter) - { - asio::const_buffer buffer(*iter); - total_buffer_size += asio::buffer_size(buffer); - } - - if (total_buffer_size == 0) + if (asio::buffer_size(buffers) == 0) return 0; if (storage_.size() == storage_.capacity()) @@ -202,16 +192,7 @@ public: { ec = asio::error_code(); - typename ConstBufferSequence::const_iterator iter = buffers.begin(); - typename ConstBufferSequence::const_iterator end = buffers.end(); - size_t total_buffer_size = 0; - for (; iter != end; ++iter) - { - asio::const_buffer buffer(*iter); - total_buffer_size += asio::buffer_size(buffer); - } - - if (total_buffer_size == 0) + if (asio::buffer_size(buffers) == 0) return 0; if (storage_.size() == storage_.capacity() && !flush(ec)) @@ -243,25 +224,14 @@ public: } else { - using namespace std; // For memcpy. - std::size_t orig_size = storage_.size(); std::size_t space_avail = storage_.capacity() - orig_size; - std::size_t bytes_copied = 0; - - typename ConstBufferSequence::const_iterator iter = buffers_.begin(); - typename ConstBufferSequence::const_iterator end = buffers_.end(); - for (; iter != end && space_avail > 0; ++iter) - { - std::size_t bytes_avail = buffer_size(*iter); - std::size_t length = (bytes_avail < space_avail) - ? bytes_avail : space_avail; - storage_.resize(orig_size + bytes_copied + length); - memcpy(storage_.data() + orig_size + bytes_copied, - buffer_cast(*iter), length); - bytes_copied += length; - space_avail -= length; - } + std::size_t bytes_avail = asio::buffer_size(buffers_); + std::size_t length = bytes_avail < space_avail + ? bytes_avail : space_avail; + storage_.resize(orig_size + length); + std::size_t bytes_copied = asio::buffer_copy( + storage_.data(), buffers_, length); io_service_.dispatch(detail::bind_handler(handler_, ec, bytes_copied)); } @@ -280,16 +250,7 @@ public: void async_write_some(const ConstBufferSequence& buffers, WriteHandler handler) { - typename ConstBufferSequence::const_iterator iter = buffers.begin(); - typename ConstBufferSequence::const_iterator end = buffers.end(); - size_t total_buffer_size = 0; - for (; iter != end; ++iter) - { - asio::const_buffer buffer(*iter); - total_buffer_size += asio::buffer_size(buffer); - } - - if (total_buffer_size == 0) + if (asio::buffer_size(buffers) == 0) { get_io_service().post(detail::bind_handler( handler, asio::error_code(), 0)); @@ -368,27 +329,12 @@ private: template std::size_t copy(const ConstBufferSequence& buffers) { - using namespace std; // For memcpy. - std::size_t orig_size = storage_.size(); std::size_t space_avail = storage_.capacity() - orig_size; - std::size_t bytes_copied = 0; - - typename ConstBufferSequence::const_iterator iter = buffers.begin(); - typename ConstBufferSequence::const_iterator end = buffers.end(); - for (; iter != end && space_avail > 0; ++iter) - { - std::size_t bytes_avail = buffer_size(*iter); - std::size_t length = (bytes_avail < space_avail) - ? bytes_avail : space_avail; - storage_.resize(orig_size + bytes_copied + length); - memcpy(storage_.data() + orig_size + bytes_copied, - buffer_cast(*iter), length); - bytes_copied += length; - space_avail -= length; - } - - return bytes_copied; + std::size_t bytes_avail = asio::buffer_size(buffers); + std::size_t length = bytes_avail < space_avail ? bytes_avail : space_avail; + storage_.resize(orig_size + length); + return asio::buffer_copy(storage_.data(), buffers, length); } /// The next layer. diff --git a/asio/include/asio/detail/buffered_stream_storage.hpp b/asio/include/asio/detail/buffered_stream_storage.hpp index 5b655aaf..63fabb71 100644 --- a/asio/include/asio/detail/buffered_stream_storage.hpp +++ b/asio/include/asio/detail/buffered_stream_storage.hpp @@ -16,6 +16,7 @@ #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include "asio/detail/config.hpp" +#include "asio/buffer.hpp" #include #include #include @@ -51,15 +52,15 @@ public: } // Return a pointer to the beginning of the unread data. - byte_type* data() + mutable_buffer data() { - return &buffer_[0] + begin_offset_; + return asio::buffer(buffer_) + begin_offset_; } // Return a pointer to the beginning of the unread data. - const byte_type* data() const + const_buffer data() const { - return &buffer_[0] + begin_offset_; + return asio::buffer(buffer_) + begin_offset_; } // Is there no unread data in the buffer. diff --git a/asio/src/tests/unit/buffer.cpp b/asio/src/tests/unit/buffer.cpp index 1bcf83ef..ffb2589f 100644 --- a/asio/src/tests/unit/buffer.cpp +++ b/asio/src/tests/unit/buffer.cpp @@ -44,6 +44,8 @@ void test() std::vector vector_data(1024); const std::vector& const_vector_data = vector_data; const std::string string_data(1024, ' '); + std::vector mutable_buffer_sequence; + std::vector const_buffer_sequence; // mutable_buffer constructors. @@ -51,13 +53,6 @@ void test() mutable_buffer mb2(void_ptr_data, 1024); mutable_buffer mb3(mb1); - // mutable_buffer functions. - - void* ptr1 = buffer_cast(mb1); - (void)ptr1; - std::size_t size1 = buffer_size(mb1); - (void)size1; - // mutable_buffer operators. mb1 = mb2 + 128; @@ -82,13 +77,6 @@ void test() const_buffer cb3(cb1); const_buffer cb4(mb1); - // const_buffer functions. - - const void* ptr2 = buffer_cast(cb1); - (void)ptr2; - std::size_t size2 = buffer_size(cb1); - (void)size2; - // const_buffer operators. cb1 = cb2 + 128; @@ -106,6 +94,28 @@ void test() const_buffers_1::const_iterator iter4 = cbc1.end(); (void)iter4; + // buffer_size function overloads. + + std::size_t size1 = buffer_size(mb1); + (void)size1; + std::size_t size2 = buffer_size(cb1); + (void)size2; + std::size_t size3 = buffer_size(mbc1); + (void)size3; + std::size_t size4 = buffer_size(cbc1); + (void)size4; + std::size_t size5 = buffer_size(mutable_buffer_sequence); + (void)size5; + std::size_t size6 = buffer_size(const_buffer_sequence); + (void)size6; + + // buffer_cast function overloads. + + void* ptr1 = buffer_cast(mb1); + (void)ptr1; + const void* ptr2 = buffer_cast(cb1); + (void)ptr2; + // buffer function overloads. mb1 = buffer(mb2); @@ -130,6 +140,71 @@ void test() cb1 = buffer(const_vector_data, 1024); cb1 = buffer(string_data); cb1 = buffer(string_data, 1024); + + // buffer_copy function overloads. + + std::size_t size7 = buffer_copy(mb1, cb2); + (void)size7; + std::size_t size8 = buffer_copy(mb1, cbc2); + (void)size8; + std::size_t size9 = buffer_copy(mb1, mb2); + (void)size9; + std::size_t size10 = buffer_copy(mb1, mbc2); + (void)size10; + std::size_t size11 = buffer_copy(mb1, const_buffer_sequence); + (void)size11; + std::size_t size12 = buffer_copy(mbc1, cb2); + (void)size12; + std::size_t size13 = buffer_copy(mbc1, cbc2); + (void)size13; + std::size_t size14 = buffer_copy(mbc1, mb2); + (void)size14; + std::size_t size15 = buffer_copy(mbc1, mbc2); + (void)size15; + std::size_t size16 = buffer_copy(mbc1, const_buffer_sequence); + (void)size16; + std::size_t size17 = buffer_copy(mutable_buffer_sequence, cb2); + (void)size17; + std::size_t size18 = buffer_copy(mutable_buffer_sequence, cbc2); + (void)size18; + std::size_t size19 = buffer_copy(mutable_buffer_sequence, mb2); + (void)size19; + std::size_t size20 = buffer_copy(mutable_buffer_sequence, mbc2); + (void)size20; + std::size_t size21 = buffer_copy( + mutable_buffer_sequence, const_buffer_sequence); + (void)size21; + std::size_t size22 = buffer_copy(mb1, cb2, 128); + (void)size22; + std::size_t size23 = buffer_copy(mb1, cbc2, 128); + (void)size23; + std::size_t size24 = buffer_copy(mb1, mb2, 128); + (void)size24; + std::size_t size25 = buffer_copy(mb1, mbc2, 128); + (void)size25; + std::size_t size26 = buffer_copy(mb1, const_buffer_sequence, 128); + (void)size26; + std::size_t size27 = buffer_copy(mbc1, cb2, 128); + (void)size27; + std::size_t size28 = buffer_copy(mbc1, cbc2, 128); + (void)size28; + std::size_t size29 = buffer_copy(mbc1, mb2, 128); + (void)size29; + std::size_t size30 = buffer_copy(mbc1, mbc2, 128); + (void)size30; + std::size_t size31 = buffer_copy(mbc1, const_buffer_sequence, 128); + (void)size31; + std::size_t size32 = buffer_copy(mutable_buffer_sequence, cb2, 128); + (void)size32; + std::size_t size33 = buffer_copy(mutable_buffer_sequence, cbc2, 128); + (void)size33; + std::size_t size34 = buffer_copy(mutable_buffer_sequence, mb2, 128); + (void)size34; + std::size_t size35 = buffer_copy(mutable_buffer_sequence, mbc2, 128); + (void)size35; + std::size_t size36 = buffer_copy( + mutable_buffer_sequence, const_buffer_sequence, 128); + (void)size36; } catch (std::exception&) { diff --git a/asio/src/tests/unit/read.cpp b/asio/src/tests/unit/read.cpp index 45b73928..491250f2 100644 --- a/asio/src/tests/unit/read.cpp +++ b/asio/src/tests/unit/read.cpp @@ -88,25 +88,11 @@ public: template size_t read_some(const Mutable_Buffers& buffers) { - size_t total_length = 0; - - typename Mutable_Buffers::const_iterator iter = buffers.begin(); - typename Mutable_Buffers::const_iterator end = buffers.end(); - for (; iter != end && total_length < next_read_length_; ++iter) - { - size_t length = asio::buffer_size(*iter); - if (length > length_ - position_) - length = length_ - position_; - - if (length > next_read_length_ - total_length) - length = next_read_length_ - total_length; - - memcpy(asio::buffer_cast(*iter), data_ + position_, length); - position_ += length; - total_length += length; - } - - return total_length; + size_t n = asio::buffer_copy(buffers, + asio::buffer(data_, length_) + position_, + next_read_length_); + position_ += n; + return n; } template diff --git a/asio/src/tests/unit/read_at.cpp b/asio/src/tests/unit/read_at.cpp index b9264d18..974801e0 100644 --- a/asio/src/tests/unit/read_at.cpp +++ b/asio/src/tests/unit/read_at.cpp @@ -91,26 +91,9 @@ public: template size_t read_some_at(boost::uint64_t offset, const Mutable_Buffers& buffers) { - size_t total_length = 0; - - typename Mutable_Buffers::const_iterator iter = buffers.begin(); - typename Mutable_Buffers::const_iterator end = buffers.end(); - for (; iter != end && total_length < next_read_length_; ++iter) - { - size_t length = asio::buffer_size(*iter); - if (length > length_ - offset) - length = length_ - offset; - - if (length > next_read_length_ - total_length) - length = next_read_length_ - total_length; - - memcpy(asio::buffer_cast(*iter), - data_ + offset, length); - offset += length; - total_length += length; - } - - return total_length; + return asio::buffer_copy(buffers, + asio::buffer(data_, length_) + offset, + next_read_length_); } template diff --git a/asio/src/tests/unit/read_until.cpp b/asio/src/tests/unit/read_until.cpp index 2625ede6..2be54e2f 100644 --- a/asio/src/tests/unit/read_until.cpp +++ b/asio/src/tests/unit/read_until.cpp @@ -63,27 +63,11 @@ public: template size_t read_some(const Mutable_Buffers& buffers) { - using namespace std; // For memcpy. - - size_t total_length = 0; - - typename Mutable_Buffers::const_iterator iter = buffers.begin(); - typename Mutable_Buffers::const_iterator end = buffers.end(); - for (; iter != end && total_length < next_read_length_; ++iter) - { - size_t length = asio::buffer_size(*iter); - if (length > length_ - position_) - length = length_ - position_; - - if (length > next_read_length_ - total_length) - length = next_read_length_ - total_length; - - memcpy(asio::buffer_cast(*iter), data_ + position_, length); - position_ += length; - total_length += length; - } - - return total_length; + size_t n = asio::buffer_copy(buffers, + asio::buffer(data_, length_) + position_, + next_read_length_); + position_ += n; + return n; } template diff --git a/asio/src/tests/unit/write.cpp b/asio/src/tests/unit/write.cpp index db9e8b73..25645257 100644 --- a/asio/src/tests/unit/write.cpp +++ b/asio/src/tests/unit/write.cpp @@ -88,26 +88,11 @@ public: template size_t write_some(const Const_Buffers& buffers) { - size_t total_length = 0; - - typename Const_Buffers::const_iterator iter = buffers.begin(); - typename Const_Buffers::const_iterator end = buffers.end(); - for (; iter != end && total_length < next_write_length_; ++iter) - { - size_t length = asio::buffer_size(*iter); - if (length > length_ - position_) - length = length_ - position_; - - if (length > next_write_length_ - total_length) - length = next_write_length_ - total_length; - - memcpy(data_ + position_, - asio::buffer_cast(*iter), length); - position_ += length; - total_length += length; - } - - return total_length; + size_t n = asio::buffer_copy( + asio::buffer(data_, length_) + position_, + buffers, next_write_length_); + position_ += n; + return n; } template diff --git a/asio/src/tests/unit/write_at.cpp b/asio/src/tests/unit/write_at.cpp index 057563a7..4cabd6d2 100644 --- a/asio/src/tests/unit/write_at.cpp +++ b/asio/src/tests/unit/write_at.cpp @@ -83,26 +83,9 @@ public: template size_t write_some_at(boost::uint64_t offset, const Const_Buffers& buffers) { - size_t total_length = 0; - - typename Const_Buffers::const_iterator iter = buffers.begin(); - typename Const_Buffers::const_iterator end = buffers.end(); - for (; iter != end && total_length < next_write_length_; ++iter) - { - size_t length = asio::buffer_size(*iter); - if (length > length_ - offset) - length = length_ - offset; - - if (length > next_write_length_ - total_length) - length = next_write_length_ - total_length; - - memcpy(data_ + offset, - asio::buffer_cast(*iter), length); - offset += length; - total_length += length; - } - - return total_length; + return asio::buffer_copy( + asio::buffer(data_, length_) + offset, + buffers, next_write_length_); } template