#include "client.hpp" #include "connect.hpp" #include using namespace boost::asio::ip; using namespace boost::system; Client::Client(tcp::socket &&socket) : socket(std::move(socket)) , buffer(new boost::asio::streambuf()) , done() {} Client::~Client() { close(); } void Client::async_connect(std::string next_host, std::string next_port, std::function on_connect) { ::async_connect(socket, next_host, next_port, on_connect); } std::array Client::prepare_length_prefix(uint32_t length) { length = htonl(length); std::array buf; std::copy(reinterpret_cast(&length), reinterpret_cast(&length) + 4, buf.data()); return buf; } std::vector Client::received_bytes_to_vector(size_t read_bytes) { buffer->commit(read_bytes); std::istream is(buffer.get()); is.unsetf(std::ios::skipws); return std::vector(std::istream_iterator(is), {}); } void Client::handle_receive_message(MessageHandler message_handler, const error_code &ec, size_t read_bytes) { if(!ec) { std::vector data = received_bytes_to_vector(read_bytes); message_handler(data); } else { BOOST_LOG_TRIVIAL(error) << ec; if(done) { done(); } } } void Client::handle_receive_size(Client::MessageHandler message_handler, error_code const& ec, size_t read_bytes) { using namespace boost::asio::placeholders; if(!ec) { std::vector data = received_bytes_to_vector(read_bytes); uint32_t size; std::copy(data.begin(), data.end(), reinterpret_cast(&size)); size = ntohl(size); socket.async_receive( buffer->prepare(size), boost::bind(&Client::handle_receive_message, this, message_handler, error(), bytes_transferred()) ); } else { BOOST_LOG_TRIVIAL(error) << ec; if(done) { done(); } } } void Client::close() { socket.close(); } void Client::on_done(Client::OnDoneFT f) { done = f; } bool Client::is_open() const { return socket.is_open(); }