| 42 | static std::unique_ptr<DuplexPipe> MakeAsPtr(const std::string& name, as::io_context& ioctx, const std::string& security = {}); |
| 43 | template<class H, class P> |
| 44 | as::awaitable<void> WritePacket(const H& header, const P& payload, std::optional<uint32_t> timeoutMs = {}) |
| 45 | { |
| 46 | // lock while this coro is running to prevent other coros from causing an overlapped operation fault |
| 47 | auto lk = co_await CoroLock(writeMtx_); |
| 48 | // some sanity checks |
| 49 | assert(writeBuf_.size() == 0); |
| 50 | assert(asioPipeHandle_.is_open()); |
| 51 | // first we directly write bytes for the size of the body as a placeholder until we know how many are serialized |
| 52 | const uint32_t placeholderSize = 'TEMP'; |
| 53 | writeStream_.write(reinterpret_cast<const char*>(&placeholderSize), sizeof(placeholderSize)); |
| 54 | // record how many bytes used for the serialization of the size |
| 55 | const auto sizeSize = writeBuf_.size(); |
| 56 | // serialize the packet body |
| 57 | writeArchive_(header, payload); |
| 58 | // calculate size of body |
| 59 | const auto payloadSize = uint32_t(writeBuf_.size() - sizeSize); |
| 60 | // replace the placeholder with the actual body size |
| 61 | const auto pSizeInPlace = const_cast<char*>(&*as::buffers_begin(writeBuf_.data())); |
| 62 | auto replacement = std::string_view{ reinterpret_cast<const char*>(&payloadSize), sizeof(payloadSize) }; |
| 63 | std::ranges::copy(replacement, pSizeInPlace); |
| 64 | // transmit the packet |
| 65 | co_await Write_(timeoutMs); |
| 66 | } |
| 67 | template<class H> |
| 68 | as::awaitable<H> ReadPacketConsumeHeader(std::optional<uint32_t> timeoutMs = {}) |
| 69 | { |
no test coverage detected