diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common.h | 7 | ||||
-rw-r--r-- | src/uv_link.c | 10 | ||||
-rw-r--r-- | src/uv_link_source.c | 160 |
3 files changed, 177 insertions, 0 deletions
diff --git a/src/common.h b/src/common.h new file mode 100644 index 0000000..8c5725d --- /dev/null +++ b/src/common.h @@ -0,0 +1,7 @@ +#ifndef SRC_COMMON_H_ +#define SRC_COMMON_H_ + +#define container_of(ptr, type, member) \ + ((type *) ((char *) (ptr) - offsetof(type, member))) + +#endif /* SRC_COMMON_H_ */ diff --git a/src/uv_link.c b/src/uv_link.c new file mode 100644 index 0000000..e4199cf --- /dev/null +++ b/src/uv_link.c @@ -0,0 +1,10 @@ +#include <string.h> + +#include "uv_link.h" + +#include "common.h" + +int uv_link_init(uv_loop_t* loop, uv_link_t* link) { + memset(link, 0, sizeof(*link)); + return 0; +} diff --git a/src/uv_link_source.c b/src/uv_link_source.c new file mode 100644 index 0000000..181a060 --- /dev/null +++ b/src/uv_link_source.c @@ -0,0 +1,160 @@ +#include <stdlib.h> + +#include "uv_link.h" + +#include "common.h" + +typedef struct uv_link_source_write_s uv_link_source_write_t; +typedef struct uv_link_source_shutdown_s uv_link_source_shutdown_t; + +struct uv_link_source_write_s { + uv_write_t req; + uv_link_t* link; + uv_link_write_cb write_cb; +}; + +struct uv_link_source_shutdown_s { + uv_shutdown_t req; + uv_link_t* link; + uv_link_shutdown_cb shutdown_cb; +}; + + +static void uv_link_source_wrap_alloc_cb(uv_handle_t* handle, + size_t suggested_size, + uv_buf_t* buf) { + uv_link_source_t* source; + + source = handle->data; + + source->link.alloc_cb(&source->link, suggested_size, buf); +} + + +static void uv_link_source_wrap_read_cb(uv_stream_t* stream, + ssize_t nread, + const uv_buf_t* buf) { + uv_link_source_t* source; + + source = stream->data; + + source->link.read_cb(&source->link, nread, buf); +} + + +static int uv_link_source_read_start(uv_link_t* link) { + uv_link_source_t* source; + + source = container_of(link, uv_link_source_t, link); + + return uv_read_start(source->stream, + uv_link_source_wrap_alloc_cb, + uv_link_source_wrap_read_cb); +} + + +static int uv_link_source_read_stop(uv_link_t* link) { + uv_link_source_t* source; + + source = container_of(link, uv_link_source_t, link); + + return uv_read_stop(source->stream); +} + + +static void uv_link_source_wrap_write_cb(uv_write_t* req, int status) { + uv_link_source_write_t* lreq; + + lreq = container_of(req, uv_link_source_write_t, req); + lreq->write_cb(lreq->link, status); + free(lreq); +} + + +static int uv_link_source_write(uv_link_t* link, + const uv_buf_t bufs[], + unsigned int nbufs, + uv_stream_t* send_handle, + uv_link_write_cb cb) { + uv_link_source_t* source; + uv_link_source_write_t* req; + + source = container_of(link, uv_link_source_t, link); + req = malloc(sizeof(*req)); + if (req == NULL) + return UV_ENOMEM; + + req->link = link; + req->write_cb = cb; + + return uv_write2(&req->req, source->stream, bufs, nbufs, send_handle, + uv_link_source_wrap_write_cb); +} + + +static int uv_link_source_try_write(uv_link_t* link, + const uv_buf_t bufs[], + unsigned int nbufs) { + uv_link_source_t* source; + + source = container_of(link, uv_link_source_t, link); + + return uv_try_write(source->stream, bufs, nbufs); +} + + +static void uv_link_source_wrap_shutdown_cb(uv_shutdown_t* req, int status) { + uv_link_source_shutdown_t* lreq; + + lreq = container_of(req, uv_link_source_shutdown_t, req); + lreq->shutdown_cb(lreq->link, status); + free(lreq); +} + + +static int uv_link_shutdown(uv_link_t* link, uv_link_shutdown_cb cb) { + uv_link_source_t* source; + uv_link_source_shutdown_t* req; + + source = container_of(link, uv_link_source_t, link); + + req = malloc(sizeof(*req)); + if (req == NULL) + return UV_ENOMEM; + + req->link = link; + req->shutdown_cb = cb; + + return uv_shutdown(&req->req, source->stream, + uv_link_source_wrap_shutdown_cb); +} + + +int uv_link_source_init(uv_loop_t* loop, + uv_link_source_t* source, + uv_stream_t* stream) { + int err; + uv_link_t* l; + + err = uv_link_init(loop, &source->link); + if (err != 0) + return err; + + source->stream = stream; + source->stream->data = source; + + l = &source->link; + l->read_start = uv_link_source_read_start; + l->read_stop = uv_link_source_read_stop; + l->write = uv_link_source_write; + l->try_write = uv_link_source_try_write; + l->shutdown = uv_link_shutdown; + + return 0; +} + + +int uv_link_source_destroy(uv_link_source_t* source) { + source->stream = NULL; + return 0; +} |