universe@56: #include "memstream.h" universe@56: #include universe@56: #include universe@56: #include universe@56: olaf@57: struct UcxMemstream { universe@56: void *space; olaf@57: off_t pos; universe@56: size_t length; universe@56: _Bool autofree; universe@56: }; universe@56: olaf@57: UcxMemstream *ucx_memopen(void *space, size_t length) { universe@56: UcxMemstream *stream = (UcxMemstream*) malloc(sizeof(UcxMemstream)); universe@56: if (stream) { universe@56: if (!space) { universe@56: stream->space = malloc(length); universe@56: if (!stream->space) { universe@56: free(stream); universe@56: return NULL; universe@56: } universe@56: memset(stream->space, 0, length); universe@56: stream->autofree = 1; universe@56: } else { universe@56: stream->space = space; universe@56: stream->autofree = 0; universe@56: } universe@56: stream->length = length; universe@56: universe@56: stream->pos = 0; universe@56: } universe@56: universe@56: return stream; universe@56: } universe@56: universe@56: void ucx_memclose(UcxMemstream *stream) { universe@56: if (stream->autofree) { universe@56: free(stream->space); universe@56: } universe@56: free(stream); universe@56: } universe@56: olaf@57: int ucx_memseek(UcxMemstream *stream, off_t offset, int whence) { olaf@57: off_t npos; universe@56: switch (whence) { universe@56: case SEEK_SET: universe@56: npos = 0; universe@56: break; universe@56: case SEEK_CUR: universe@56: npos = stream->pos; universe@56: break; universe@56: case SEEK_END: universe@56: npos = strlen(stream->space); universe@56: break; universe@56: } universe@56: universe@56: npos += offset; universe@56: universe@56: if (npos < 0 || npos > stream->length) { universe@56: return -1; universe@56: } else { universe@56: stream->pos = npos; universe@56: return 0; universe@56: } universe@56: universe@56: } universe@56: universe@56: int ucx_memeof(UcxMemstream *stream) { universe@56: return stream->pos >= stream->length; universe@56: } universe@56: universe@56: size_t ucx_memtell(UcxMemstream *stream) { universe@56: return stream->pos; universe@56: } universe@56: universe@56: size_t ucx_memio(void* d, size_t s, size_t n, UcxMemstream *m, _Bool read) { universe@56: size_t len; universe@56: if (m->pos + s*n > m->length) { universe@58: len = m->length - m->pos; universe@58: if (s > 1) len -= len%s; universe@56: } else { universe@56: len = s*n; universe@56: } universe@56: universe@56: if (len == 0) { universe@56: return 0; universe@56: } universe@56: universe@56: if (read) { olaf@57: memcpy(d, (char*)m->space+m->pos, len); universe@56: } else { olaf@57: memcpy((char*)m->space+m->pos, d, len); universe@56: } universe@56: m->pos += len; universe@56: universe@56: return len; universe@56: } universe@56: universe@56: int ucx_memputc(UcxMemstream *stream, int c) { universe@56: if (ucx_memeof(stream)) { universe@56: return EOF; universe@56: } else { universe@56: c &= 0xFF; universe@56: ((char*)(stream->space))[stream->pos] = (char) c; universe@56: stream->pos++; universe@56: return c; universe@56: } universe@56: } universe@56: universe@56: int ucx_memgetc(UcxMemstream *stream) { universe@56: if (ucx_memeof(stream)) { universe@56: return EOF; universe@56: } else { universe@56: int c = ((char*)(stream->space))[stream->pos]; universe@56: stream->pos++; universe@56: return c; universe@56: } universe@56: }