Наконец решил проблему, написав свой собственный класс 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 */
Так что, я надеюсь, это будет полезно и для кого-то.