src/ucx/buffer.c

Tue, 23 Aug 2016 13:49:38 +0200

author
Mike Becker <universe@uap-core.de>
date
Tue, 23 Aug 2016 13:49:38 +0200
changeset 39
ac35daceb24c
permissions
-rw-r--r--

adds UCX + changes how the input file is read (uses an consecutive memory area now)

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

mercurial