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

     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 }

mercurial