mirror of
				https://git.sfja.dk/Mikkel/slige.git
				synced 2025-10-29 04:18:30 +00:00 
			
		
		
		
	this->sucks
This commit is contained in:
		
							parent
							
								
									f96d4849f6
								
							
						
					
					
						commit
						d26da549cc
					
				| @ -1,15 +1,77 @@ | ||||
| #include "rpc_server.hpp" | ||||
| #include "socket.hpp" | ||||
| #include <netinet/in.h> | ||||
| #include <sys/socket.h> | ||||
| #include <unistd.h> | ||||
| #include <utility> | ||||
| 
 | ||||
| auto slige_rpc::RpcServer::bind( | ||||
|     uint16_t port) -> std::variant<slige_rpc::RpcServer, slige_socket::Ewwow> | ||||
| auto create_address(uint16_t port) -> sockaddr_in | ||||
| { | ||||
|     std::variant<slige_socket::ServerSocket, slige_socket::Ewwow> socket_result | ||||
|         = slige_socket::Socket::bind(port); | ||||
|     if (std::holds_alternative<slige_socket::Ewwow>(socket_result)) { | ||||
|         return std::get<slige_socket::Ewwow>(socket_result); | ||||
|     } | ||||
|     return RpcServer(std::get<slige_socket::ServerSocket>(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 <typename Functor> | ||||
| auto slige_rpc::RpcServer<Functor>::listen() -> Res<Unit> | ||||
| { | ||||
|     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<Unit> | ||||
| { | ||||
|     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<Unit> | ||||
| { | ||||
|     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<size_t> | ||||
| { | ||||
|     auto result = ::write(this->fd, this->buffer, this->occupied); | ||||
|     if (result < 0) { | ||||
|         return { { "unable to write" } }; | ||||
|     } | ||||
|     this->occupied = 0; | ||||
|     return (size_t)result; | ||||
| } | ||||
|  | ||||
| @ -1,15 +1,60 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include "socket.hpp" | ||||
| #include <arpa/inet.h> | ||||
| #include <cstdint> | ||||
| #include <netdb.h> | ||||
| #include <stdlib.h> | ||||
| #include <string> | ||||
| #include <unistd.h> | ||||
| #include <variant> | ||||
| 
 | ||||
| namespace slige_rpc { | ||||
| 
 | ||||
| struct Err { | ||||
|     std::string msg; | ||||
| }; | ||||
| 
 | ||||
| template <typename T> 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<size_t>; | ||||
|     auto write(uint8_t byte) -> Res<Unit>; | ||||
|     auto write(std::string message) -> Res<Unit>; | ||||
| 
 | ||||
| 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 <typename Functor> class RpcServer { | ||||
| public: | ||||
|     auto static bind(uint16_t port) | ||||
|         -> std::variant<slige_rpc::RpcServer, slige_socket::Ewwow>; | ||||
|     RpcServer(Functor functor) | ||||
|         : functor(functor) {}; | ||||
| 
 | ||||
|     auto listen() -> Res<Unit>; | ||||
| 
 | ||||
| private: | ||||
|     RpcServer(slige_socket::ServerSocket socket) | ||||
|         : socket(socket) | ||||
|     { | ||||
|     } | ||||
|     slige_socket::ServerSocket socket; | ||||
|     Functor functor; | ||||
| }; | ||||
| 
 | ||||
| }; | ||||
|  | ||||
| @ -1,88 +0,0 @@ | ||||
| #include "socket.hpp" | ||||
| #include <sys/socket.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| auto slige_socket::ClientSocket::read( | ||||
|     uint8_t* buffer, size_t length) -> std::variant<size_t, slige_socket::Ewwow> | ||||
| { | ||||
|     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<size_t, slige_socket::Ewwow> | ||||
| { | ||||
|     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<ClientSocket, slige_socket::Ewwow> | ||||
| { | ||||
|     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<ClientSocket, slige_socket::Ewwow> | ||||
| { | ||||
|     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<ServerSocket, slige_socket::Ewwow> | ||||
| { | ||||
|     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) }; | ||||
| } | ||||
| @ -1,55 +0,0 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include <arpa/inet.h> | ||||
| #include <cstdint> | ||||
| #include <netdb.h> | ||||
| #include <stdlib.h> | ||||
| #include <string> | ||||
| #include <unistd.h> | ||||
| #include <variant> | ||||
| 
 | ||||
| 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<size_t, Ewwow>; | ||||
|     auto write(uint8_t* buffer, size_t length) -> std::variant<size_t, Ewwow>; | ||||
| 
 | ||||
| private: | ||||
|     int fd; | ||||
| }; | ||||
| 
 | ||||
| class ServerSocket { | ||||
| public: | ||||
|     ServerSocket(int fd, sockaddr_in address) | ||||
|         : fd(fd) | ||||
|         , address(address) | ||||
|     { | ||||
|     } | ||||
|     ~ServerSocket() { close(fd); }; | ||||
|     auto accept() -> std::variant<ClientSocket, Ewwow>; | ||||
| 
 | ||||
| private: | ||||
|     int fd; | ||||
|     sockaddr_in address; | ||||
| }; | ||||
| 
 | ||||
| class Socket { | ||||
| public: | ||||
|     auto static connect(uint16_t port) -> std::variant<ClientSocket, Ewwow>; | ||||
|     auto static bind(uint16_t port) -> std::variant<ServerSocket, Ewwow>; | ||||
| 
 | ||||
| private: | ||||
|     auto static create_address(uint16_t port) -> sockaddr_in; | ||||
| }; | ||||
| 
 | ||||
| }; | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user