mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-27 02:01:42 +00:00
154 lines
4.5 KiB
C++
154 lines
4.5 KiB
C++
// Copyright (c) FIRST and other WPILib contributors.
|
|
// Open Source Software; you can modify and/or share it under the terms of
|
|
// the WPILib BSD license file in the root directory of this project.
|
|
|
|
#ifndef WPIUTIL_WPI_UV_NETWORKSTREAM_H_
|
|
#define WPIUTIL_WPI_UV_NETWORKSTREAM_H_
|
|
|
|
#include <uv.h>
|
|
|
|
#include <cstdlib>
|
|
#include <functional>
|
|
#include <memory>
|
|
|
|
#include "wpi/Signal.h"
|
|
#include "wpi/uv/Stream.h"
|
|
|
|
namespace wpi::uv {
|
|
|
|
class NetworkStream;
|
|
|
|
/**
|
|
* Connection request.
|
|
*/
|
|
class ConnectReq : public RequestImpl<ConnectReq, uv_connect_t> {
|
|
public:
|
|
ConnectReq();
|
|
|
|
NetworkStream& GetStream() const {
|
|
return *static_cast<NetworkStream*>(GetRaw()->handle->data);
|
|
}
|
|
|
|
/**
|
|
* Connection completed signal.
|
|
*/
|
|
sig::Signal<> connected;
|
|
};
|
|
|
|
/**
|
|
* Network stream handle.
|
|
* This is an abstract type; there are two network stream implementations (Tcp
|
|
* and Pipe).
|
|
*/
|
|
class NetworkStream : public Stream {
|
|
public:
|
|
static constexpr int kDefaultBacklog = 128;
|
|
|
|
std::shared_ptr<NetworkStream> shared_from_this() {
|
|
return std::static_pointer_cast<NetworkStream>(Handle::shared_from_this());
|
|
}
|
|
|
|
std::shared_ptr<const NetworkStream> shared_from_this() const {
|
|
return std::static_pointer_cast<const NetworkStream>(
|
|
Handle::shared_from_this());
|
|
}
|
|
|
|
/**
|
|
* Start listening for incoming connections. When a new incoming connection
|
|
* is received the connection signal is generated.
|
|
* @param backlog the number of connections the kernel might queue, same as
|
|
* listen(2).
|
|
*/
|
|
void Listen(int backlog = kDefaultBacklog);
|
|
|
|
/**
|
|
* Start listening for incoming connections. This is a convenience wrapper
|
|
* around `Listen(int)` that also connects a callback to the connection
|
|
* signal. When a new incoming connection is received the connection signal
|
|
* is generated (and the callback is called).
|
|
* @param callback the callback to call when a connection is received.
|
|
* `Accept()` should be called from this callback.
|
|
* @param backlog the number of connections the kernel might queue, same as
|
|
* listen(2).
|
|
*/
|
|
void Listen(std::function<void()> callback, int backlog = kDefaultBacklog);
|
|
|
|
/**
|
|
* Accept incoming connection.
|
|
*
|
|
* This call is used in conjunction with `Listen()` to accept incoming
|
|
* connections. Call this function after receiving a ListenEvent event to
|
|
* accept the connection.
|
|
* An error signal will be emitted in case of errors.
|
|
*
|
|
* When the connection signal is emitted it is guaranteed that this
|
|
* function will complete successfully the first time. If you attempt to use
|
|
* it more than once, it may fail.
|
|
* It is suggested to only call this function once per connection signal.
|
|
*
|
|
* @return The stream handle for the accepted connection, or nullptr on error.
|
|
*/
|
|
std::shared_ptr<NetworkStream> Accept() {
|
|
return DoAccept()->shared_from_this();
|
|
}
|
|
|
|
/**
|
|
* Accept incoming connection.
|
|
*
|
|
* This call is used in conjunction with `Listen()` to accept incoming
|
|
* connections. Call this function after receiving a connection signal to
|
|
* accept the connection.
|
|
* An error signal will be emitted in case of errors.
|
|
*
|
|
* When the connection signal is emitted it is guaranteed that this
|
|
* function will complete successfully the first time. If you attempt to use
|
|
* it more than once, it may fail.
|
|
* It is suggested to only call this function once per connection signal.
|
|
*
|
|
* @param client Client stream object.
|
|
* @return False on error.
|
|
*/
|
|
bool Accept(const std::shared_ptr<NetworkStream>& client) {
|
|
return Invoke(&uv_accept, GetRawStream(), client->GetRawStream());
|
|
}
|
|
|
|
/**
|
|
* Signal generated when an incoming connection is received.
|
|
*/
|
|
sig::Signal<> connection;
|
|
|
|
protected:
|
|
explicit NetworkStream(uv_stream_t* uv_stream) : Stream{uv_stream} {}
|
|
|
|
virtual NetworkStream* DoAccept() = 0;
|
|
};
|
|
|
|
template <typename T, typename U>
|
|
class NetworkStreamImpl : public NetworkStream {
|
|
public:
|
|
std::shared_ptr<T> shared_from_this() {
|
|
return std::static_pointer_cast<T>(Handle::shared_from_this());
|
|
}
|
|
|
|
std::shared_ptr<const T> shared_from_this() const {
|
|
return std::static_pointer_cast<const T>(Handle::shared_from_this());
|
|
}
|
|
|
|
/**
|
|
* Get the underlying handle data structure.
|
|
*
|
|
* @return The underlying handle data structure.
|
|
*/
|
|
U* GetRaw() const noexcept {
|
|
return reinterpret_cast<U*>(this->GetRawHandle());
|
|
}
|
|
|
|
protected:
|
|
NetworkStreamImpl()
|
|
: NetworkStream{static_cast<uv_stream_t*>(std::malloc(sizeof(U)))} {}
|
|
};
|
|
|
|
} // namespace wpi::uv
|
|
|
|
#endif // WPIUTIL_WPI_UV_NETWORKSTREAM_H_
|