Wed, 10 Oct 2012 14:18:06 +0200
added autoextend feature to buffer
and we celebrate the 50th test case
1 #include "buffer.h"
2 #include <stdarg.h>
3 #include <stdlib.h>
4 #include <string.h>
6 UcxBuffer *ucx_buffer_new(void *space, size_t length, int flags) {
7 UcxBuffer *buffer = (UcxBuffer*) malloc(sizeof(UcxBuffer));
8 if (buffer) {
9 buffer->flags = flags;
10 if (!space) {
11 buffer->space = malloc(length);
12 if (!buffer->space) {
13 free(buffer);
14 return NULL;
15 }
16 memset(buffer->space, 0, length);
17 buffer->flags |= UCX_BUFFER_AUTOFREE;
18 } else {
19 buffer->space = space;
20 }
21 buffer->size = length;
23 buffer->pos = 0;
24 }
26 return buffer;
27 }
29 void ucx_buffer_free(UcxBuffer *buffer) {
30 if ((buffer->flags & UCX_BUFFER_AUTOFREE) == UCX_BUFFER_AUTOFREE) {
31 free(buffer->space);
32 }
33 free(buffer);
34 }
36 UcxBuffer *ucx_buffer_extract(
37 UcxBuffer *src, size_t start, size_t length, int flags) {
38 if (length == 0) {
39 length = src->size - start;
40 }
41 if (start+length > src->size) {
42 return NULL;
43 }
45 UcxBuffer *dst = (UcxBuffer*) malloc(sizeof(UcxBuffer));
46 if (dst) {
47 dst->space = malloc(length);
48 if (!dst->space) {
49 free(dst);
50 return NULL;
51 }
52 dst->size = length;
53 dst->flags = flags | UCX_BUFFER_AUTOFREE;
54 dst->pos = 0;
55 memcpy(dst->space, (char*)src->space+start, length);
56 }
57 return dst;
58 }
60 int ucx_buffer_seek(UcxBuffer *buffer, off_t offset, int whence) {
61 off_t npos;
62 switch (whence) {
63 case SEEK_SET:
64 npos = 0;
65 break;
66 case SEEK_CUR:
67 npos = buffer->pos;
68 break;
69 case SEEK_END:
70 npos = strlen(buffer->space);
71 break;
72 }
74 npos += offset;
76 if (npos < 0 || npos > buffer->size) {
77 return -1;
78 } else {
79 buffer->pos = npos;
80 return 0;
81 }
83 }
85 int ucx_buffer_eof(UcxBuffer *buffer) {
86 return buffer->pos >= buffer->size;
87 }
89 size_t ucx_bufio(void* d, size_t s, size_t n, UcxBuffer *b, _Bool read) {
90 size_t len = s*n;
91 if (b->pos + len > b->size) {
92 if ((b->flags & UCX_BUFFER_AUTOEXTEND) == UCX_BUFFER_AUTOEXTEND) {
93 size_t newsize = b->size;
94 while (b->pos + len > newsize) newsize <<= 1;
95 void *newspace = realloc(b->space, newsize);
96 if (newspace) {
97 memset((char*)newspace+b->size, 0, newsize-b->size);
98 b->space = newspace;
99 b->size = newsize;
100 } else {
101 len = -1;
102 }
103 } else {
104 len = b->size - b->pos;
105 if (s > 1) len -= len%s;
106 }
107 }
109 if (len <= 0) {
110 return len;
111 }
113 if (read) {
114 memcpy(d, (char*)b->space+b->pos, len);
115 } else {
116 memcpy((char*)b->space+b->pos, d, len);
117 }
118 b->pos += len;
120 return len;
121 }
123 int ucx_buffer_putc(UcxBuffer *buffer, int c) {
124 if (ucx_buffer_eof(buffer)) {
125 return EOF;
126 } else {
127 c &= 0xFF;
128 ((char*)(buffer->space))[buffer->pos] = (char) c;
129 buffer->pos++;
130 return c;
131 }
132 }
134 int ucx_buffer_getc(UcxBuffer *buffer) {
135 if (ucx_buffer_eof(buffer)) {
136 return EOF;
137 } else {
138 int c = ((char*)(buffer->space))[buffer->pos];
139 buffer->pos++;
140 return c;
141 }
142 }