10 #include "request.hpp" 64 explicit DataEvent(std::unique_ptr<
char[]> buf, std::size_t len) noexcept
65 : data{std::move(buf)}, length{len}
68 std::unique_ptr<char[]>
data;
76 struct ConnectReq final:
public Request<ConnectReq, uv_connect_t> {
77 using Request::Request;
79 template<
typename F,
typename... Args>
80 void connect(F &&f, Args&&... args) {
81 invoke(std::forward<F>(f),
get(), std::forward<Args>(args)..., &defaultCallback<ConnectEvent>);
86 struct ShutdownReq final:
public Request<ShutdownReq, uv_shutdown_t> {
87 using Request::Request;
89 void shutdown(uv_stream_t *handle) {
90 invoke(&uv_shutdown,
get(), handle, &defaultCallback<ShutdownEvent>);
95 class WriteReq final:
public Request<WriteReq, uv_write_t> {
97 using Deleter = void(*)(
char *);
99 WriteReq(ConstructorAccess ca, std::shared_ptr<Loop> loop, std::unique_ptr<
char[], Deleter> dt,
unsigned int len)
100 : Request<WriteReq, uv_write_t>{ca, std::move(loop)},
102 buf{uv_buf_init(data.get(), len)}
105 void write(uv_stream_t *handle) {
106 invoke(&uv_write,
get(), handle, &buf, 1, &defaultCallback<WriteEvent>);
109 void write(uv_stream_t *handle, uv_stream_t *send) {
110 invoke(&uv_write2,
get(), handle, &buf, 1, send, &defaultCallback<WriteEvent>);
114 std::unique_ptr<char[], Deleter> data;
129 template<
typename T,
typename U>
131 static constexpr
unsigned int DEFAULT_BACKLOG = 128;
133 static void readCallback(uv_stream_t *handle, ssize_t nread,
const uv_buf_t *buf) {
134 T &ref = *(
static_cast<T*
>(handle->data));
136 std::unique_ptr<char[]> data{buf->base};
142 if(nread == UV_EOF) {
145 }
else if(nread > 0) {
147 ref.publish(
DataEvent{std::move(data),
static_cast<std::size_t
>(nread)});
148 }
else if(nread < 0) {
154 static void listenCallback(uv_stream_t *handle,
int status) {
155 T &ref = *(
static_cast<T*
>(handle->data));
156 if(status) { ref.publish(
ErrorEvent{status}); }
162 StreamHandle(ConstructorAccess ca, std::shared_ptr<Loop> ref)
163 :
Handle{ca, std::move(ref)}
177 auto listener = [ptr = this->shared_from_this()](
const auto &event,
const auto &) {
181 auto shutdown = this->loop().template resource<details::ShutdownReq>();
182 shutdown->template once<ErrorEvent>(listener);
183 shutdown->template once<ShutdownEvent>(listener);
184 shutdown->shutdown(this->
template get<uv_stream_t>());
197 void listen(
int backlog = DEFAULT_BACKLOG) {
198 this->invoke(&uv_listen, this->
template get<uv_stream_t>(), backlog, &listenCallback);
221 this->invoke(&uv_accept, this->
template get<uv_stream_t>(), ref.template get<uv_stream_t>());
232 this->invoke(&uv_read_start, this->
template get<uv_stream_t>(), &this->allocCallback, &readCallback);
241 this->invoke(&uv_read_stop, this->
template get<uv_stream_t>());
256 void write(std::unique_ptr<
char[]> data,
unsigned int len) {
257 auto req = this->loop().template resource<details::WriteReq>(
258 std::unique_ptr<char[], details::WriteReq::Deleter>{
259 data.release(), [](
char *ptr) {
delete[] ptr; }
262 auto listener = [ptr = this->shared_from_this()](
const auto &event,
const auto &) {
266 req->template once<ErrorEvent>(listener);
267 req->template once<WriteEvent>(listener);
268 req->write(this->
template get<uv_stream_t>());
283 void write(
char *data,
unsigned int len) {
284 auto req = this->loop().template resource<details::WriteReq>(
285 std::unique_ptr<char[], details::WriteReq::Deleter>{
289 auto listener = [ptr = this->shared_from_this()](
const auto &event,
const auto &) {
293 req->template once<ErrorEvent>(listener);
294 req->template once<WriteEvent>(listener);
295 req->write(this->
template get<uv_stream_t>());
318 void write(S &send, std::unique_ptr<
char[]> data,
unsigned int len) {
319 auto req = this->loop().template resource<details::WriteReq>(
320 std::unique_ptr<char[], details::WriteReq::Deleter>{
321 data.release(), [](
char *ptr) {
delete[] ptr; }
324 auto listener = [ptr = this->shared_from_this()](
const auto &event,
const auto &) {
328 req->template once<ErrorEvent>(listener);
329 req->template once<WriteEvent>(listener);
330 req->write(this->
template get<uv_stream_t>(), send.template get<uv_stream_t>());
353 void write(S &send,
char *data,
unsigned int len) {
354 auto req = this->loop().template resource<details::WriteReq>(
355 std::unique_ptr<char[], details::WriteReq::Deleter>{
359 auto listener = [ptr = this->shared_from_this()](
const auto &event,
const auto &) {
363 req->template once<ErrorEvent>(listener);
364 req->template once<WriteEvent>(listener);
365 req->write(this->
template get<uv_stream_t>(), send.template get<uv_stream_t>());
379 int tryWrite(std::unique_ptr<
char[]> data,
unsigned int len) {
380 uv_buf_t bufs[] = { uv_buf_init(data.get(), len) };
381 auto bw = uv_try_write(this->
template get<uv_stream_t>(), bufs, 1);
403 uv_buf_t bufs[] = { uv_buf_init(data, len) };
404 auto bw = uv_try_write(this->
template get<uv_stream_t>(), bufs, 1);
419 return (uv_is_readable(this->
template get<uv_stream_t>()) == 1);
427 return (uv_is_writable(this->
template get<uv_stream_t>()) == 1);
446 return (0 == uv_stream_set_blocking(this->
template get<uv_stream_t>(), enable));
void write(S &send, char *data, unsigned int len)
Extended write function for sending handles over a pipe handle.
bool blocking(bool enable=false)
Enables or disables blocking mode for a stream.
void read()
Starts reading data from an incoming stream.
bool writable() const noexcept
Checks if the stream is writable.
void listen(int backlog=DEFAULT_BACKLOG)
Starts listening for incoming connections.
void accept(S &ref)
Accepts incoming connections.
void write(std::unique_ptr< char[]> data, unsigned int len)
Writes data to the stream.
int tryWrite(char *data, unsigned int len)
Queues a write request if it can be completed immediately.
void shutdown()
Shutdowns the outgoing (write) side of a duplex stream.
std::unique_ptr< char[]> data
int tryWrite(std::unique_ptr< char[]> data, unsigned int len)
Queues a write request if it can be completed immediately.
void write(char *data, unsigned int len)
Writes data to the stream.
void stop()
Stops reading data from the stream.
void write(S &send, std::unique_ptr< char[]> data, unsigned int len)
Extended write function for sending handles over a pipe handle.
bool readable() const noexcept
Checks if the stream is readable.