예제 #1
0
FILE *open_memstream(char **ptr, size_t *sizeloc) {
    if (ptr && sizeloc) {
        struct memstream *ms = calloc(1, sizeof(struct memstream));
        FILE *fp = 0;
        if (!ms)
            return 0; /* errno == ENOMEM */
        ms->position = ms->size = 0;
        ms->capacity = 4096;
        ms->contents = calloc(ms->capacity, 1);
        if (!ms->contents) {
            free(ms);
            return 0;
        } /* errno == ENOMEM */
        ms->ptr = ptr;
        ms->sizeloc = sizeloc;
        memstream_print(ms);
        fp = funopen(ms, memstream_read, memstream_write, memstream_seek,
                     memstream_close);
        if (!fp) {
            free(ms->contents);
            free(ms);
            return 0; /* errno set by funopen */
        }
        *ptr = ms->contents;
        *sizeloc = ms->size;
        return fp;
    }
    errno = EINVAL;
    return 0;
}
예제 #2
0
static fpos_t memstream_seek(void *cookie, fpos_t offset, int whence) {
    struct memstream *ms = (struct memstream *)cookie;
    fpos_t pos = 0;
    memstream_check(ms);
    memstream_info(("memstream_seek %p %i %i\n", ms, (int)offset, whence));
    switch (whence) {
    case SEEK_SET:
        pos = offset;
        break;
    case SEEK_CUR:
        pos = ms->position + offset;
        break;
    case SEEK_END:
        pos = ms->size + offset;
        break;
    default:
        errno = EINVAL;
        return -1;
    }
    if (pos >= ms->capacity)
        memstream_grow(ms, pos);
    ms->position = pos;
    if (ms->size < ms->position)
        *ms->sizeloc = ms->size = ms->position;
    memstream_print(ms);
    memstream_info(("=> %i\n", (int)pos));
    assert(ms->size < ms->capacity && ms->contents[ms->size] == 0);
    return pos;
}
예제 #3
0
static int memstream_read(void *cookie, char *buf, int count)
{
    struct memstream *ms= (struct memstream *)cookie;			memstream_check(ms);
    int n= min(ms->size - ms->position, count);				memstream_info(("memstream_read %p %i\n", ms, count));
    if (n < 1) return 0;
    memcpy(buf, ms->contents, n);
    ms->position += n;							memstream_print(ms);
    return n;
}
예제 #4
0
static int memstream_write(void *cookie, const char *buf, int count)
{
    struct memstream *ms= (struct memstream *)cookie;			memstream_check(ms);
    if (ms->capacity <= ms->position + count)
	if (memstream_grow(ms, ms->position + count) < 0)		/* errno == ENOMEM */
	    return -1;
    memcpy(ms->contents + ms->position, buf, count);			memstream_info(("memstream_write %p %i\n", ms, count));
    ms->position += count;
    if (ms->size < ms->position) *ms->sizeloc= ms->size= ms->position;	memstream_print(ms);
									assert(ms->size < ms->capacity);
									assert(ms->contents[ms->size] == 0);
    return count;
}