1#ifndef UVW_STREAM_INCLUDE_H
2#define UVW_STREAM_INCLUDE_H
57 explicit DataEvent(std::unique_ptr<
char[]> buf, std::size_t len)
noexcept;
59 std::unique_ptr<char[]>
data;
65struct ConnectReq final:
public Request<ConnectReq, uv_connect_t> {
66 using Request::Request;
68 template<
typename F,
typename... Args>
69 void connect(F &&f, Args &&...args) {
70 invoke(std::forward<F>(f), get(), std::forward<Args>(args)..., &defaultCallback<ConnectEvent>);
74struct ShutdownReq final:
public Request<ShutdownReq, uv_shutdown_t> {
75 using Request::Request;
77 void shutdown(uv_stream_t *handle);
80template<
typename Deleter>
81class WriteReq final:
public Request<WriteReq<Deleter>, uv_write_t> {
82 using ConstructorAccess =
typename Request<WriteReq<Deleter>, uv_write_t>::ConstructorAccess;
85 WriteReq(ConstructorAccess ca, std::shared_ptr<Loop>
loop, std::unique_ptr<
char[], Deleter> dt,
unsigned int len)
86 : Request<WriteReq<Deleter>, uv_write_t>{ca, std::move(
loop)},
88 buf{uv_buf_init(data.get(), len)} {}
90 void write(uv_stream_t *handle) {
91 this->invoke(&uv_write, this->get(), handle, &buf, 1, &this->
template defaultCallback<WriteEvent>);
94 void write(uv_stream_t *handle, uv_stream_t *send) {
95 this->invoke(&uv_write2, this->get(), handle, &buf, 1, send, &this->
template defaultCallback<WriteEvent>);
99 std::unique_ptr<char[], Deleter> data;
112template<
typename T,
typename U>
114 static constexpr unsigned int DEFAULT_BACKLOG = 128;
116 static void readCallback(uv_stream_t *handle, ssize_t nread,
const uv_buf_t *buf) {
117 T &ref = *(
static_cast<T *
>(handle->data));
119 std::unique_ptr<char[]>
data{buf->base};
125 if(nread == UV_EOF) {
128 }
else if(nread > 0) {
130 ref.publish(
DataEvent{std::move(
data),
static_cast<std::size_t
>(nread)});
131 }
else if(nread < 0) {
137 static void listenCallback(uv_stream_t *handle,
int status) {
138 if(T &ref = *(
static_cast<T *
>(handle->data)); status) {
147 StreamHandle(
typename Handle<T, U>::ConstructorAccess ca, std::shared_ptr<Loop> ref)
150 using Handle<T, U>::Handle;
161 auto listener = [ptr = this->shared_from_this()](
const auto &event,
const auto &) {
165 auto shutdown = this->
loop().template resource<details::ShutdownReq>();
168 shutdown->shutdown(this->
template get<uv_stream_t>());
181 void listen(
int backlog = DEFAULT_BACKLOG) {
182 this->invoke(&uv_listen, this->
template get<uv_stream_t>(), backlog, &listenCallback);
206 this->invoke(&uv_accept, this->
template get<uv_stream_t>(), this->
template get<uv_stream_t>(ref));
217 this->invoke(&uv_read_start, this->
template get<uv_stream_t>(), &this->allocCallback, &readCallback);
226 this->invoke(&uv_read_stop, this->
template get<uv_stream_t>());
241 template<
typename Deleter>
242 void write(std::unique_ptr<
char[], Deleter>
data,
unsigned int len) {
243 auto req = this->
loop().template resource<details::WriteReq<Deleter>>(std::move(
data), len);
244 auto listener = [ptr = this->shared_from_this()](
const auto &event,
const auto &) {
250 req->write(this->
template get<uv_stream_t>());
266 auto req = this->
loop().template resource<details::WriteReq<void (*)(
char *)>>(std::unique_ptr<
char[],
void (*)(
char *)>{
data, [](
char *) {}}, len);
267 auto listener = [ptr = this->shared_from_this()](
const auto &event,
const auto &) {
273 req->write(this->
template get<uv_stream_t>());
295 template<
typename S,
typename Deleter>
296 void write(S &send, std::unique_ptr<
char[], Deleter>
data,
unsigned int len) {
297 auto req = this->
loop().template resource<details::WriteReq<Deleter>>(std::move(
data), len);
298 auto listener = [ptr = this->shared_from_this()](
const auto &event,
const auto &) {
304 req->write(this->
template get<uv_stream_t>(), this->
template get<uv_stream_t>(send));
328 auto req = this->
loop().template resource<details::WriteReq<void (*)(
char *)>>(std::unique_ptr<
char[],
void (*)(
char *)>{
data, [](
char *) {}}, len);
329 auto listener = [ptr = this->shared_from_this()](
const auto &event,
const auto &) {
335 req->write(this->
template get<uv_stream_t>(), this->
template get<uv_stream_t>(send));
350 uv_buf_t bufs[] = {uv_buf_init(
data.get(), len)};
351 auto bw = uv_try_write(this->
template get<uv_stream_t>(), bufs, 1);
372 template<
typename V,
typename W>
374 uv_buf_t bufs[] = {uv_buf_init(
data.get(), len)};
375 auto bw = uv_try_write2(this->
template get<uv_stream_t>(), bufs, 1, send.
raw());
397 uv_buf_t bufs[] = {uv_buf_init(
data, len)};
398 auto bw = uv_try_write(this->
template get<uv_stream_t>(), bufs, 1);
419 template<
typename V,
typename W>
421 uv_buf_t bufs[] = {uv_buf_init(
data, len)};
422 auto bw = uv_try_write2(this->
template get<uv_stream_t>(), bufs, 1, send.
raw());
437 return (uv_is_readable(this->
template get<uv_stream_t>()) == 1);
445 return (uv_is_writable(this->
template get<uv_stream_t>()) == 1);
464 return (0 == uv_stream_set_blocking(this->
template get<uv_stream_t>(), enable));
472 return uv_stream_get_write_queue_size(this->
template get<uv_stream_t>());
479# include "stream.cpp"
Connection< E > once(Listener< E > f)
Registers a short-lived listener with the event emitter.
std::shared_ptr< R > data() const
Gets user-defined data. uvw won't use this field in any case.
void write(S &send, char *data, unsigned int len)
Extended write function for sending handles over a pipe handle.
void write(S &send, std::unique_ptr< char[], Deleter > data, unsigned int len)
Extended write function for sending handles over a pipe handle.
void read()
Starts reading data from an incoming stream.
void shutdown()
Shutdowns the outgoing (write) side of a duplex stream.
int tryWrite(std::unique_ptr< char[]> data, unsigned int len)
Queues a write request if it can be completed immediately.
bool writable() const noexcept
Checks if the stream is writable.
bool blocking(bool enable=false)
Enables or disables blocking mode for a stream.
int tryWrite(char *data, unsigned int len, StreamHandle< V, W > &send)
Queues a write request if it can be completed immediately.
size_t writeQueueSize() const noexcept
Gets the amount of queued bytes waiting to be sent.
int tryWrite(char *data, unsigned int len)
Queues a write request if it can be completed immediately.
bool readable() const noexcept
Checks if the stream is readable.
void stop()
Stops reading data from the stream.
void write(char *data, unsigned int len)
Writes data to the stream.
void listen(int backlog=DEFAULT_BACKLOG)
Starts listening for incoming connections.
void accept(S &ref)
Accepts incoming connections.
int tryWrite(std::unique_ptr< char[]> data, unsigned int len, StreamHandle< V, W > &send)
Queues a write request if it can be completed immediately.
void write(std::unique_ptr< char[], Deleter > data, unsigned int len)
Writes data to the stream.
Loop & loop() const noexcept
const U * raw() const noexcept
Gets the underlying raw data structure.
std::unique_ptr< char[]> data