ucx/buffer.c

Sun, 04 Nov 2012 20:50:12 +0100

author
Mike Becker <universe@uap-core.de>
date
Sun, 04 Nov 2012 20:50:12 +0100
changeset 75
990734f548ef
parent 69
fb59270b1de3
child 76
655020a30e77
permissions
-rw-r--r--

fixed some compiler warnings

#include "buffer.h"
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>

UcxBuffer *ucx_buffer_new(void *space, size_t length, int flags) {
    UcxBuffer *buffer = (UcxBuffer*) malloc(sizeof(UcxBuffer));
    if (buffer) {
        buffer->flags = flags;
        if (!space) {
            buffer->space = malloc(length);
            if (!buffer->space) {
                free(buffer);
                return NULL;
            }
            memset(buffer->space, 0, length);
            buffer->flags |= UCX_BUFFER_AUTOFREE;
        } else {
            buffer->space = space;
        }
        buffer->size = length;

        buffer->pos = 0;
    }

    return buffer;
}

void ucx_buffer_free(UcxBuffer *buffer) {
    if ((buffer->flags & UCX_BUFFER_AUTOFREE) == UCX_BUFFER_AUTOFREE) {
        free(buffer->space);
    }
    free(buffer);
}

UcxBuffer *restrict ucx_buffer_extract(
        UcxBuffer *restrict src, size_t start, size_t length, int flags) {
    if (length == 0) {
        length = src->size - start;
    }
    if (start+length > src->size) {
        return NULL;
    }

    UcxBuffer *restrict dst = (UcxBuffer*) malloc(sizeof(UcxBuffer));
    if (dst) {
        dst->space = malloc(length);
        if (!dst->space) {
            free(dst);
            return NULL;
        }
        dst->size = length;
        dst->flags = flags | UCX_BUFFER_AUTOFREE;
        dst->pos = 0;
        memcpy(dst->space, (char*)src->space+start, length);
    }
    return dst;
}

int ucx_buffer_seek(UcxBuffer *buffer, off_t offset, int whence) {
    off_t npos;
    switch (whence) {
    case SEEK_SET:
        npos = 0;
        break;
    case SEEK_CUR:
        npos = buffer->pos;
        break;
    case SEEK_END:
        npos = strlen((const char*) buffer->space);
        break;
    }

    npos += offset;

    if (npos < 0 || npos > buffer->size) {
        return -1;
    } else {
        buffer->pos = npos;
        return 0;
    }

}

int ucx_buffer_eof(UcxBuffer *buffer) {
    return buffer->pos >= buffer->size;
}

size_t ucx_bufio(void* d, size_t s, size_t n, UcxBuffer *b, _Bool read) {
    size_t len = s*n;
    if (b->pos + len > b->size) {
        if ((b->flags & UCX_BUFFER_AUTOEXTEND) == UCX_BUFFER_AUTOEXTEND) {
            size_t newsize = b->size;
            while (b->pos + len > newsize) newsize <<= 1;
            void *newspace = realloc(b->space, newsize);
            if (newspace) {
                memset((char*)newspace+b->size, 0, newsize-b->size);
                b->space = newspace;
                b->size = newsize;
            } else {
                len = -1;
            }
        } else {
            len = b->size - b->pos;
            if (s > 1) len -= len%s;
        }
    }

    if (len <= 0) {
        return len;
    }

    if (read) {
        memcpy(d, (char*)b->space+b->pos, len);
    } else {
        memcpy((char*)b->space+b->pos, d, len);
    }
    b->pos += len;

    return len;
}

int ucx_buffer_putc(UcxBuffer *buffer, int c) {
    if (ucx_buffer_eof(buffer)) {
        return EOF;
    } else {
        c &= 0xFF;
        ((char*)(buffer->space))[buffer->pos] = (char) c;
        buffer->pos++;
        return c;
    }
}

int ucx_buffer_getc(UcxBuffer *buffer) {
    if (ucx_buffer_eof(buffer)) {
        return EOF;
    } else {
        int c = ((char*)(buffer->space))[buffer->pos];
        buffer->pos++;
        return c;
    }
}

mercurial