diff options
Diffstat (limited to 'example/src')
-rw-r--r-- | example/src/main.c | 99 | ||||
-rw-r--r-- | example/src/middle.c | 58 | ||||
-rw-r--r-- | example/src/middle.h | 6 |
3 files changed, 163 insertions, 0 deletions
diff --git a/example/src/main.c b/example/src/main.c new file mode 100644 index 0000000..4fa570f --- /dev/null +++ b/example/src/main.c @@ -0,0 +1,99 @@ +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "uv.h" +#include "uv_link_t.h" + +/* Declaration of `middle_methods` */ +#include "middle.h" + +typedef struct client_s client_t; + +static uv_tcp_t server; + +struct client_s { + uv_tcp_t tcp; + uv_link_source_t source; + uv_link_t middle; + uv_link_observer_t observer; +}; + +static void read_cb(uv_link_observer_t* observer, + ssize_t nread, + const uv_buf_t* buf) { + client_t* client; + + client = observer->link.data; + + if (nread < 0) { + fprintf(stderr, "error or close\n"); + uv_link_read_stop(&observer->link); + uv_close((uv_handle_t*) &client->tcp, NULL); + free(client); + return; + } + + fprintf(stderr, "read \"%.*s\"\n", (int) nread, buf->base); +} + + +static void connection_cb(uv_stream_t* s, int status) { + int err; + client_t* client; + + client = malloc(sizeof(*client)); + assert(client != NULL); + + err = uv_tcp_init(uv_default_loop(), &client->tcp); + assert(err == 0); + + err = uv_accept(s, (uv_stream_t*) &client->tcp); + assert(err == 0); + + err = uv_link_source_init(&client->source, (uv_stream_t*) &client->tcp); + assert(err == 0); + + err = uv_link_init(&client->middle, &middle_methods); + assert(err == 0); + + err = uv_link_chain(&client->source.link, &client->middle); + assert(err == 0); + + err = uv_link_observer_init(&client->observer, &client->middle); + assert(err == 0); + + client->observer.read_cb = read_cb; + client->observer.link.data = client; + + err = uv_link_read_start(&client->observer.link); + assert(err == 0); +} + + +int main() { + static const int kBacklog = 128; + + int err; + uv_loop_t* loop; + struct sockaddr_in addr; + + loop = uv_default_loop(); + + err = uv_tcp_init(loop, &server); + assert(err == 0); + + err = uv_ip4_addr("0.0.0.0", 9000, &addr); + assert(err == 0); + + err = uv_tcp_bind(&server, (struct sockaddr*) &addr, 0); + assert(err == 0); + + err = uv_listen((uv_stream_t*) &server, kBacklog, connection_cb); + + err = uv_run(loop, UV_RUN_DEFAULT); + assert(err == 0); + + return 0; +} diff --git a/example/src/middle.c b/example/src/middle.c new file mode 100644 index 0000000..9e6d158 --- /dev/null +++ b/example/src/middle.c @@ -0,0 +1,58 @@ +#include <assert.h> +#include <stdlib.h> +#include <string.h> + +#include "uv_link_t.h" + +static int read_start_impl(uv_link_t* link) { + return uv_link_read_start(link->parent); +} + + +static int read_stop_impl(uv_link_t* link) { + return uv_link_read_stop(link->parent); +} + + +static void alloc_cb_override(uv_link_t* link, + size_t suggested_size, + uv_buf_t* buf) { + buf->base = malloc(suggested_size); + assert(buf->base != NULL); + buf->len = suggested_size; +} + + +static void read_cb_override(uv_link_t* link, + ssize_t nread, + const uv_buf_t* buf) { + const char* res; + uv_buf_t tmp; + + if (nread >= 0) { + if (nread == 9 && strncmp(buf->base, "password\n", 9) == 0) + res = "welcome"; + else + res = "go away"; + } else { + res = "error"; + } + + free(buf->base); + + uv_link_invoke_alloc_cb(link, strlen(res), &tmp); + assert(tmp.len >= strlen(res)); + + memcpy(tmp.base, res, strlen(res)); + uv_link_invoke_read_cb(link, strlen(res), &tmp); +} + + +uv_link_methods_t middle_methods = { + .read_start = read_start_impl, + .read_stop = read_stop_impl, + + /* Other doesn't matter in this example */ + .alloc_cb_override = alloc_cb_override, + .read_cb_override = read_cb_override +}; diff --git a/example/src/middle.h b/example/src/middle.h new file mode 100644 index 0000000..820721d --- /dev/null +++ b/example/src/middle.h @@ -0,0 +1,6 @@ +#ifndef EXAMPLE_SRC_MIDDLE_H_ +#define EXAMPLE_SRC_MIDDLE_H_ + +uv_link_methods_t middle_methods; + +#endif /* EXAMPLE_SRC_MIDDLE_H_ */ |