ucx/buffer.c

Thu, 28 Feb 2013 08:50:24 +0100

author
Mike Becker <universe@uap-core.de>
date
Thu, 28 Feb 2013 08:50:24 +0100
changeset 103
08018864fb91
parent 95
ecfdc1c4a552
child 140
15f871f50bfd
permissions
-rw-r--r--

added license and copyright notice to all files

universe@103 1 /*
universe@103 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
universe@103 3 *
universe@103 4 * Copyright 2013 Olaf Wintermann. All rights reserved.
universe@103 5 *
universe@103 6 * Redistribution and use in source and binary forms, with or without
universe@103 7 * modification, are permitted provided that the following conditions are met:
universe@103 8 *
universe@103 9 * 1. Redistributions of source code must retain the above copyright
universe@103 10 * notice, this list of conditions and the following disclaimer.
universe@103 11 *
universe@103 12 * 2. Redistributions in binary form must reproduce the above copyright
universe@103 13 * notice, this list of conditions and the following disclaimer in the
universe@103 14 * documentation and/or other materials provided with the distribution.
universe@103 15 *
universe@103 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
universe@103 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
universe@103 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
universe@103 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
universe@103 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
universe@103 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
universe@103 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
universe@103 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
universe@103 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
universe@103 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
universe@103 26 * POSSIBILITY OF SUCH DAMAGE.
universe@103 27 */
universe@103 28
universe@60 29 #include "buffer.h"
universe@56 30 #include <stdarg.h>
universe@56 31 #include <stdlib.h>
universe@56 32 #include <string.h>
universe@56 33
olaf@76 34 UcxBuffer *ucx_buffer_new(void *space, size_t size, int flags) {
universe@60 35 UcxBuffer *buffer = (UcxBuffer*) malloc(sizeof(UcxBuffer));
universe@60 36 if (buffer) {
universe@61 37 buffer->flags = flags;
universe@56 38 if (!space) {
olaf@78 39 buffer->space = (char*)malloc(size);
universe@60 40 if (!buffer->space) {
universe@60 41 free(buffer);
universe@56 42 return NULL;
universe@56 43 }
olaf@76 44 memset(buffer->space, 0, size);
universe@61 45 buffer->flags |= UCX_BUFFER_AUTOFREE;
universe@56 46 } else {
olaf@78 47 buffer->space = (char*)space;
universe@56 48 }
olaf@76 49 buffer->capacity = size;
olaf@76 50 buffer->size = 0;
universe@56 51
universe@60 52 buffer->pos = 0;
universe@56 53 }
universe@56 54
universe@60 55 return buffer;
universe@56 56 }
universe@56 57
universe@60 58 void ucx_buffer_free(UcxBuffer *buffer) {
universe@63 59 if ((buffer->flags & UCX_BUFFER_AUTOFREE) == UCX_BUFFER_AUTOFREE) {
universe@60 60 free(buffer->space);
universe@56 61 }
universe@60 62 free(buffer);
universe@56 63 }
universe@56 64
olaf@76 65 UcxBuffer* ucx_buffer_extract(
olaf@76 66 UcxBuffer *src, size_t start, size_t length, int flags) {
olaf@76 67 if(src->size == 0) {
olaf@76 68 return NULL;
olaf@76 69 }
universe@62 70 if (length == 0) {
universe@62 71 length = src->size - start;
universe@62 72 }
universe@62 73 if (start+length > src->size) {
universe@62 74 return NULL;
universe@62 75 }
universe@62 76
olaf@76 77 UcxBuffer *dst = (UcxBuffer*) malloc(sizeof(UcxBuffer));
universe@62 78 if (dst) {
olaf@78 79 dst->space = (char*)malloc(length);
universe@62 80 if (!dst->space) {
universe@62 81 free(dst);
universe@62 82 return NULL;
universe@62 83 }
olaf@76 84 dst->capacity = length;
universe@62 85 dst->size = length;
universe@62 86 dst->flags = flags | UCX_BUFFER_AUTOFREE;
universe@62 87 dst->pos = 0;
olaf@76 88 memcpy(dst->space, src->space+start, length);
universe@62 89 }
universe@62 90 return dst;
universe@62 91 }
universe@62 92
universe@60 93 int ucx_buffer_seek(UcxBuffer *buffer, off_t offset, int whence) {
universe@95 94 size_t npos = 0;
universe@56 95 switch (whence) {
universe@56 96 case SEEK_SET:
universe@56 97 npos = 0;
universe@56 98 break;
universe@56 99 case SEEK_CUR:
universe@60 100 npos = buffer->pos;
universe@56 101 break;
universe@56 102 case SEEK_END:
olaf@76 103 npos = buffer->size;
universe@56 104 break;
universe@56 105 }
universe@56 106
universe@56 107 npos += offset;
olaf@76 108
universe@95 109 if (npos > buffer->size) {
universe@56 110 return -1;
universe@56 111 } else {
universe@60 112 buffer->pos = npos;
universe@56 113 return 0;
universe@56 114 }
universe@56 115
universe@56 116 }
universe@56 117
universe@60 118 int ucx_buffer_eof(UcxBuffer *buffer) {
universe@62 119 return buffer->pos >= buffer->size;
universe@56 120 }
universe@56 121
olaf@76 122 int ucx_buffer_extend(UcxBuffer *buffer, size_t len) {
olaf@76 123 size_t newcap = buffer->capacity;
olaf@76 124 while (buffer->pos + len > newcap) newcap <<= 1;
olaf@76 125
olaf@78 126 char *newspace = (char*)realloc(buffer->space, newcap);
olaf@76 127 if (newspace) {
olaf@76 128 memset(newspace+buffer->size, 0, newcap-buffer->size);
olaf@76 129 buffer->space = newspace;
olaf@76 130 buffer->capacity = newcap;
olaf@76 131 } else {
olaf@76 132 return -1;
olaf@76 133 }
olaf@76 134
olaf@76 135 return 0;
olaf@76 136 }
olaf@76 137
olaf@76 138 size_t ucx_buffer_write(const void *ptr, size_t size, size_t nitems,
olaf@76 139 UcxBuffer *buffer) {
olaf@76 140 size_t len = size * nitems;
olaf@76 141 if (buffer->pos + len > buffer->capacity) {
olaf@76 142 if ((buffer->flags & UCX_BUFFER_AUTOEXTEND) == UCX_BUFFER_AUTOEXTEND) {
olaf@76 143 if(ucx_buffer_extend(buffer, len)) {
olaf@76 144 return -1;
universe@64 145 }
universe@64 146 } else {
olaf@76 147 len = buffer->capacity - buffer->pos;
olaf@76 148 if (size > 1) len -= len%size;
universe@64 149 }
universe@56 150 }
olaf@76 151
universe@64 152 if (len <= 0) {
universe@64 153 return len;
universe@56 154 }
olaf@76 155
olaf@76 156 memcpy(buffer->space + buffer->pos, ptr, len);
olaf@76 157 buffer->pos += len;
olaf@76 158 if(buffer->pos > buffer->size) {
olaf@76 159 buffer->size = buffer->pos;
olaf@76 160 }
olaf@76 161
olaf@76 162 return len / size;
olaf@76 163 }
universe@56 164
olaf@76 165 size_t ucx_buffer_read(void *ptr, size_t size, size_t nitems,
olaf@76 166 UcxBuffer *buffer) {
olaf@76 167 size_t len = size * nitems;
olaf@76 168 if (buffer->pos + len > buffer->size) {
olaf@76 169 len = buffer->size - buffer->pos;
olaf@76 170 if (size > 1) len -= len%size;
universe@56 171 }
olaf@76 172
olaf@76 173 if (len <= 0) {
olaf@76 174 return len;
olaf@76 175 }
olaf@76 176
olaf@76 177 memcpy(ptr, buffer->space + buffer->pos, len);
olaf@76 178 buffer->pos += len;
olaf@76 179
olaf@76 180 return len / size;
universe@56 181 }
universe@56 182
universe@60 183 int ucx_buffer_putc(UcxBuffer *buffer, int c) {
olaf@76 184 if(buffer->pos >= buffer->capacity) {
olaf@76 185 if ((buffer->flags & UCX_BUFFER_AUTOEXTEND) == UCX_BUFFER_AUTOEXTEND) {
olaf@76 186 if(ucx_buffer_extend(buffer, 1)) {
olaf@76 187 return EOF;
olaf@76 188 }
olaf@76 189 } else {
olaf@76 190 return EOF;
olaf@76 191 }
universe@56 192 }
olaf@76 193
olaf@76 194 c &= 0xFF;
olaf@76 195 buffer->space[buffer->pos] = (char) c;
olaf@76 196 buffer->pos++;
olaf@76 197 if(buffer->pos > buffer->size) {
olaf@76 198 buffer->size = buffer->pos;
olaf@76 199 }
olaf@76 200 return c;
universe@56 201 }
universe@56 202
universe@60 203 int ucx_buffer_getc(UcxBuffer *buffer) {
universe@60 204 if (ucx_buffer_eof(buffer)) {
universe@56 205 return EOF;
universe@56 206 } else {
olaf@76 207 int c = buffer->space[buffer->pos];
universe@60 208 buffer->pos++;
universe@56 209 return c;
universe@56 210 }
universe@56 211 }
olaf@76 212
olaf@76 213 size_t ucx_buffer_generic_copy(void *s1, void *s2,
olaf@76 214 read_func readfnc, write_func writefnc, size_t bufsize) {
olaf@76 215 size_t ncp = 0;
olaf@78 216 char *buf = (char*)malloc(bufsize);
olaf@76 217 if(buf == NULL) {
olaf@76 218 return 0;
olaf@76 219 }
olaf@76 220
olaf@76 221 size_t r;
olaf@76 222 while((r = readfnc(buf, 1, bufsize, s1)) != 0) {
olaf@76 223 r = writefnc(buf, 1, r, s2);
olaf@76 224 ncp += r;
olaf@76 225 if(r == 0) {
olaf@76 226 break;
olaf@76 227 }
olaf@76 228 }
olaf@76 229
olaf@76 230 free(buf);
olaf@76 231 return ncp;
olaf@76 232 }
olaf@86 233
olaf@86 234 size_t ucx_buffer_generic_ncopy(void *s1, void *s2,
olaf@86 235 read_func readfnc, write_func writefnc, size_t bufsize, size_t n) {
olaf@86 236 if(n == 0) {
olaf@86 237 return 0;
olaf@86 238 }
olaf@86 239
olaf@86 240 size_t ncp = 0;
olaf@86 241 char *buf = (char*)malloc(bufsize);
olaf@86 242 if(buf == NULL) {
olaf@86 243 return 0;
olaf@86 244 }
olaf@86 245
olaf@86 246 size_t r;
olaf@86 247 size_t rn = bufsize > n ? n : bufsize;
olaf@86 248 while((r = readfnc(buf, 1, rn, s1)) != 0) {
olaf@86 249 r = writefnc(buf, 1, r, s2);
olaf@86 250 ncp += r;
olaf@86 251 n -= r;
olaf@86 252 rn = bufsize > n ? n : bufsize;
olaf@86 253 if(r == 0 || n == 0) {
olaf@86 254 break;
olaf@86 255 }
olaf@86 256 }
olaf@86 257
olaf@86 258 free(buf);
olaf@86 259 return ncp;
olaf@86 260 }

mercurial