src/sock_test.c
changeset 40 51678c7eae03
child 41 40f7aa051acb
equal deleted inserted replaced
39:a4891d71aca9 40:51678c7eae03
       
     1 #include "sock_test.h"
       
     2 
       
     3 #include <stdlib.h>
       
     4 #include <string.h>
       
     5 #include <assert.h>
       
     6 
       
     7 static err_t sock_test_read (struct sock_stream *base_sock, void *buf_ptr, size_t *len)
       
     8 {
       
     9     struct sock_test *sock = SOCK_FROM_BASE(base_sock, struct sock_test);
       
    10     struct io_buf *buf = &sock->recv_buf;
       
    11     struct io_vec *vec = buf->vec;
       
    12 
       
    13     // no current vector -> EOF
       
    14     if (!vec)
       
    15         return ERR_READ_EOF;
       
    16 
       
    17     // vector past the end -> EOF
       
    18     if (vec == &buf->vecs[buf->count])
       
    19         return ERR_READ_EOF;
       
    20     
       
    21     // no data left in current vector -> EOF
       
    22     if (buf->off >= vec->len)
       
    23         return ERR_READ_EOF;
       
    24     
       
    25     // amount of data available in this iovec
       
    26     size_t available = vec->len - buf->off;
       
    27 
       
    28     // amount to read
       
    29     size_t to_read = *len;
       
    30     
       
    31     // trim down?
       
    32     if (to_read > available)
       
    33         to_read = available;
       
    34 
       
    35     // copy
       
    36     memcpy(buf_ptr, vec->buf + buf->off, to_read);
       
    37     
       
    38     // consumed the whole vec?
       
    39     if (to_read < available) {
       
    40         // move offset
       
    41         buf->off += to_read;
       
    42 
       
    43     } else {
       
    44         // next vector
       
    45         buf->vec++;
       
    46     }
       
    47 
       
    48     // update len
       
    49     *len = to_read;
       
    50 
       
    51     // ok
       
    52     return SUCCESS;
       
    53 }
       
    54 
       
    55 static err_t sock_test_write (struct sock_stream *base_sock, const void *buf_ptr, size_t *len)
       
    56 {
       
    57     struct sock_test *sock = SOCK_FROM_BASE(base_sock, struct sock_test);
       
    58     struct io_buf *buf = &sock->send_buf;
       
    59     struct io_vec *vec = buf->vec;
       
    60     
       
    61     // vectors full?
       
    62     if (buf->vecs == NULL || vec == &buf->vecs[buf->count]) {
       
    63         size_t vec_offset = vec ? (vec - buf->vecs) : 0;
       
    64         struct io_vec *v;
       
    65 
       
    66         // new size
       
    67         buf->count = buf->count * 2 + 1;
       
    68 
       
    69         // grow
       
    70         assert((buf->vecs = realloc(buf->vecs, buf->count * sizeof(struct io_vec))));
       
    71 
       
    72         // set vec
       
    73         vec = buf->vec = buf->vecs + vec_offset;
       
    74 
       
    75         // zero
       
    76         for (v = vec; v < &buf->vecs[buf->count]; v++) {
       
    77             v->buf = NULL;
       
    78             v->len = 0;
       
    79         }
       
    80     }
       
    81 
       
    82     // store
       
    83     vec->len = *len;
       
    84     assert((vec->buf = malloc(vec->len)));
       
    85     memcpy(vec->buf, buf_ptr, vec->len);
       
    86 
       
    87     // move vec onwards
       
    88     buf->vec++;
       
    89 
       
    90     // ok
       
    91     return SUCCESS;
       
    92 }
       
    93 
       
    94 static err_t sock_test_event_init (struct sock_stream *base_sock)
       
    95 {
       
    96     
       
    97     return SUCCESS;
       
    98 }
       
    99 
       
   100 static err_t sock_test_event_enable (struct sock_stream *base_sock, short mask)
       
   101 {
       
   102     
       
   103     return SUCCESS;
       
   104 }
       
   105 
       
   106 static void sock_test_release (struct sock_stream *base_sock)
       
   107 {
       
   108 
       
   109 }
       
   110 
       
   111 /*
       
   112  * Our sock_stream_type
       
   113  */
       
   114 static struct sock_stream_type sock_test_type = {
       
   115     .methods                = {
       
   116         .read               = &sock_test_read,
       
   117         .write              = &sock_test_write,
       
   118         .event_init         = &sock_test_event_init,
       
   119         .event_enable       = &sock_test_event_enable,
       
   120         .release            = &sock_test_release,
       
   121     },
       
   122 };
       
   123 
       
   124 struct sock_test* sock_test_create (void)
       
   125 {
       
   126     struct sock_test *sock;
       
   127 
       
   128     // allocate
       
   129     assert((sock = calloc(1, sizeof(*sock))));
       
   130     
       
   131     // initialize base with our sock_stream_type
       
   132     sock_stream_init(SOCK_TEST_BASE(sock), &sock_test_type);
       
   133 
       
   134     // ok
       
   135     return sock;
       
   136 }
       
   137 
       
   138 void sock_test_set_recv_buffer (struct sock_test *sock, struct io_vec *vecs, size_t count)
       
   139 {
       
   140     sock->recv_buf.vecs = vecs;
       
   141     sock->recv_buf.count = count;
       
   142     sock->recv_buf.vec = vecs;
       
   143     sock->recv_buf.off = 0;
       
   144 }
       
   145 
       
   146 void sock_test_get_send_data (struct sock_test *sock, char **buf_ptr, size_t *len_ptr)
       
   147 {
       
   148     struct io_buf *buf = &sock->send_buf;
       
   149     size_t len = 0, i, off = 0;
       
   150     char *out;
       
   151     
       
   152     // calculate total size
       
   153     for (i = 0; i < buf->count; i++) {
       
   154         len += buf->vecs[i].len;
       
   155     }
       
   156 
       
   157     // alloc
       
   158     assert((out = malloc(len)));
       
   159 
       
   160     // copy
       
   161     for (i = 0; i < buf->count; i++) {
       
   162         memcpy(out + off, buf->vecs[i].buf, buf->vecs[i].len);
       
   163         off += buf->vecs[i].len;
       
   164     }
       
   165     
       
   166     // update return
       
   167     *buf_ptr = out;
       
   168     *len_ptr = len;
       
   169 }
       
   170