diff options
author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2023-06-02 17:42:30 +0200 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2023-06-03 23:36:14 +0200 |
commit | 061fbc12fe49ff49088a644def3227d3800cd8a7 (patch) | |
tree | a9390a1c0610b3a93dddb7882956f1cb9a9ea37c /lib/io/src | |
parent | 3f7f3654d243275332d964f9ecbb79f9eb83a5d1 (diff) |
libio: consolidate add-hoc memory istream_t implementations
In several places, there are ad-hoc istream_t implementations that
read from a memory buffer to test something else stacked on top.
This commit consolidates those ad-hoc implmentations into a proper
one in libio, and uses the chance to remove external files for some
older tests that rely on file I/O instead.
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'lib/io/src')
-rw-r--r-- | lib/io/src/mem.c | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/lib/io/src/mem.c b/lib/io/src/mem.c new file mode 100644 index 0000000..4e9f9af --- /dev/null +++ b/lib/io/src/mem.c @@ -0,0 +1,85 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * mem.c + * + * Copyright (C) 2023 David Oberhollenzer <goliath@infraroot.at> + */ +#include "config.h" +#include "io/mem.h" +#include "compat.h" + +#include <stdlib.h> +#include <string.h> + +typedef struct { + istream_t base; + + sqfs_u8 *buffer; + size_t bufsz; + + const void *data; + size_t size; + + char *name; +} mem_istream_t; + +static int mem_in_precache(istream_t *strm) +{ + mem_istream_t *mem = (mem_istream_t *)strm; + size_t diff = mem->bufsz - strm->buffer_used; + + if (diff > mem->size) + diff = mem->size; + + if (diff > 0) { + memcpy(mem->buffer + strm->buffer_used, mem->data, diff); + strm->buffer_used += diff; + mem->data = (const char *)mem->data + diff; + mem->size -= diff; + } + + if (mem->size == 0) + strm->eof = true; + + return 0; +} + +static const char *mem_in_get_filename(istream_t *strm) +{ + return ((mem_istream_t *)strm)->name; +} + +static void mem_in_destroy(sqfs_object_t *obj) +{ + free(((mem_istream_t *)obj)->buffer); + free(((mem_istream_t *)obj)->name); + free(obj); +} + +istream_t *istream_memory_create(const char *name, size_t bufsz, + const void *data, size_t size) +{ + mem_istream_t *mem = calloc(1, sizeof(*mem)); + istream_t *strm = (istream_t *)mem; + + if (mem == NULL) + return NULL; + + sqfs_object_init(mem, mem_in_destroy, NULL); + + mem->name = strdup(name); + if (mem->name == NULL) + return sqfs_drop(mem); + + mem->buffer = malloc(bufsz); + if (mem->buffer == NULL) + return sqfs_drop(mem); + + mem->data = data; + mem->size = size; + mem->bufsz = bufsz; + strm->buffer = mem->buffer; + strm->precache = mem_in_precache; + strm->get_filename = mem_in_get_filename; + return strm; +} |