From fac9e8bec1983fa9dff8f447fef106e427dfec26 Mon Sep 17 00:00:00 2001 From: "Claudius \"keldu\" Holeksa" Date: Thu, 20 Jul 2023 17:02:05 +0200 Subject: c++: Renamed src to c++ --- c++/io/io.h | 219 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 219 insertions(+) create mode 100644 c++/io/io.h (limited to 'c++/io/io.h') diff --git a/c++/io/io.h b/c++/io/io.h new file mode 100644 index 0000000..7653ace --- /dev/null +++ b/c++/io/io.h @@ -0,0 +1,219 @@ +#pragma once + +#include +#include +#include "io_helpers.h" + +#include +#include + +namespace saw { +/** + * Set of error common in io + */ +namespace err { +struct disconnected { + static constexpr std::string_view description = "Disconnected"; + static constexpr bool is_critical = true; +}; + +struct resource_busy { + static constexpr std::string_view description = "Resource busy"; + static constexpr bool is_critical = false; +}; +} +/* + * Input stream + */ +class input_stream { +public: + virtual ~input_stream() = default; + + virtual error_or read(void *buffer, size_t length) = 0; + + virtual conveyor read_ready() = 0; + + virtual conveyor on_read_disconnected() = 0; +}; + +/* + * Output stream + */ +class output_stream { +public: + virtual ~output_stream() = default; + + virtual error_or write(const void *buffer, size_t length) = 0; + + virtual conveyor write_ready() = 0; +}; + +/* + * Io stream + */ +class io_stream : public input_stream, public output_stream { +public: + virtual ~io_stream() = default; +}; + +class async_input_stream { +public: + virtual ~async_input_stream() = default; + + virtual void read(void *buffer, size_t min_length, size_t max_length) = 0; + + virtual conveyor read_done() = 0; + virtual conveyor on_read_disconnected() = 0; +}; + +class async_output_stream { +public: + virtual ~async_output_stream() = default; + + virtual void write(const void *buffer, size_t length) = 0; + + virtual conveyor write_done() = 0; +}; + +class async_io_stream final : public async_input_stream, + public async_output_stream { +private: + own stream_; + + conveyor_sink read_ready_; + conveyor_sink write_ready_; + conveyor_sink read_disconnected_; + + read_task_and_step_helper read_stepper_; + write_task_and_step_helper write_stepper_; + +public: + async_io_stream(own str); + + SAW_FORBID_COPY(async_io_stream); + SAW_FORBID_MOVE(async_io_stream); + + void read(void *buffer, size_t length, size_t max_length) override; + + conveyor read_done() override; + + conveyor on_read_disconnected() override; + + void write(const void *buffer, size_t length) override; + + conveyor write_done() override; +}; + +class server { +public: + virtual ~server() = default; + + virtual conveyor> accept() = 0; +}; + +class network_address; +/** + * Datagram class. Bound to a local address it is able to receive inbound + * datagram messages and send them as well as long as an address is provided as + * well + */ +class datagram { +public: + virtual ~datagram() = default; + + virtual error_or read(void *buffer, size_t length) = 0; + virtual conveyor read_ready() = 0; + + virtual error_or write(const void *buffer, size_t length, + network_address &dest) = 0; + virtual conveyor write_ready() = 0; +}; + +class os_network_address; +class string_network_address; + +class network_address { +public: + using child_variant = + std::variant; + + virtual ~network_address() = default; + + virtual network_address::child_variant representation() = 0; + + virtual const std::string &address() const = 0; + virtual uint16_t port() const = 0; +}; + +class os_network_address : public network_address { +public: + virtual ~os_network_address() = default; + + network_address::child_variant representation() override { return this; } +}; + +class string_network_address final : public network_address { +private: + std::string address_value_; + uint16_t port_value_; + +public: + string_network_address(const std::string &address, uint16_t port); + + const std::string &address() const override; + uint16_t port() const override; + + network_address::child_variant representation() override { return this; } +}; + +class network { +public: + virtual ~network() = default; + + /** + * Resolve the provided string and uint16 to the preferred storage method + */ + virtual conveyor> + resolve_address(const std::string &addr, uint16_t port_hint = 0) = 0; + + /** + * Parse the provided string and uint16 to the preferred storage method + * Since no dns request is made here, no async conveyors have to be used. + */ + /// @todo implement + // virtual Own parseAddress(const std::string& addr, + // uint16_t port_hint = 0) = 0; + + /** + * Set up a listener on this address + */ + virtual own listen(network_address &bind_addr) = 0; + + /** + * Connect to a remote address + */ + virtual conveyor> connect(network_address &address) = 0; + + /** + * Bind a datagram socket at this address. + */ + virtual own datagram(network_address &address) = 0; +}; + +class io_provider { +public: + virtual ~io_provider() = default; + + virtual own wrap_input_fd(int fd) = 0; + + virtual network &get_network() = 0; +}; + +struct async_io_context { + own io; + event_loop &event_loop; + event_port &event_port; +}; + +error_or setup_async_io(); +} // namespace saw -- cgit v1.2.3