--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/sock_test.c Thu Mar 12 20:00:48 2009 +0200
@@ -0,0 +1,170 @@
+#include "sock_test.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+static err_t sock_test_read (struct sock_stream *base_sock, void *buf_ptr, size_t *len)
+{
+ struct sock_test *sock = SOCK_FROM_BASE(base_sock, struct sock_test);
+ struct io_buf *buf = &sock->recv_buf;
+ struct io_vec *vec = buf->vec;
+
+ // no current vector -> EOF
+ if (!vec)
+ return ERR_READ_EOF;
+
+ // vector past the end -> EOF
+ if (vec == &buf->vecs[buf->count])
+ return ERR_READ_EOF;
+
+ // no data left in current vector -> EOF
+ if (buf->off >= vec->len)
+ return ERR_READ_EOF;
+
+ // amount of data available in this iovec
+ size_t available = vec->len - buf->off;
+
+ // amount to read
+ size_t to_read = *len;
+
+ // trim down?
+ if (to_read > available)
+ to_read = available;
+
+ // copy
+ memcpy(buf_ptr, vec->buf + buf->off, to_read);
+
+ // consumed the whole vec?
+ if (to_read < available) {
+ // move offset
+ buf->off += to_read;
+
+ } else {
+ // next vector
+ buf->vec++;
+ }
+
+ // update len
+ *len = to_read;
+
+ // ok
+ return SUCCESS;
+}
+
+static err_t sock_test_write (struct sock_stream *base_sock, const void *buf_ptr, size_t *len)
+{
+ struct sock_test *sock = SOCK_FROM_BASE(base_sock, struct sock_test);
+ struct io_buf *buf = &sock->send_buf;
+ struct io_vec *vec = buf->vec;
+
+ // vectors full?
+ if (buf->vecs == NULL || vec == &buf->vecs[buf->count]) {
+ size_t vec_offset = vec ? (vec - buf->vecs) : 0;
+ struct io_vec *v;
+
+ // new size
+ buf->count = buf->count * 2 + 1;
+
+ // grow
+ assert((buf->vecs = realloc(buf->vecs, buf->count * sizeof(struct io_vec))));
+
+ // set vec
+ vec = buf->vec = buf->vecs + vec_offset;
+
+ // zero
+ for (v = vec; v < &buf->vecs[buf->count]; v++) {
+ v->buf = NULL;
+ v->len = 0;
+ }
+ }
+
+ // store
+ vec->len = *len;
+ assert((vec->buf = malloc(vec->len)));
+ memcpy(vec->buf, buf_ptr, vec->len);
+
+ // move vec onwards
+ buf->vec++;
+
+ // ok
+ return SUCCESS;
+}
+
+static err_t sock_test_event_init (struct sock_stream *base_sock)
+{
+
+ return SUCCESS;
+}
+
+static err_t sock_test_event_enable (struct sock_stream *base_sock, short mask)
+{
+
+ return SUCCESS;
+}
+
+static void sock_test_release (struct sock_stream *base_sock)
+{
+
+}
+
+/*
+ * Our sock_stream_type
+ */
+static struct sock_stream_type sock_test_type = {
+ .methods = {
+ .read = &sock_test_read,
+ .write = &sock_test_write,
+ .event_init = &sock_test_event_init,
+ .event_enable = &sock_test_event_enable,
+ .release = &sock_test_release,
+ },
+};
+
+struct sock_test* sock_test_create (void)
+{
+ struct sock_test *sock;
+
+ // allocate
+ assert((sock = calloc(1, sizeof(*sock))));
+
+ // initialize base with our sock_stream_type
+ sock_stream_init(SOCK_TEST_BASE(sock), &sock_test_type);
+
+ // ok
+ return sock;
+}
+
+void sock_test_set_recv_buffer (struct sock_test *sock, struct io_vec *vecs, size_t count)
+{
+ sock->recv_buf.vecs = vecs;
+ sock->recv_buf.count = count;
+ sock->recv_buf.vec = vecs;
+ sock->recv_buf.off = 0;
+}
+
+void sock_test_get_send_data (struct sock_test *sock, char **buf_ptr, size_t *len_ptr)
+{
+ struct io_buf *buf = &sock->send_buf;
+ size_t len = 0, i, off = 0;
+ char *out;
+
+ // calculate total size
+ for (i = 0; i < buf->count; i++) {
+ len += buf->vecs[i].len;
+ }
+
+ // alloc
+ assert((out = malloc(len)));
+
+ // copy
+ for (i = 0; i < buf->count; i++) {
+ memcpy(out + off, buf->vecs[i].buf, buf->vecs[i].len);
+ off += buf->vecs[i].len;
+ }
+
+ // update return
+ *buf_ptr = out;
+ *len_ptr = len;
+}
+