| 50 | /// Asynchronously write a data structure to the socket. |
| 51 | template <typename T, typename Handler> |
| 52 | void async_write(const T& t, Handler handler) |
| 53 | { |
| 54 | // Serialize the data first so we know how large it is. |
| 55 | std::ostringstream archive_stream; |
| 56 | boost::archive::text_oarchive archive(archive_stream); |
| 57 | archive << t; |
| 58 | outbound_data_ = archive_stream.str(); |
| 59 | |
| 60 | // Format the header. |
| 61 | std::ostringstream header_stream; |
| 62 | header_stream << std::setw(header_length) |
| 63 | << std::hex << outbound_data_.size(); |
| 64 | if (!header_stream || header_stream.str().size() != header_length) |
| 65 | { |
| 66 | // Something went wrong, inform the caller. |
| 67 | boost::system::error_code error(boost::asio::error::invalid_argument); |
| 68 | boost::asio::post(socket_.get_executor(), std::bind(handler, error)); |
| 69 | return; |
| 70 | } |
| 71 | outbound_header_ = header_stream.str(); |
| 72 | |
| 73 | // Write the serialized data to the socket. We use "gather-write" to send |
| 74 | // both the header and the data in a single write operation. |
| 75 | std::vector<boost::asio::const_buffer> buffers; |
| 76 | buffers.push_back(boost::asio::buffer(outbound_header_)); |
| 77 | buffers.push_back(boost::asio::buffer(outbound_data_)); |
| 78 | boost::asio::async_write(socket_, buffers, handler); |
| 79 | } |
| 80 | |
| 81 | /// Asynchronously read a data structure from the socket. |
| 82 | template <typename T, typename Handler> |
no test coverage detected