async_read_until
要求basic_streambuf
将数据读入其中。我不想分配额外的内存,而是使用内存地址(来自我不允许更改的指定接口)作为目标缓冲区。
是否可以使用外部内存地址创建streambuf
,还是需要编写包装类?
答案 0 :(得分:1)
最后通过编写我自己的async_read_until_delim
类来解决这个问题,该类需要读取内存指针和最大字节值。它与原始的boost实现尽可能接近,但有一些调整可以带来更高性能的执行。
namespace {
template<typename read_handler>
class async_read_until_delim
{
public:
async_read_until_delim(tcp::socket& socket, void* buffer, std::size_t max_read_size_in_bytes,
char delim, read_handler& handler)
: m_socket(socket), m_cur(static_cast<char*>(buffer)),
m_end(static_cast<char*>(buffer) + max_read_size_in_bytes), m_delim(delim),
m_handler(handler), m_pos(0)
{
read_some();
}
async_read_until_delim(async_read_until_delim const& other)
: m_socket(other.m_socket), m_cur(other.m_cur), m_end(other.m_end), m_delim(other.m_delim),
m_handler(other.m_handler), m_pos(other.m_pos)
{
}
void operator()(boost::system::error_code const& error, std::size_t bytes_transferred)
{
if (!error)
{
if (std::find(m_cur, m_end, m_delim) != m_end)
{
m_handler(error, m_pos + bytes_transferred);
return;
}
else if (m_cur == m_end)
{
m_handler(boost::asio::error::not_found, -1);
return;
}
m_cur += bytes_transferred;
m_pos += bytes_transferred;
read_some();
}
else
m_handler(error, m_pos);
}
private:
void read_some()
{
m_socket.async_read_some(
boost::asio::buffer(m_cur, m_end - m_cur), async_read_until_delim(*this));
}
tcp::socket& m_socket;
char *m_cur,
*m_end;
char m_delim;
read_handler m_handler;
std::size_t m_pos;
};
template<typename read_handler>
inline void do_async_read_until_delim(tcp::socket& socket, void* buffer, std::size_t max_read_size_in_bytes,
char delim, read_handler& handler)
{
async_read_until_delim<read_handler>(socket, buffer, max_read_size_in_bytes, delim, handler);
}
} /* anonymous namespace */
所以,我希望它对某些人也有用。