forstio/source/forstio/io.h

197 lines
4.1 KiB
C
Raw Permalink Normal View History

2020-08-23 15:47:14 +02:00
#pragma once
#include "async.h"
2020-08-24 12:47:18 +02:00
#include "common.h"
#include "io_helpers.h"
2020-08-23 15:47:14 +02:00
2020-08-25 19:51:45 +02:00
#include <string>
#include <variant>
2020-08-25 19:51:45 +02:00
2021-12-29 19:26:22 +01:00
namespace saw {
/*
* Input stream
*/
2020-08-23 15:47:14 +02:00
class InputStream {
public:
virtual ~InputStream() = default;
2020-09-28 19:36:35 +02:00
2021-06-04 23:21:25 +02:00
virtual ErrorOr<size_t> read(void *buffer, size_t length) = 0;
2021-06-04 14:43:40 +02:00
2020-09-28 19:36:35 +02:00
virtual Conveyor<void> readReady() = 0;
virtual Conveyor<void> onReadDisconnected() = 0;
2020-08-23 15:47:14 +02:00
};
/*
* Output stream
*/
2020-08-23 15:47:14 +02:00
class OutputStream {
public:
virtual ~OutputStream() = default;
2020-09-28 19:36:35 +02:00
2021-06-04 23:21:25 +02:00
virtual ErrorOr<size_t> write(const void *buffer, size_t length) = 0;
2021-06-04 14:43:40 +02:00
2020-09-28 19:36:35 +02:00
virtual Conveyor<void> writeReady() = 0;
2020-08-23 15:47:14 +02:00
};
/*
* Io stream
*/
2020-08-23 15:47:14 +02:00
class IoStream : public InputStream, public OutputStream {
public:
virtual ~IoStream() = default;
};
2021-06-04 23:21:25 +02:00
class AsyncInputStream {
public:
virtual ~AsyncInputStream() = default;
virtual void read(void *buffer, size_t min_length, size_t max_length) = 0;
2021-06-04 23:21:25 +02:00
virtual Conveyor<size_t> readDone() = 0;
2021-06-20 13:28:59 +02:00
virtual Conveyor<void> onReadDisconnected() = 0;
2021-06-04 23:21:25 +02:00
};
class AsyncOutputStream {
public:
virtual ~AsyncOutputStream() = default;
virtual void write(const void *buffer, size_t length) = 0;
2021-06-04 23:21:25 +02:00
virtual Conveyor<size_t> writeDone() = 0;
};
2022-03-13 14:40:34 +01:00
class AsyncIoStream final : public AsyncInputStream, public AsyncOutputStream {
2021-06-04 23:21:25 +02:00
private:
Own<IoStream> stream;
SinkConveyor read_ready;
SinkConveyor write_ready;
SinkConveyor read_disconnected;
ReadTaskAndStepHelper read_stepper;
WriteTaskAndStepHelper write_stepper;
2021-06-04 23:21:25 +02:00
public:
AsyncIoStream(Own<IoStream> str);
2022-03-13 14:40:34 +01:00
SAW_FORBID_COPY(AsyncIoStream);
SAW_FORBID_MOVE(AsyncIoStream);
2022-01-08 10:46:57 +01:00
void read(void *buffer, size_t length, size_t max_length) override;
2021-06-04 23:21:25 +02:00
Conveyor<size_t> readDone() override;
2021-06-20 13:28:59 +02:00
Conveyor<void> onReadDisconnected() override;
void write(const void *buffer, size_t length) override;
2021-06-04 23:21:25 +02:00
Conveyor<size_t> writeDone() override;
};
2020-08-23 15:47:14 +02:00
class Server {
public:
virtual ~Server() = default;
2020-09-28 19:36:35 +02:00
virtual Conveyor<Own<IoStream>> accept() = 0;
2020-08-23 15:47:14 +02:00
};
class NetworkAddress;
2022-01-07 00:29:29 +01:00
/**
* 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
2022-01-07 00:29:29 +01:00
*/
class Datagram {
public:
virtual ~Datagram() = default;
2022-01-08 10:46:57 +01:00
virtual ErrorOr<size_t> read(void *buffer, size_t length) = 0;
virtual Conveyor<void> readReady() = 0;
2022-01-07 00:29:29 +01:00
2022-02-04 21:53:05 +01:00
virtual ErrorOr<size_t> write(const void *buffer, size_t length,
2022-01-08 10:46:57 +01:00
NetworkAddress &dest) = 0;
virtual Conveyor<void> writeReady() = 0;
2022-01-07 00:29:29 +01:00
};
class OsNetworkAddress;
class StringNetworkAddress;
2020-08-23 15:47:14 +02:00
class NetworkAddress {
public:
using ChildVariant =
std::variant<OsNetworkAddress *, StringNetworkAddress *>;
2020-08-23 15:47:14 +02:00
virtual ~NetworkAddress() = default;
virtual NetworkAddress::ChildVariant representation() = 0;
2022-01-07 00:29:29 +01:00
virtual const std::string &address() const = 0;
virtual uint16_t port() const = 0;
};
2020-08-25 19:51:45 +02:00
class OsNetworkAddress : public NetworkAddress {
public:
virtual ~OsNetworkAddress() = default;
2022-01-07 00:29:29 +01:00
NetworkAddress::ChildVariant representation() override { return this; }
};
2021-06-18 00:17:18 +02:00
class StringNetworkAddress final : public NetworkAddress {
private:
std::string address_value;
uint16_t port_value;
public:
StringNetworkAddress(const std::string &address, uint16_t port);
const std::string &address() const override;
uint16_t port() const override;
NetworkAddress::ChildVariant representation() override { return this; }
2020-08-23 15:47:14 +02:00
};
2020-11-11 23:08:37 +01:00
class Network {
2020-08-23 15:47:14 +02:00
public:
2020-11-11 23:08:37 +01:00
virtual ~Network() = default;
2020-08-23 15:47:14 +02:00
/**
* Parse the provided string and uint16 to the preferred storage method
*/
virtual Conveyor<Own<NetworkAddress>>
2021-05-09 15:19:09 +02:00
parseAddress(const std::string &addr, uint16_t port_hint = 0) = 0;
/**
* Set up a listener on this address
*/
virtual Own<Server> listen(NetworkAddress &bind_addr) = 0;
/**
* Connect to a remote address
*/
virtual Conveyor<Own<IoStream>> connect(NetworkAddress &address) = 0;
/**
* Bind a datagram socket at this address.
*/
virtual Own<Datagram> datagram(NetworkAddress &address) = 0;
2020-11-11 23:08:37 +01:00
};
2021-06-04 14:43:40 +02:00
class IoProvider {
2020-11-11 23:08:37 +01:00
public:
2021-06-04 14:43:40 +02:00
virtual ~IoProvider() = default;
2020-09-23 21:25:59 +02:00
virtual Own<InputStream> wrapInputFd(int fd) = 0;
2020-11-11 23:08:37 +01:00
virtual Network &network() = 0;
};
2020-08-23 15:47:14 +02:00
struct AsyncIoContext {
2021-06-04 14:43:40 +02:00
Own<IoProvider> io;
2021-02-16 18:21:52 +01:00
EventLoop &event_loop;
2020-08-25 19:51:45 +02:00
EventPort &event_port;
2020-08-23 15:47:14 +02:00
};
2021-03-13 22:22:01 +01:00
ErrorOr<AsyncIoContext> setupAsyncIo();
2021-12-29 19:26:22 +01:00
} // namespace saw