read_at.cpp

来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 1,467 行 · 第 1/4 页

CPP
1,467
字号
//// read_at.cpp// ~~~~~~~~~~~//// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)//// Distributed under the Boost Software License, Version 1.0. (See accompanying// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)//// Disable autolinking for unit tests.#if !defined(BOOST_ALL_NO_LIB)#define BOOST_ALL_NO_LIB 1#endif // !defined(BOOST_ALL_NO_LIB)// Test that header file is self-contained.#include <boost/asio/read_at.hpp>#include <boost/bind.hpp>#include <boost/noncopyable.hpp>#include <cstring>#include <boost/asio.hpp>#include "unit_test.hpp"using namespace std; // For memcmp, memcpy and memset.class test_random_access_device  : private boost::noncopyable{public:  typedef boost::asio::io_service io_service_type;  test_random_access_device(boost::asio::io_service& io_service)    : io_service_(io_service),      length_(0),      next_read_length_(0)  {  }  io_service_type& get_io_service()  {    return io_service_;  }  void reset(const void* data, size_t length)  {    BOOST_CHECK(length <= max_length);    length_ = 0;    while (length_ + length < max_length)    {      memcpy(data_ + length_, data, length);      length_ += length;    }    next_read_length_ = length;  }  void next_read_length(size_t length)  {    next_read_length_ = length;  }  template <typename Const_Buffers>  bool check(boost::uint64_t offset,      const Const_Buffers& buffers, size_t length)  {    if (offset + length > max_length)      return false;    typename Const_Buffers::const_iterator iter = buffers.begin();    typename Const_Buffers::const_iterator end = buffers.end();    size_t checked_length = 0;    for (; iter != end && checked_length < length; ++iter)    {      size_t buffer_length = boost::asio::buffer_size(*iter);      if (buffer_length > length - checked_length)        buffer_length = length - checked_length;      if (memcmp(data_ + offset + checked_length,            boost::asio::buffer_cast<const void*>(*iter), buffer_length) != 0)        return false;      checked_length += buffer_length;    }    return true;  }  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 = boost::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(boost::asio::buffer_cast<void*>(*iter),          data_ + offset, length);      offset += length;      total_length += length;    }    return total_length;  }  template <typename Mutable_Buffers>  size_t read_some_at(boost::uint64_t offset,      const Mutable_Buffers& buffers, boost::system::error_code& ec)  {    ec = boost::system::error_code();    return read_some_at(offset, buffers);  }  template <typename Mutable_Buffers, typename Handler>  void async_read_some_at(boost::uint64_t offset,      const Mutable_Buffers& buffers, Handler handler)  {    size_t bytes_transferred = read_some_at(offset, buffers);    io_service_.post(boost::asio::detail::bind_handler(          handler, boost::system::error_code(), bytes_transferred));  }private:  io_service_type& io_service_;  enum { max_length = 8192 };  char data_[max_length];  size_t length_;  size_t next_read_length_;};static const char read_data[]  = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";void test_3_arg_read_at(){  boost::asio::io_service ios;  test_random_access_device s(ios);  char read_buf[sizeof(read_data)];  boost::asio::mutable_buffers_1 buffers    = boost::asio::buffer(read_buf, sizeof(read_buf));  s.reset(read_data, sizeof(read_data));  memset(read_buf, 0, sizeof(read_buf));  size_t bytes_transferred = boost::asio::read_at(s, 0, buffers);  BOOST_CHECK(bytes_transferred == sizeof(read_data));  BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));  s.reset(read_data, sizeof(read_data));  memset(read_buf, 0, sizeof(read_buf));  bytes_transferred = boost::asio::read_at(s, 1234, buffers);  BOOST_CHECK(bytes_transferred == sizeof(read_data));  BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));  s.reset(read_data, sizeof(read_data));  s.next_read_length(1);  memset(read_buf, 0, sizeof(read_buf));  bytes_transferred = boost::asio::read_at(s, 0, buffers);  BOOST_CHECK(bytes_transferred == sizeof(read_data));  BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));  s.reset(read_data, sizeof(read_data));  s.next_read_length(1);  memset(read_buf, 0, sizeof(read_buf));  bytes_transferred = boost::asio::read_at(s, 1234, buffers);  BOOST_CHECK(bytes_transferred == sizeof(read_data));  BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));  s.reset(read_data, sizeof(read_data));  s.next_read_length(10);  memset(read_buf, 0, sizeof(read_buf));  bytes_transferred = boost::asio::read_at(s, 0, buffers);  BOOST_CHECK(bytes_transferred == sizeof(read_data));  BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));  s.reset(read_data, sizeof(read_data));  s.next_read_length(10);  memset(read_buf, 0, sizeof(read_buf));  bytes_transferred = boost::asio::read_at(s, 1234, buffers);  BOOST_CHECK(bytes_transferred == sizeof(read_data));  BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));}bool old_style_transfer_all(const boost::system::error_code& ec,    size_t bytes_transferred){  return !!ec;}size_t short_transfer(const boost::system::error_code& ec,    size_t bytes_transferred){  return !!ec ? 0 : 3;}void test_4_arg_read_at(){  boost::asio::io_service ios;  test_random_access_device s(ios);  char read_buf[sizeof(read_data)];  boost::asio::mutable_buffers_1 buffers    = boost::asio::buffer(read_buf, sizeof(read_buf));  s.reset(read_data, sizeof(read_data));  memset(read_buf, 0, sizeof(read_buf));  size_t bytes_transferred = boost::asio::read_at(s, 0, buffers,      boost::asio::transfer_all());  BOOST_CHECK(bytes_transferred == sizeof(read_data));  BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));  s.reset(read_data, sizeof(read_data));  memset(read_buf, 0, sizeof(read_buf));  bytes_transferred = boost::asio::read_at(s, 1234, buffers,      boost::asio::transfer_all());  BOOST_CHECK(bytes_transferred == sizeof(read_data));  BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));  s.reset(read_data, sizeof(read_data));  s.next_read_length(1);  memset(read_buf, 0, sizeof(read_buf));  bytes_transferred = boost::asio::read_at(s, 0, buffers,      boost::asio::transfer_all());  BOOST_CHECK(bytes_transferred == sizeof(read_data));  BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));  s.reset(read_data, sizeof(read_data));  s.next_read_length(1);  memset(read_buf, 0, sizeof(read_buf));  bytes_transferred = boost::asio::read_at(s, 1234, buffers,      boost::asio::transfer_all());  BOOST_CHECK(bytes_transferred == sizeof(read_data));  BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));  s.reset(read_data, sizeof(read_data));  s.next_read_length(10);  memset(read_buf, 0, sizeof(read_buf));  bytes_transferred = boost::asio::read_at(s, 0, buffers,      boost::asio::transfer_all());  BOOST_CHECK(bytes_transferred == sizeof(read_data));  BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));  s.reset(read_data, sizeof(read_data));  s.next_read_length(10);  memset(read_buf, 0, sizeof(read_buf));  bytes_transferred = boost::asio::read_at(s, 1234, buffers,      boost::asio::transfer_all());  BOOST_CHECK(bytes_transferred == sizeof(read_data));  BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));  s.reset(read_data, sizeof(read_data));  memset(read_buf, 0, sizeof(read_buf));  bytes_transferred = boost::asio::read_at(s, 0, buffers,      boost::asio::transfer_at_least(1));  BOOST_CHECK(bytes_transferred == sizeof(read_data));  BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));  s.reset(read_data, sizeof(read_data));  memset(read_buf, 0, sizeof(read_buf));  bytes_transferred = boost::asio::read_at(s, 1234, buffers,      boost::asio::transfer_at_least(1));  BOOST_CHECK(bytes_transferred == sizeof(read_data));  BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));  s.reset(read_data, sizeof(read_data));  s.next_read_length(1);  memset(read_buf, 0, sizeof(read_buf));  bytes_transferred = boost::asio::read_at(s, 0, buffers,      boost::asio::transfer_at_least(1));  BOOST_CHECK(bytes_transferred == 1);  BOOST_CHECK(s.check(0, buffers, 1));  s.reset(read_data, sizeof(read_data));  s.next_read_length(1);  memset(read_buf, 0, sizeof(read_buf));  bytes_transferred = boost::asio::read_at(s, 1234, buffers,      boost::asio::transfer_at_least(1));  BOOST_CHECK(bytes_transferred == 1);  BOOST_CHECK(s.check(1234, buffers, 1));  s.reset(read_data, sizeof(read_data));  s.next_read_length(10);  memset(read_buf, 0, sizeof(read_buf));  bytes_transferred = boost::asio::read_at(s, 0, buffers,      boost::asio::transfer_at_least(1));  BOOST_CHECK(bytes_transferred == 10);  BOOST_CHECK(s.check(0, buffers, 10));  s.reset(read_data, sizeof(read_data));  s.next_read_length(10);  memset(read_buf, 0, sizeof(read_buf));  bytes_transferred = boost::asio::read_at(s, 1234, buffers,      boost::asio::transfer_at_least(1));  BOOST_CHECK(bytes_transferred == 10);  BOOST_CHECK(s.check(1234, buffers, 10));  s.reset(read_data, sizeof(read_data));  memset(read_buf, 0, sizeof(read_buf));  bytes_transferred = boost::asio::read_at(s, 0, buffers,      boost::asio::transfer_at_least(10));  BOOST_CHECK(bytes_transferred == sizeof(read_data));  BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));  s.reset(read_data, sizeof(read_data));  memset(read_buf, 0, sizeof(read_buf));  bytes_transferred = boost::asio::read_at(s, 1234, buffers,      boost::asio::transfer_at_least(10));  BOOST_CHECK(bytes_transferred == sizeof(read_data));  BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));  s.reset(read_data, sizeof(read_data));  s.next_read_length(1);  memset(read_buf, 0, sizeof(read_buf));  bytes_transferred = boost::asio::read_at(s, 0, buffers,      boost::asio::transfer_at_least(10));  BOOST_CHECK(bytes_transferred == 10);  BOOST_CHECK(s.check(0, buffers, 10));  s.reset(read_data, sizeof(read_data));  s.next_read_length(1);  memset(read_buf, 0, sizeof(read_buf));  bytes_transferred = boost::asio::read_at(s, 1234, buffers,      boost::asio::transfer_at_least(10));  BOOST_CHECK(bytes_transferred == 10);  BOOST_CHECK(s.check(1234, buffers, 10));  s.reset(read_data, sizeof(read_data));  s.next_read_length(10);  memset(read_buf, 0, sizeof(read_buf));  bytes_transferred = boost::asio::read_at(s, 0, buffers,      boost::asio::transfer_at_least(10));  BOOST_CHECK(bytes_transferred == 10);  BOOST_CHECK(s.check(0, buffers, 10));  s.reset(read_data, sizeof(read_data));  s.next_read_length(10);  memset(read_buf, 0, sizeof(read_buf));  bytes_transferred = boost::asio::read_at(s, 1234, buffers,      boost::asio::transfer_at_least(10));  BOOST_CHECK(bytes_transferred == 10);  BOOST_CHECK(s.check(1234, buffers, 10));  s.reset(read_data, sizeof(read_data));  memset(read_buf, 0, sizeof(read_buf));  bytes_transferred = boost::asio::read_at(s, 0, buffers,      boost::asio::transfer_at_least(42));  BOOST_CHECK(bytes_transferred == sizeof(read_data));  BOOST_CHECK(s.check(0, buffers, sizeof(read_data)));  s.reset(read_data, sizeof(read_data));  memset(read_buf, 0, sizeof(read_buf));  bytes_transferred = boost::asio::read_at(s, 1234, buffers,      boost::asio::transfer_at_least(42));  BOOST_CHECK(bytes_transferred == sizeof(read_data));  BOOST_CHECK(s.check(1234, buffers, sizeof(read_data)));  s.reset(read_data, sizeof(read_data));  s.next_read_length(1);  memset(read_buf, 0, sizeof(read_buf));  bytes_transferred = boost::asio::read_at(s, 0, buffers,      boost::asio::transfer_at_least(42));  BOOST_CHECK(bytes_transferred == 42);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?