1.1 --- a/ucx/buffer.c Sun Nov 04 20:50:12 2012 +0100 1.2 +++ b/ucx/buffer.c Fri Nov 30 13:10:58 2012 +0100 1.3 @@ -3,22 +3,23 @@ 1.4 #include <stdlib.h> 1.5 #include <string.h> 1.6 1.7 -UcxBuffer *ucx_buffer_new(void *space, size_t length, int flags) { 1.8 +UcxBuffer *ucx_buffer_new(void *space, size_t size, int flags) { 1.9 UcxBuffer *buffer = (UcxBuffer*) malloc(sizeof(UcxBuffer)); 1.10 if (buffer) { 1.11 buffer->flags = flags; 1.12 if (!space) { 1.13 - buffer->space = malloc(length); 1.14 + buffer->space = malloc(size); 1.15 if (!buffer->space) { 1.16 free(buffer); 1.17 return NULL; 1.18 } 1.19 - memset(buffer->space, 0, length); 1.20 + memset(buffer->space, 0, size); 1.21 buffer->flags |= UCX_BUFFER_AUTOFREE; 1.22 } else { 1.23 buffer->space = space; 1.24 } 1.25 - buffer->size = length; 1.26 + buffer->capacity = size; 1.27 + buffer->size = 0; 1.28 1.29 buffer->pos = 0; 1.30 } 1.31 @@ -33,8 +34,11 @@ 1.32 free(buffer); 1.33 } 1.34 1.35 -UcxBuffer *restrict ucx_buffer_extract( 1.36 - UcxBuffer *restrict src, size_t start, size_t length, int flags) { 1.37 +UcxBuffer* ucx_buffer_extract( 1.38 + UcxBuffer *src, size_t start, size_t length, int flags) { 1.39 + if(src->size == 0) { 1.40 + return NULL; 1.41 + } 1.42 if (length == 0) { 1.43 length = src->size - start; 1.44 } 1.45 @@ -42,17 +46,18 @@ 1.46 return NULL; 1.47 } 1.48 1.49 - UcxBuffer *restrict dst = (UcxBuffer*) malloc(sizeof(UcxBuffer)); 1.50 + UcxBuffer *dst = (UcxBuffer*) malloc(sizeof(UcxBuffer)); 1.51 if (dst) { 1.52 dst->space = malloc(length); 1.53 if (!dst->space) { 1.54 free(dst); 1.55 return NULL; 1.56 } 1.57 + dst->capacity = length; 1.58 dst->size = length; 1.59 dst->flags = flags | UCX_BUFFER_AUTOFREE; 1.60 dst->pos = 0; 1.61 - memcpy(dst->space, (char*)src->space+start, length); 1.62 + memcpy(dst->space, src->space+start, length); 1.63 } 1.64 return dst; 1.65 } 1.66 @@ -67,12 +72,12 @@ 1.67 npos = buffer->pos; 1.68 break; 1.69 case SEEK_END: 1.70 - npos = strlen((const char*) buffer->space); 1.71 + npos = buffer->size; 1.72 break; 1.73 } 1.74 1.75 npos += offset; 1.76 - 1.77 + 1.78 if (npos < 0 || npos > buffer->size) { 1.79 return -1; 1.80 } else { 1.81 @@ -86,57 +91,114 @@ 1.82 return buffer->pos >= buffer->size; 1.83 } 1.84 1.85 -size_t ucx_bufio(void* d, size_t s, size_t n, UcxBuffer *b, _Bool read) { 1.86 - size_t len = s*n; 1.87 - if (b->pos + len > b->size) { 1.88 - if ((b->flags & UCX_BUFFER_AUTOEXTEND) == UCX_BUFFER_AUTOEXTEND) { 1.89 - size_t newsize = b->size; 1.90 - while (b->pos + len > newsize) newsize <<= 1; 1.91 - void *newspace = realloc(b->space, newsize); 1.92 - if (newspace) { 1.93 - memset((char*)newspace+b->size, 0, newsize-b->size); 1.94 - b->space = newspace; 1.95 - b->size = newsize; 1.96 - } else { 1.97 - len = -1; 1.98 +int ucx_buffer_extend(UcxBuffer *buffer, size_t len) { 1.99 + size_t newcap = buffer->capacity; 1.100 + while (buffer->pos + len > newcap) newcap <<= 1; 1.101 + 1.102 + char *newspace = realloc(buffer->space, newcap); 1.103 + if (newspace) { 1.104 + memset(newspace+buffer->size, 0, newcap-buffer->size); 1.105 + buffer->space = newspace; 1.106 + buffer->capacity = newcap; 1.107 + } else { 1.108 + return -1; 1.109 + } 1.110 + 1.111 + return 0; 1.112 +} 1.113 + 1.114 +size_t ucx_buffer_write(const void *ptr, size_t size, size_t nitems, 1.115 + UcxBuffer *buffer) { 1.116 + size_t len = size * nitems; 1.117 + if (buffer->pos + len > buffer->capacity) { 1.118 + if ((buffer->flags & UCX_BUFFER_AUTOEXTEND) == UCX_BUFFER_AUTOEXTEND) { 1.119 + if(ucx_buffer_extend(buffer, len)) { 1.120 + return -1; 1.121 } 1.122 } else { 1.123 - len = b->size - b->pos; 1.124 - if (s > 1) len -= len%s; 1.125 + len = buffer->capacity - buffer->pos; 1.126 + if (size > 1) len -= len%size; 1.127 } 1.128 } 1.129 - 1.130 + 1.131 if (len <= 0) { 1.132 return len; 1.133 } 1.134 + 1.135 + memcpy(buffer->space + buffer->pos, ptr, len); 1.136 + buffer->pos += len; 1.137 + if(buffer->pos > buffer->size) { 1.138 + buffer->size = buffer->pos; 1.139 + } 1.140 + 1.141 + return len / size; 1.142 +} 1.143 1.144 - if (read) { 1.145 - memcpy(d, (char*)b->space+b->pos, len); 1.146 - } else { 1.147 - memcpy((char*)b->space+b->pos, d, len); 1.148 +size_t ucx_buffer_read(void *ptr, size_t size, size_t nitems, 1.149 + UcxBuffer *buffer) { 1.150 + size_t len = size * nitems; 1.151 + if (buffer->pos + len > buffer->size) { 1.152 + len = buffer->size - buffer->pos; 1.153 + if (size > 1) len -= len%size; 1.154 } 1.155 - b->pos += len; 1.156 - 1.157 - return len; 1.158 + 1.159 + if (len <= 0) { 1.160 + return len; 1.161 + } 1.162 + 1.163 + memcpy(ptr, buffer->space + buffer->pos, len); 1.164 + buffer->pos += len; 1.165 + 1.166 + return len / size; 1.167 } 1.168 1.169 int ucx_buffer_putc(UcxBuffer *buffer, int c) { 1.170 - if (ucx_buffer_eof(buffer)) { 1.171 - return EOF; 1.172 - } else { 1.173 - c &= 0xFF; 1.174 - ((char*)(buffer->space))[buffer->pos] = (char) c; 1.175 - buffer->pos++; 1.176 - return c; 1.177 + if(buffer->pos >= buffer->capacity) { 1.178 + if ((buffer->flags & UCX_BUFFER_AUTOEXTEND) == UCX_BUFFER_AUTOEXTEND) { 1.179 + if(ucx_buffer_extend(buffer, 1)) { 1.180 + return EOF; 1.181 + } 1.182 + } else { 1.183 + return EOF; 1.184 + } 1.185 } 1.186 + 1.187 + c &= 0xFF; 1.188 + buffer->space[buffer->pos] = (char) c; 1.189 + buffer->pos++; 1.190 + if(buffer->pos > buffer->size) { 1.191 + buffer->size = buffer->pos; 1.192 + } 1.193 + return c; 1.194 } 1.195 1.196 int ucx_buffer_getc(UcxBuffer *buffer) { 1.197 if (ucx_buffer_eof(buffer)) { 1.198 return EOF; 1.199 } else { 1.200 - int c = ((char*)(buffer->space))[buffer->pos]; 1.201 + int c = buffer->space[buffer->pos]; 1.202 buffer->pos++; 1.203 return c; 1.204 } 1.205 } 1.206 + 1.207 +size_t ucx_buffer_generic_copy(void *s1, void *s2, 1.208 + read_func readfnc, write_func writefnc, size_t bufsize) { 1.209 + size_t ncp = 0; 1.210 + char *buf = malloc(bufsize); 1.211 + if(buf == NULL) { 1.212 + return 0; 1.213 + } 1.214 + 1.215 + size_t r; 1.216 + while((r = readfnc(buf, 1, bufsize, s1)) != 0) { 1.217 + r = writefnc(buf, 1, r, s2); 1.218 + ncp += r; 1.219 + if(r == 0) { 1.220 + break; 1.221 + } 1.222 + } 1.223 + 1.224 + free(buf); 1.225 + return ncp; 1.226 +}