diff options
author | Claudius Holeksa <mail@keldu.de> | 2023-04-29 18:44:59 +0200 |
---|---|---|
committer | Claudius Holeksa <mail@keldu.de> | 2023-04-29 18:44:59 +0200 |
commit | f07487ce8f0f3ebd5c4d1082a9521f09588fa34a (patch) | |
tree | 5cccd5e20d180cbe128dd0ae7759b50d26199af4 /forstio/io/io.h | |
parent | 47c44aab6cf54e4885de4138cab1aa3825f115e4 (diff) |
Added io to new repo
Diffstat (limited to 'forstio/io/io.h')
-rw-r--r-- | forstio/io/io.h | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/forstio/io/io.h b/forstio/io/io.h new file mode 100644 index 0000000..4a87da5 --- /dev/null +++ b/forstio/io/io.h @@ -0,0 +1,205 @@ +#pragma once + +#include <forstio/async/async.h> +#include <forstio/core/common.h> +#include "io_helpers.h" + +#include <string> +#include <variant> + +namespace saw { +/* + * 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 &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 |