From d26da549cc354f95666b58c121c25ca0de42f359 Mon Sep 17 00:00:00 2001 From: Theis Pieter Hollebeek Date: Wed, 20 Nov 2024 13:04:55 +0100 Subject: [PATCH] this->sucks --- runtime/rpc_server.cpp | 80 +++++++++++++++++++++++++++++++++----- runtime/rpc_server.hpp | 66 +++++++++++++++++++++++++------ runtime/socket.cpp | 88 ------------------------------------------ runtime/socket.hpp | 55 -------------------------- 4 files changed, 126 insertions(+), 163 deletions(-) delete mode 100644 runtime/socket.cpp delete mode 100644 runtime/socket.hpp diff --git a/runtime/rpc_server.cpp b/runtime/rpc_server.cpp index 5ac9c8b..24b9a2b 100644 --- a/runtime/rpc_server.cpp +++ b/runtime/rpc_server.cpp @@ -1,15 +1,77 @@ #include "rpc_server.hpp" -#include "socket.hpp" +#include #include #include +#include -auto slige_rpc::RpcServer::bind( - uint16_t port) -> std::variant +auto create_address(uint16_t port) -> sockaddr_in { - std::variant socket_result - = slige_socket::Socket::bind(port); - if (std::holds_alternative(socket_result)) { - return std::get(socket_result); - } - return RpcServer(std::get(socket_result)); + return { + .sin_family = AF_INET, + .sin_port = htons(port), + .sin_addr = { .s_addr = inet_addr("127.0.0.1") }, + .sin_zero = { 0 }, + }; +} + +template +auto slige_rpc::RpcServer::listen() -> Res +{ + int socket_fd = ::socket(AF_INET, SOCK_STREAM, 0); + if (socket_fd < 0) { + return Err { "could not get socket" }; + }; + + sockaddr_in address = create_address(13370); + unsigned int address_size = sizeof(this->address); + + if (::bind(socket_fd, (struct sockaddr*)&address, sizeof(address)) < 0) { + return Err { "could not bind" }; + }; + + if (::listen(socket_fd, 0) < 0) { + return Err { "could not listen" }; + } + while (true) { + int client = ::accept( + this->fd, (struct sockaddr*)&this->address, &address_size); + if (client < 0) { + return Err { "could not accept" }; + } + uint8_t buffer[1024] = {}; + } + std::unreachable(); +} + +auto slige_rpc::BufferedWriter::write(std::string message) -> Res +{ + for (size_t i = 0; i < message.length(); ++i) { + auto res = this->write((uint8_t)message[i]); + if (!res.is_ok()) { + return res.err(); + } + } + return Unit {}; +} + +auto slige_rpc::BufferedWriter::write(uint8_t byte) -> Res +{ + if (this->occupied >= length) { + auto res = this->flush(); + if (!res.is_ok()) { + return res.err(); + } + } + this->buffer[this->occupied] = byte; + return Unit {}; +} + +auto slige_rpc::BufferedWriter::flush() -> Res +{ + auto result = ::write(this->fd, this->buffer, this->occupied); + if (result < 0) { + return { { "unable to write" } }; + } + this->occupied = 0; + return (size_t)result; } diff --git a/runtime/rpc_server.hpp b/runtime/rpc_server.hpp index 2ca718c..e06ceaf 100644 --- a/runtime/rpc_server.hpp +++ b/runtime/rpc_server.hpp @@ -1,15 +1,60 @@ #pragma once -#include "socket.hpp" #include -#include #include #include +#include #include -#include namespace slige_rpc { +struct Err { + std::string msg; +}; + +template class Res { +public: + Res(T value) + { + this->value = value; + this->holds_value = true; + } + Res(Err error) + { + this->error = error; + this->holds_value = false; + } + auto is_ok() -> bool { return this->holds_value; } + auto ok() -> T { return this->value; } + auto err() -> Err { return this->error; } + +private: + bool holds_value; + T value; + Err error; +}; + +struct Unit { }; +struct Req { }; + +class BufferedWriter { + BufferedWriter(int fd) + : fd(fd) + { + } + ~BufferedWriter() { close(fd); } + + auto flush() -> Res; + auto write(uint8_t byte) -> Res; + auto write(std::string message) -> Res; + +private: + static const size_t length = 1024; + size_t occupied = 0; + uint8_t buffer[length]; + int fd; +}; + /// - load code /// - program input /// - run @@ -22,16 +67,15 @@ namespace slige_rpc { /// - json string /// - fetch stack /// - json string -class RpcServer { +template class RpcServer { public: - auto static bind(uint16_t port) - -> std::variant; + RpcServer(Functor functor) + : functor(functor) {}; + + auto listen() -> Res; private: - RpcServer(slige_socket::ServerSocket socket) - : socket(socket) - { - } - slige_socket::ServerSocket socket; + Functor functor; }; + }; diff --git a/runtime/socket.cpp b/runtime/socket.cpp deleted file mode 100644 index 556ecb7..0000000 --- a/runtime/socket.cpp +++ /dev/null @@ -1,88 +0,0 @@ -#include "socket.hpp" -#include -#include - -auto slige_socket::ClientSocket::read( - uint8_t* buffer, size_t length) -> std::variant -{ - ssize_t bytes_read = recv(this->fd, buffer, length, 0); - if (bytes_read < 0) { - return Ewwow { .message = "unable to read" }; - } - return (size_t)bytes_read; -}; - -auto slige_socket::ClientSocket::write( - uint8_t* buffer, size_t length) -> std::variant -{ - ssize_t bytes_written = send(this->fd, buffer, length, 0); - if (bytes_written < 0) { - return Ewwow { .message = "unable to write" }; - } - return (size_t)bytes_written; -}; - -auto slige_socket::Socket::connect( - uint16_t port) -> std::variant -{ - auto address = Socket::create_address(port); - int socket_fd; - if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - return { Ewwow { .message = "could not get socket" } }; - } - // TODO: - // 1) does address (presumably 'socket) - // live as long as child socket ('client)? - // - immediate answer is no - // 2) does it need to? - if (::connect(socket_fd, (struct sockaddr*)&address, sizeof(address)) < 0) { - return { Ewwow { - .message = "could not connect, is the server running?" } }; - } - return { ClientSocket(socket_fd) }; -} - -auto slige_socket::ServerSocket::accept() - -> std::variant -{ - unsigned int address_size = sizeof(this->address); - // TODO: - // 1) does address (presumably 'server) - // live as long as child socket ('socket)? - // - immediate answer is no - // 2) does it need to? - int client - = ::accept(this->fd, (struct sockaddr*)&this->address, &address_size); - if (client < 0) { - return Ewwow { .message = "could not accept" }; - } - return { ClientSocket(client) }; -} - -auto slige_socket::Socket::bind( - uint16_t port) -> std::variant -{ - sockaddr_in address = Socket::create_address(port); - - int socket_fd; - if ((socket_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - return { Ewwow { .message = "could not get socket" } }; - } - // TODO: - // 1) does address (presumably 'socket) - // live as long as child socket ('server)? - // - immediate answer is no - // 2) does it need to? - if (::bind(socket_fd, (struct sockaddr*)&address, sizeof(address)) < 0) { - return { Ewwow { .message = "could not bind" } }; - } - - if (::listen(socket_fd, 0) < 0) { - return { Ewwow { .message = "could not listen" } }; - } - // TODO: - // 1) does this address get moved, copied or cloned? - // it should be represented as a u32, - // so copying should be fine - but does it? - return { ServerSocket(socket_fd, address) }; -} diff --git a/runtime/socket.hpp b/runtime/socket.hpp deleted file mode 100644 index f8c06fc..0000000 --- a/runtime/socket.hpp +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -namespace slige_socket { - -struct Ewwow { - std::string message; -}; - -class ClientSocket { -public: - ClientSocket(int fd) - : fd(fd) - { - } - ~ClientSocket() { close(fd); }; - auto read(uint8_t* buffer, size_t length) -> std::variant; - auto write(uint8_t* buffer, size_t length) -> std::variant; - -private: - int fd; -}; - -class ServerSocket { -public: - ServerSocket(int fd, sockaddr_in address) - : fd(fd) - , address(address) - { - } - ~ServerSocket() { close(fd); }; - auto accept() -> std::variant; - -private: - int fd; - sockaddr_in address; -}; - -class Socket { -public: - auto static connect(uint16_t port) -> std::variant; - auto static bind(uint16_t port) -> std::variant; - -private: - auto static create_address(uint16_t port) -> sockaddr_in; -}; - -};