WPILibC++ 2023.4.3
NetworkStream.h
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#ifndef WPINET_UV_NETWORKSTREAM_H_
6#define WPINET_UV_NETWORKSTREAM_H_
7
8#include <uv.h>
9
10#include <cstdlib>
11#include <functional>
12#include <memory>
13
14#include <wpi/Signal.h>
15
16#include "wpinet/uv/Stream.h"
17
18namespace wpi::uv {
19
20class NetworkStream;
21
22/**
23 * Connection request.
24 */
25class ConnectReq : public RequestImpl<ConnectReq, uv_connect_t> {
26 public:
28
30 return *static_cast<NetworkStream*>(GetRaw()->handle->data);
31 }
32
33 /**
34 * Connection completed signal.
35 */
37};
38
39/**
40 * Network stream handle.
41 * This is an abstract type; there are two network stream implementations (Tcp
42 * and Pipe).
43 */
44class NetworkStream : public Stream {
45 public:
46 static constexpr int kDefaultBacklog = 128;
47
48 std::shared_ptr<NetworkStream> shared_from_this() {
49 return std::static_pointer_cast<NetworkStream>(Handle::shared_from_this());
50 }
51
52 std::shared_ptr<const NetworkStream> shared_from_this() const {
53 return std::static_pointer_cast<const NetworkStream>(
54 Handle::shared_from_this());
55 }
56
57 /**
58 * Start listening for incoming connections. When a new incoming connection
59 * is received the connection signal is generated.
60 * @param backlog the number of connections the kernel might queue, same as
61 * listen(2).
62 */
63 void Listen(int backlog = kDefaultBacklog);
64
65 /**
66 * Start listening for incoming connections. This is a convenience wrapper
67 * around `Listen(int)` that also connects a callback to the connection
68 * signal. When a new incoming connection is received the connection signal
69 * is generated (and the callback is called).
70 * @param callback the callback to call when a connection is received.
71 * `Accept()` should be called from this callback.
72 * @param backlog the number of connections the kernel might queue, same as
73 * listen(2).
74 */
75 void Listen(std::function<void()> callback, int backlog = kDefaultBacklog);
76
77 /**
78 * Accept incoming connection.
79 *
80 * This call is used in conjunction with `Listen()` to accept incoming
81 * connections. Call this function after receiving a ListenEvent event to
82 * accept the connection.
83 * An error signal will be emitted in case of errors.
84 *
85 * When the connection signal is emitted it is guaranteed that this
86 * function will complete successfully the first time. If you attempt to use
87 * it more than once, it may fail.
88 * It is suggested to only call this function once per connection signal.
89 *
90 * @return The stream handle for the accepted connection, or nullptr on error.
91 */
92 std::shared_ptr<NetworkStream> Accept() {
93 return DoAccept()->shared_from_this();
94 }
95
96 /**
97 * Accept incoming connection.
98 *
99 * This call is used in conjunction with `Listen()` to accept incoming
100 * connections. Call this function after receiving a connection signal to
101 * accept the connection.
102 * An error signal will be emitted in case of errors.
103 *
104 * When the connection signal is emitted it is guaranteed that this
105 * function will complete successfully the first time. If you attempt to use
106 * it more than once, it may fail.
107 * It is suggested to only call this function once per connection signal.
108 *
109 * @param client Client stream object.
110 * @return False on error.
111 */
112 bool Accept(const std::shared_ptr<NetworkStream>& client) {
113 return Invoke(&uv_accept, GetRawStream(), client->GetRawStream());
114 }
115
116 /**
117 * Signal generated when an incoming connection is received.
118 */
120
121 protected:
122 explicit NetworkStream(uv_stream_t* uv_stream) : Stream{uv_stream} {}
123
124 virtual NetworkStream* DoAccept() = 0;
125};
126
127template <typename T, typename U>
129 public:
130 std::shared_ptr<T> shared_from_this() {
131 return std::static_pointer_cast<T>(Handle::shared_from_this());
132 }
133
134 std::shared_ptr<const T> shared_from_this() const {
135 return std::static_pointer_cast<const T>(Handle::shared_from_this());
136 }
137
138 /**
139 * Get the underlying handle data structure.
140 *
141 * @return The underlying handle data structure.
142 */
143 U* GetRaw() const noexcept {
144 return reinterpret_cast<U*>(this->GetRawHandle());
145 }
146
147 protected:
149 : NetworkStream{static_cast<uv_stream_t*>(std::malloc(sizeof(U)))} {}
150};
151
152} // namespace wpi::uv
153
154#endif // WPINET_UV_NETWORKSTREAM_H_
SignalBase is an implementation of the observer pattern, through the use of an emitting object and sl...
Definition: Signal.h:495
Connection request.
Definition: NetworkStream.h:25
sig::Signal connected
Connection completed signal.
Definition: NetworkStream.h:36
NetworkStream & GetStream() const
Definition: NetworkStream.h:29
uv_handle_t * GetRawHandle() const noexcept
Get the underlying handle data structure.
Definition: Handle.h:176
bool Invoke(F &&f, Args &&... args) const
Definition: Handle.h:251
Network stream handle.
Definition: NetworkStream.h:44
std::shared_ptr< const NetworkStream > shared_from_this() const
Definition: NetworkStream.h:52
sig::Signal connection
Signal generated when an incoming connection is received.
Definition: NetworkStream.h:119
static constexpr int kDefaultBacklog
Definition: NetworkStream.h:46
std::shared_ptr< NetworkStream > Accept()
Accept incoming connection.
Definition: NetworkStream.h:92
virtual NetworkStream * DoAccept()=0
std::shared_ptr< NetworkStream > shared_from_this()
Definition: NetworkStream.h:48
void Listen(std::function< void()> callback, int backlog=kDefaultBacklog)
Start listening for incoming connections.
bool Accept(const std::shared_ptr< NetworkStream > &client)
Accept incoming connection.
Definition: NetworkStream.h:112
void Listen(int backlog=kDefaultBacklog)
Start listening for incoming connections.
NetworkStream(uv_stream_t *uv_stream)
Definition: NetworkStream.h:122
Definition: NetworkStream.h:128
std::shared_ptr< T > shared_from_this()
Definition: NetworkStream.h:130
U * GetRaw() const noexcept
Get the underlying handle data structure.
Definition: NetworkStream.h:143
std::shared_ptr< const T > shared_from_this() const
Definition: NetworkStream.h:134
NetworkStreamImpl()
Definition: NetworkStream.h:148
Request.
Definition: Request.h:130
uv_connect_t * GetRaw() noexcept
Get the underlying request data structure.
Definition: Request.h:145
Stream handle.
Definition: Stream.h:68
uv_stream_t * GetRawStream() const noexcept
Get the underlying stream data structure.
Definition: Stream.h:287
Definition: StdDeque.h:50
Definition: ParallelTcpConnector.h:22
uv_stream_t * handle
Definition: uv.h:593
Definition: uv.h:497
UV_EXTERN int uv_accept(uv_stream_t *server, uv_stream_t *client)