diff -r a4891d71aca9 -r 51678c7eae03 src/sock_test.c --- /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 +#include +#include + +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; +} +