Extend the buffer_size() function so that it works for buffer sequences

in addition to individual buffers.

Add a new buffer_copy() function that can be used to copy the raw bytes
between individual buffers and buffer sequences.
This commit is contained in:
Christopher Kohlhoff 2011-02-08 19:02:15 +11:00
parent 548ce5c9a4
commit 37ed4c8c44
10 changed files with 1235 additions and 388 deletions

File diff suppressed because it is too large Load Diff

View File

@ -17,7 +17,6 @@
#include "asio/detail/config.hpp"
#include <cstddef>
#include <cstring>
#include <boost/type_traits/remove_reference.hpp>
#include "asio/buffered_read_stream_fwd.hpp"
#include "asio/buffer.hpp"
@ -219,16 +218,7 @@ public:
template <typename MutableBufferSequence>
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<void*>(*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 <typename MutableBufferSequence>
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<void*>(*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 <typename MutableBufferSequence>
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<void*>(*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.

View File

@ -17,7 +17,6 @@
#include "asio/detail/config.hpp"
#include <cstddef>
#include <cstring>
#include <boost/type_traits/remove_reference.hpp>
#include "asio/buffered_write_stream_fwd.hpp"
#include "asio/buffer.hpp"
@ -176,16 +175,7 @@ public:
template <typename ConstBufferSequence>
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<const void*>(*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 <typename ConstBufferSequence>
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<const void*>(*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.

View File

@ -16,6 +16,7 @@
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/config.hpp"
#include "asio/buffer.hpp"
#include <boost/assert.hpp>
#include <cstddef>
#include <cstring>
@ -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.

View File

@ -44,6 +44,8 @@ void test()
std::vector<char> vector_data(1024);
const std::vector<char>& const_vector_data = vector_data;
const std::string string_data(1024, ' ');
std::vector<mutable_buffer> mutable_buffer_sequence;
std::vector<const_buffer> 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<void*>(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<const void*>(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<void*>(mb1);
(void)ptr1;
const void* ptr2 = buffer_cast<const void*>(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&)
{

View File

@ -88,25 +88,11 @@ public:
template <typename Mutable_Buffers>
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<void*>(*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 <typename Mutable_Buffers>

View File

@ -91,26 +91,9 @@ public:
template <typename Mutable_Buffers>
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<void*>(*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 <typename Mutable_Buffers>

View File

@ -63,27 +63,11 @@ public:
template <typename Mutable_Buffers>
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<void*>(*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 <typename Mutable_Buffers>

View File

@ -88,26 +88,11 @@ public:
template <typename Const_Buffers>
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<const void*>(*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 <typename Const_Buffers>

View File

@ -83,26 +83,9 @@ public:
template <typename Const_Buffers>
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<const void*>(*iter), length);
offset += length;
total_length += length;
}
return total_length;
return asio::buffer_copy(
asio::buffer(data_, length_) + offset,
buffers, next_write_length_);
}
template <typename Const_Buffers>