ucx/memstream.c

Tue, 09 Oct 2012 16:46:29 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Tue, 09 Oct 2012 16:46:29 +0200
changeset 57
e18157c52985
parent 56
76caac0da4a0
child 58
733f22fca61a
permissions
-rw-r--r--

some fixes

     1 #include "memstream.h"
     2 #include <stdarg.h>
     3 #include <stdlib.h>
     4 #include <string.h>
     6 struct UcxMemstream {
     7     void *space;
     8     off_t pos;
     9     size_t length;
    10     _Bool autofree;
    11 };
    13 UcxMemstream *ucx_memopen(void *space, size_t length) {
    14     UcxMemstream *stream = (UcxMemstream*) malloc(sizeof(UcxMemstream));
    15     if (stream) {
    16         if (!space) {
    17             stream->space = malloc(length);
    18             if (!stream->space) {
    19                 free(stream);
    20                 return NULL;
    21             }
    22             memset(stream->space, 0, length);
    23             stream->autofree = 1;
    24         } else {
    25             stream->space = space;
    26             stream->autofree = 0;
    27         }
    28         stream->length = length;
    30         stream->pos = 0;
    31     }
    33     return stream;
    34 }
    36 void ucx_memclose(UcxMemstream *stream) {
    37     if (stream->autofree) {
    38         free(stream->space);
    39     }
    40     free(stream);
    41 }
    43 int ucx_memseek(UcxMemstream *stream, off_t offset, int whence) {
    44     off_t npos;
    45     switch (whence) {
    46     case SEEK_SET:
    47         npos = 0;
    48         break;
    49     case SEEK_CUR:
    50         npos = stream->pos;
    51         break;
    52     case SEEK_END:
    53         npos = strlen(stream->space);
    54         break;
    55     }
    57     npos += offset;
    59     if (npos < 0 || npos > stream->length) {
    60         return -1;
    61     } else {
    62         stream->pos = npos;
    63         return 0;
    64     }
    66 }
    68 int ucx_memeof(UcxMemstream *stream) {
    69     return stream->pos >= stream->length;
    70 }
    72 int ucx_memoverflow(UcxMemstream *stream) {
    73     return stream->pos > stream->length;
    74 }
    76 size_t ucx_memtell(UcxMemstream *stream) {
    77     return stream->pos;
    78 }
    80 size_t ucx_memio(void* d, size_t s, size_t n, UcxMemstream *m, _Bool read) {
    81     size_t len;
    82     if (m->pos + s*n > m->length) {
    83         if (ucx_memoverflow(m)) {
    84             len = 0;
    85         } else {
    86             len = m->length - m->pos;
    87             if (s > 1) len -= len%s;
    88         }
    89     } else {
    90         len = s*n;
    91     }
    93     if (len == 0) {
    94         return 0;
    95     }
    97     if (read) {
    98         memcpy(d, (char*)m->space+m->pos, len);
    99     } else {
   100         memcpy((char*)m->space+m->pos, d, len);
   101     }
   102     m->pos += len;
   104     return len;
   105 }
   107 int ucx_memputc(UcxMemstream *stream, int c) {
   108     if (ucx_memeof(stream)) {
   109         return EOF;
   110     } else {
   111         c &= 0xFF;
   112         ((char*)(stream->space))[stream->pos] = (char) c;
   113         stream->pos++;
   114         return c;
   115     }
   116 }
   118 int ucx_memgetc(UcxMemstream *stream) {
   119     if (ucx_memeof(stream)) {
   120         return EOF;
   121     } else {
   122         int c = ((char*)(stream->space))[stream->pos];
   123         stream->pos++;
   124         return c;
   125     }
   126 }
   128 int ucx_memprintf(UcxMemstream *stream, const char* format, ...) {
   129     va_list v;
   130     va_start(v, format);
   131     int r = vsprintf((char*)stream->space+stream->pos, format, v);
   132     va_end(v);
   134     stream->pos += r;
   136     return r;
   137 }
   139 int ucx_memscanf(UcxMemstream *stream, const char* format, ...) {
   141     /* TODO: vsscanf returns the number of fields read,
   142      * we need the number of bytes */
   144     va_list v;
   145     va_start(v, format);
   146     int r = vsscanf((char*)stream->space+stream->pos, format, v);
   147     va_end(v);
   149     stream->pos += r;
   151     return r;
   152 }

mercurial