#include "rpc_server.hpp" extern "C" { #include #include #include #include #include #include #include #include } using namespace sliger::rpc; static auto create_address(uint16_t port) -> sockaddr_in { return { .sin_family = AF_INET, .sin_port = ::htons(port), .sin_addr = { .s_addr = ::inet_addr("127.0.0.1") }, .sin_zero = { 0 }, }; } auto Socket::init() -> Res { this->socket_fd = ::socket(AF_INET, SOCK_STREAM, 0); if (socket_fd < 0) { return Err { .msg = std::format("could not get socket ({})", socket_fd) }; }; this->initialized = true; int trueValue = 1; ::setsockopt( this->socket_fd, SOL_SOCKET, SO_REUSEADDR, &trueValue, sizeof(int)); int err; auto address = create_address(13370); err = ::bind(socket_fd, (struct sockaddr*)&address, sizeof(address)); if (err < 0) { return Err { .msg = std::format("could not bind ({})", err) }; }; err = ::listen(socket_fd, 0); if (err < 0) { return Err { .msg = std::format("could not listen ({})", err) }; } return {}; } auto Socket::accept() -> Res> { auto client_address = create_address(13370); socklen_t address_size = sizeof(client_address); int client = ::accept(socket_fd, (struct sockaddr*)&client_address, &address_size); if (client < 0) { return Err { .msg = std::format("could not accept ({})", client) }; } return std::make_unique(client); } auto Client::read(int8_t* buffer, size_t buffer_size) -> ssize_t { return ::read(this->client_sock, buffer, buffer_size); } auto Client::write(uint8_t* buffer, size_t buffer_size) -> ssize_t { return ::write(this->client_sock, buffer, buffer_size); } auto BufferedWriter::write(std::string message) -> Res { for (auto ch : message) { if (auto res = this->write((uint8_t)ch); !res.is_ok()) { return res.err(); } } return {}; } auto BufferedWriter::write(uint8_t byte) -> Res { if (this->occupied >= length) { if (auto res = this->flush(); !res.is_ok()) { return res.err(); } } this->buffer[this->occupied] = byte; this->occupied += 1; return {}; } auto BufferedWriter::flush() -> Res { auto result = this->client->write(this->buffer, this->occupied); if (result < 0) { return Err("unable to write"); } this->occupied = 0; return (size_t)result; }