ucx/buffer.c

Wed, 10 Oct 2012 14:18:06 +0200

author
Mike Becker <universe@uap-core.de>
date
Wed, 10 Oct 2012 14:18:06 +0200
changeset 64
16590c9c497c
parent 63
1d3500806565
child 67
27e67e725d35
permissions
-rw-r--r--

added autoextend feature to buffer

and we celebrate the 50th test case

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

mercurial