mercredi 6 février 2019

How to read data when length is unknown?

I'm currently using boost::asio to read data across network connections but settled on a pattern I feel is inneficient:

auto listener::read(std::function<void(std::error_code ec, packet packet)> callback) noexcept -> void {
  m_buffer.resize(1);
  m_buffer.shrink_to_fit();

  asio::async_read(*m_socket, asio::buffer(m_buffer), asio::transfer_exactly(1),
                   [&, callback](std::error_code ec, std::size_t length) {
                     const auto available = m_socket->available();
                     packet tmp;
                     tmp.resize(available);
                     asio::async_read(*m_socket, asio::buffer(tmp), asio::transfer_exactly(available));
                     tmp.insert(tmp.begin(), std::make_move_iterator(m_buffer.begin()),
                                std::make_move_iterator(m_buffer.end()));
                     callback(ec, std::move(tmp));
                   });
}

(packet is std::vector<unsigned char>)

I'm not sure how to create this without the temporary. I can't resize m_buffer at the beginning because I don't know how much data is coming. I tried to use m_buffer only resizing within the lambda to match available + 1 but I just end up losing the first byte stored in m_buffer.

Is there a more efficient way to do this when expecting a packet of unknown length?

Aucun commentaire:

Enregistrer un commentaire