diff --git a/nixd/librpc/include/nixd/rpc/IO.h b/nixd/librpc/include/nixd/rpc/IO.h index 7bbf7caac..64d0e04d6 100644 --- a/nixd/librpc/include/nixd/rpc/IO.h +++ b/nixd/librpc/include/nixd/rpc/IO.h @@ -1,12 +1,12 @@ #pragma once -#include -#include +#include + +#include namespace nixd::rpc { /// \brief Read N bytes from FD into Buf, block until N bytes are read. -/// \returns the number of bytes read, or -1 on error. (errno is set) -long readBytes(int FD, void *Buf, std::size_t N); +size_t readBytes(int FD, void *Buf, std::size_t N); } // namespace nixd::rpc diff --git a/nixd/librpc/include/nixd/rpc/Transport.h b/nixd/librpc/include/nixd/rpc/Transport.h index 673f7cf95..11718ee14 100644 --- a/nixd/librpc/include/nixd/rpc/Transport.h +++ b/nixd/librpc/include/nixd/rpc/Transport.h @@ -1,5 +1,7 @@ #pragma once +#include "nixd/rpc/Protocol.h" + #include #include @@ -10,9 +12,26 @@ class Transport { int OutboundFD; protected: - [[nodiscard]] int send(std::string_view Msg) const; + /// \brief Wraps a message with it's length, and then send it. + void send(std::string_view Msg) const; + + /// \brief Read a message and then forms a packet. + [[nodiscard]] std::vector recv() const; + + template T recvPacket() const { + std::vector Buf = recv(); + T Data; + std::string_view D = {Buf.begin(), Buf.end()}; + readBytecode(D, Data); + return Data; + } + + template void sendPacket(const T &Data) { + auto Str = bc::toBytecode(Data); + send(Str); + } - [[nodiscard]] virtual int handleInbound(const std::vector &Buf) = 0; + virtual void handleInbound(const std::vector &Buf) = 0; public: [[nodiscard]] int run(); diff --git a/nixd/librpc/src/IO.cpp b/nixd/librpc/src/IO.cpp index 3a8b4aeee..cab72c309 100644 --- a/nixd/librpc/src/IO.cpp +++ b/nixd/librpc/src/IO.cpp @@ -1,18 +1,20 @@ #include "nixd/rpc/IO.h" +#include + #include namespace nixd::rpc { -long readBytes(int FD, void *Buf, std::size_t N) { - std::size_t Read = 0; +size_t readBytes(int FD, void *Buf, std::size_t N) { + size_t Read = 0; while (Read < N) { - auto BytesRead = read(FD, static_cast(Buf) + Read, N - Read); + size_t BytesRead = read(FD, static_cast(Buf) + Read, N - Read); if (BytesRead <= 0) - return BytesRead; + throw std::system_error(std::make_error_code(std::errc(errno))); Read += BytesRead; } - return static_cast(Read); + return Read; } } // namespace nixd::rpc diff --git a/nixd/librpc/src/Transport.cpp b/nixd/librpc/src/Transport.cpp index 5cffef9e7..1515c7760 100644 --- a/nixd/librpc/src/Transport.cpp +++ b/nixd/librpc/src/Transport.cpp @@ -1,36 +1,37 @@ #include "nixd/rpc/Transport.h" #include "nixd/rpc/IO.h" -#include +#include #include +#include + namespace nixd::rpc { using MessageSizeT = std::size_t; -int Transport::send(std::string_view Msg) const { +void Transport::send(std::string_view Msg) const { MessageSizeT Size = Msg.size(); if (write(OutboundFD, &Size, sizeof(MessageSizeT)) < 0) - return -1; + throw std::system_error(std::make_error_code(std::errc(errno))); if (write(OutboundFD, Msg.data(), Msg.size()) < 0) - return -1; - return 0; + throw std::system_error(std::make_error_code(std::errc(errno))); +} + +std::vector Transport::recv() const { + MessageSizeT Size; + readBytes(InboundFD, &Size, sizeof(Size)); + + // Collect a message + std::vector Buf(Size); + readBytes(InboundFD, Buf.data(), Size); + return Buf; } int Transport::run() { for (;;) { - MessageSizeT Size; - if (readBytes(InboundFD, &Size, sizeof(Size)) <= 0) { - // Handle error - } - - // Then read the message - // Collect a message - std::vector Buf(Size); - if (readBytes(InboundFD, Buf.data(), Size) <= 0) - return -1; - if (handleInbound(Buf) != 0) - return -1; + std::vector Buf = recv(); + handleInbound(Buf); } return 0; }