diff options
author | Claudius "keldu" Holeksa <mail@keldu.de> | 2024-01-23 13:12:11 +0100 |
---|---|---|
committer | Claudius "keldu" Holeksa <mail@keldu.de> | 2024-01-23 13:12:11 +0100 |
commit | 8dad985328e2183b224300aa992951131956fdb3 (patch) | |
tree | ceda3d9805335f36f571fb36585444ebdb421a02 /modules/io/io.hpp | |
parent | a9d2025030d0a7641f4b0701bd4aff7d2db5aeb4 (diff) |
core,codec-json,codec-minecraft,codec-netcdf,codec,io-tls,io,io_codec,window,window-opengl:
Renamed file endings and changed includes
Diffstat (limited to 'modules/io/io.hpp')
-rw-r--r-- | modules/io/io.hpp | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/modules/io/io.hpp b/modules/io/io.hpp new file mode 100644 index 0000000..e2022be --- /dev/null +++ b/modules/io/io.hpp @@ -0,0 +1,219 @@ +#pragma once + +#include <forstio/async/async.h> +#include <forstio/common.h> +#include "io_helpers.hpp + +#include <string> +#include <variant> + +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<size_t> read(void *buffer, size_t length) = 0; + + virtual conveyor<void> read_ready() = 0; + + virtual conveyor<void> on_read_disconnected() = 0; +}; + +/* + * Output stream + */ +class output_stream { +public: + virtual ~output_stream() = default; + + virtual error_or<size_t> write(const void *buffer, size_t length) = 0; + + virtual conveyor<void> 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<size_t> read_done() = 0; + virtual conveyor<void> 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<size_t> write_done() = 0; +}; + +class async_io_stream final : public async_input_stream, + public async_output_stream { +private: + own<io_stream> 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<io_stream> 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<size_t> read_done() override; + + conveyor<void> on_read_disconnected() override; + + void write(const void *buffer, size_t length) override; + + conveyor<size_t> write_done() override; +}; + +class server { +public: + virtual ~server() = default; + + virtual conveyor<own<io_stream>> 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<size_t> read(void *buffer, size_t length) = 0; + virtual conveyor<void> read_ready() = 0; + + virtual error_or<size_t> write(const void *buffer, size_t length, + network_address &dest) = 0; + virtual conveyor<void> write_ready() = 0; +}; + +class os_network_address; +class string_network_address; + +class network_address { +public: + using child_variant = + std::variant<os_network_address *, string_network_address *>; + + 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<own<network_address>> + 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<NetworkAddress> parseAddress(const std::string& addr, + // uint16_t port_hint = 0) = 0; + + /** + * Set up a listener on this address + */ + virtual own<server> listen(network_address &bind_addr) = 0; + + /** + * Connect to a remote address + */ + virtual conveyor<own<io_stream>> connect(network_address &address) = 0; + + /** + * Bind a datagram socket at this address. + */ + virtual own<datagram> datagram(network_address &address) = 0; +}; + +class io_provider { +public: + virtual ~io_provider() = default; + + virtual own<input_stream> wrap_input_fd(int fd) = 0; + + virtual network &get_network() = 0; +}; + +struct async_io_context { + own<io_provider> io; + event_loop &event_loop; + event_port &event_port; +}; + +error_or<async_io_context> setup_async_io(); +} // namespace saw |