ucx/buffer.c

changeset 76
655020a30e77
parent 69
fb59270b1de3
child 78
af355652f271
     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 +}

mercurial