SSX3LobbyServer/lib/aries/MessageIo.hpp

63 lines
1.8 KiB
C++
Raw Normal View History

#include <aries/Message.hpp>
#include <aries/Tags.hpp>
#include <base/types.hpp>
#include <boost/asio/read.hpp>
#include <boost/asio/write.hpp>
#include <exception>
#include <impl/asio_config.hpp>
namespace ls::aries {
constexpr static auto MAX_PAYLOAD_SIZE_IN_MB = 1;
constexpr static auto MAX_PAYLOAD_SIZE_IN_BYTES = MAX_PAYLOAD_SIZE_IN_MB * (1024 * 1024);
/// Raw read aries massage.
struct RawAriesMessage {
AriesMessageHeader header;
std::vector<u8> tagPayload;
};
namespace errors {
struct TagPayloadTooLarge : std::exception {
TagPayloadTooLarge(u32 size)
: payloadSize(size) {
whatStr = std::format("Tag payload over {} MB (Max is {}MB).", (static_cast<u32>(payloadSize) / 1024 / 1024), MAX_PAYLOAD_SIZE_IN_MB);
}
const char* what() const noexcept override {
return whatStr.c_str();
}
private:
u32 payloadSize;
std::string whatStr;
};
} // namespace errors
/// Reads an Aries message from an Boost.Asio async read stream.
template <class AsyncReadStream>
base::Awaitable<RawAriesMessage> AsyncReadAriesMessage(AsyncReadStream& stream) {
RawAriesMessage res;
// Read the header first
co_await asio::async_read(stream, asio::buffer(&res.header, sizeof(res.header)), asio::deferred);
auto realPayloadSize = res.header.messageSize - sizeof(res.header);
// Read tag payload (if there is one)
if(res.header.messageSize != sizeof(res.header)) {
// Sanity check. I don't expect game payloads to ever reach this large, but who knows.
if(realPayloadSize > MAX_PAYLOAD_SIZE_IN_BYTES)
throw errors::TagPayloadTooLarge(realPayloadSize);
res.tagPayload.resize(realPayloadSize);
co_await asio::async_read(stream, asio::buffer(res.tagPayload), asio::deferred);
}
co_return res;
}
} // namespace ls::aries