about summary refs log tree commit diff stats
path: root/example/src
diff options
context:
space:
mode:
Diffstat (limited to 'example/src')
-rw-r--r--example/src/main.c99
-rw-r--r--example/src/middle.c58
-rw-r--r--example/src/middle.h6
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_ */