ucx/buffer.c

Tue, 13 Aug 2013 14:20:12 +0200

author
Mike Becker <universe@uap-core.de>
date
Tue, 13 Aug 2013 14:20:12 +0200
changeset 140
15f871f50bfd
parent 103
08018864fb91
child 169
279dd3ca7a77
permissions
-rw-r--r--

completed documentation + changed API for buffer/stream generic copy functions

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@140 94 size_t npos;
universe@56 95 switch (whence) {
universe@56 96 case SEEK_CUR:
universe@60 97 npos = buffer->pos;
universe@56 98 break;
universe@56 99 case SEEK_END:
olaf@76 100 npos = buffer->size;
universe@56 101 break;
universe@140 102 default:
universe@140 103 npos = 0;
universe@56 104 }
universe@56 105
universe@56 106 npos += offset;
olaf@76 107
universe@95 108 if (npos > buffer->size) {
universe@56 109 return -1;
universe@56 110 } else {
universe@60 111 buffer->pos = npos;
universe@56 112 return 0;
universe@56 113 }
universe@56 114
universe@56 115 }
universe@56 116
universe@60 117 int ucx_buffer_eof(UcxBuffer *buffer) {
universe@62 118 return buffer->pos >= buffer->size;
universe@56 119 }
universe@56 120
olaf@76 121 int ucx_buffer_extend(UcxBuffer *buffer, size_t len) {
olaf@76 122 size_t newcap = buffer->capacity;
olaf@76 123 while (buffer->pos + len > newcap) newcap <<= 1;
olaf@76 124
olaf@78 125 char *newspace = (char*)realloc(buffer->space, newcap);
olaf@76 126 if (newspace) {
olaf@76 127 memset(newspace+buffer->size, 0, newcap-buffer->size);
olaf@76 128 buffer->space = newspace;
olaf@76 129 buffer->capacity = newcap;
olaf@76 130 } else {
olaf@76 131 return -1;
olaf@76 132 }
olaf@76 133
olaf@76 134 return 0;
olaf@76 135 }
olaf@76 136
olaf@76 137 size_t ucx_buffer_write(const void *ptr, size_t size, size_t nitems,
olaf@76 138 UcxBuffer *buffer) {
olaf@76 139 size_t len = size * nitems;
olaf@76 140 if (buffer->pos + len > buffer->capacity) {
olaf@76 141 if ((buffer->flags & UCX_BUFFER_AUTOEXTEND) == UCX_BUFFER_AUTOEXTEND) {
olaf@76 142 if(ucx_buffer_extend(buffer, len)) {
olaf@76 143 return -1;
universe@64 144 }
universe@64 145 } else {
olaf@76 146 len = buffer->capacity - buffer->pos;
olaf@76 147 if (size > 1) len -= len%size;
universe@64 148 }
universe@56 149 }
olaf@76 150
universe@64 151 if (len <= 0) {
universe@64 152 return len;
universe@56 153 }
olaf@76 154
olaf@76 155 memcpy(buffer->space + buffer->pos, ptr, len);
olaf@76 156 buffer->pos += len;
olaf@76 157 if(buffer->pos > buffer->size) {
olaf@76 158 buffer->size = buffer->pos;
olaf@76 159 }
olaf@76 160
olaf@76 161 return len / size;
olaf@76 162 }
universe@56 163
olaf@76 164 size_t ucx_buffer_read(void *ptr, size_t size, size_t nitems,
olaf@76 165 UcxBuffer *buffer) {
olaf@76 166 size_t len = size * nitems;
olaf@76 167 if (buffer->pos + len > buffer->size) {
olaf@76 168 len = buffer->size - buffer->pos;
olaf@76 169 if (size > 1) len -= len%size;
universe@56 170 }
olaf@76 171
olaf@76 172 if (len <= 0) {
olaf@76 173 return len;
olaf@76 174 }
olaf@76 175
olaf@76 176 memcpy(ptr, buffer->space + buffer->pos, len);
olaf@76 177 buffer->pos += len;
olaf@76 178
olaf@76 179 return len / size;
universe@56 180 }
universe@56 181
universe@60 182 int ucx_buffer_putc(UcxBuffer *buffer, int c) {
olaf@76 183 if(buffer->pos >= buffer->capacity) {
olaf@76 184 if ((buffer->flags & UCX_BUFFER_AUTOEXTEND) == UCX_BUFFER_AUTOEXTEND) {
olaf@76 185 if(ucx_buffer_extend(buffer, 1)) {
olaf@76 186 return EOF;
olaf@76 187 }
olaf@76 188 } else {
olaf@76 189 return EOF;
olaf@76 190 }
universe@56 191 }
olaf@76 192
olaf@76 193 c &= 0xFF;
olaf@76 194 buffer->space[buffer->pos] = (char) c;
olaf@76 195 buffer->pos++;
olaf@76 196 if(buffer->pos > buffer->size) {
olaf@76 197 buffer->size = buffer->pos;
olaf@76 198 }
olaf@76 199 return c;
universe@56 200 }
universe@56 201
universe@60 202 int ucx_buffer_getc(UcxBuffer *buffer) {
universe@60 203 if (ucx_buffer_eof(buffer)) {
universe@56 204 return EOF;
universe@56 205 } else {
olaf@76 206 int c = buffer->space[buffer->pos];
universe@60 207 buffer->pos++;
universe@56 208 return c;
universe@56 209 }
universe@56 210 }
olaf@76 211
universe@140 212 size_t ucx_buffer_puts(UcxBuffer *buffer, char *str) {
universe@140 213 return ucx_buffer_write((const void*)str, 1, strlen(str), buffer);
olaf@76 214 }

mercurial