diff options
Diffstat (limited to 'lib/common/io_stdin.c')
-rw-r--r-- | lib/common/io_stdin.c | 182 |
1 files changed, 0 insertions, 182 deletions
diff --git a/lib/common/io_stdin.c b/lib/common/io_stdin.c deleted file mode 100644 index 4694989..0000000 --- a/lib/common/io_stdin.c +++ /dev/null @@ -1,182 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * io_stdin.c - * - * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at> - */ -#include "common.h" - -#include <stdlib.h> -#include <string.h> -#include <errno.h> - - -typedef struct { - sqfs_file_t base; - - const sparse_map_t *map; - sqfs_u64 offset; - sqfs_u64 real_size; - sqfs_u64 apparent_size; - FILE *fp; -} sqfs_file_stdinout_t; - - -static void stdinout_destroy(sqfs_object_t *base) -{ - free(base); -} - -static sqfs_u64 stdinout_get_size(const sqfs_file_t *base) -{ - return ((const sqfs_file_stdinout_t *)base)->apparent_size; -} - -static int stdinout_truncate(sqfs_file_t *base, sqfs_u64 size) -{ - (void)base; (void)size; - return SQFS_ERROR_IO; -} - -static int stdin_read_at(sqfs_file_t *base, sqfs_u64 offset, - void *buffer, size_t size) -{ - sqfs_file_stdinout_t *file = (sqfs_file_stdinout_t *)base; - size_t temp_size = 0; - sqfs_u8 *temp = NULL; - sqfs_u64 diff; - size_t ret; - - if (offset < file->offset) - return SQFS_ERROR_IO; - - if (offset > file->offset) { - temp_size = 1024; - temp = alloca(temp_size); - } - - if (offset >= file->real_size || (offset + size) > file->real_size) - return SQFS_ERROR_OUT_OF_BOUNDS; - - while (size > 0) { - if (ferror(file->fp)) - return SQFS_ERROR_IO; - - if (feof(file->fp)) - return SQFS_ERROR_OUT_OF_BOUNDS; - - if (offset > file->offset) { - diff = file->offset - offset; - diff = diff > (sqfs_u64)temp_size ? temp_size : diff; - - ret = fread(temp, 1, diff, file->fp); - } else { - ret = fread(buffer, 1, size, file->fp); - } - - if (offset <= file->offset) { - buffer = (char *)buffer + ret; - size -= ret; - offset += ret; - } - - file->offset += ret; - } - - return 0; -} - -static int stdin_read_condensed(sqfs_file_t *base, sqfs_u64 offset, - void *buffer, size_t size) -{ - sqfs_file_stdinout_t *file = (sqfs_file_stdinout_t *)base; - sqfs_u64 poffset = 0, src_start; - size_t dst_start, diff, count; - const sparse_map_t *it; - int err; - - memset(buffer, 0, size); - - for (it = file->map; it != NULL; it = it->next) { - if (it->offset + it->count <= offset) { - poffset += it->count; - continue; - } - - if (it->offset >= offset + size) { - poffset += it->count; - continue; - } - - count = size; - - if (offset + count >= it->offset + it->count) - count = it->offset + it->count - offset; - - if (it->offset < offset) { - diff = offset - it->offset; - - src_start = poffset + diff; - dst_start = 0; - count -= diff; - } else if (it->offset > offset) { - diff = it->offset - offset; - - src_start = poffset; - dst_start = diff; - } else { - src_start = poffset; - dst_start = 0; - } - - err = stdin_read_at(base, src_start, - (char *)buffer + dst_start, count); - if (err) - return err; - - poffset += it->count; - } - - return 0; -} - -static int stdin_write_at(sqfs_file_t *base, sqfs_u64 offset, - const void *buffer, size_t size) -{ - (void)base; (void)offset; (void)buffer; (void)size; - return SQFS_ERROR_IO; -} - -sqfs_file_t *sqfs_get_stdin_file(FILE *fp, const sparse_map_t *map, - sqfs_u64 size) -{ - sqfs_file_stdinout_t *file = calloc(1, sizeof(*file)); - sqfs_file_t *base = (sqfs_file_t *)file; - const sparse_map_t *it; - - if (file == NULL) - return NULL; - - file->apparent_size = size; - file->map = map; - file->fp = fp; - - if (map != NULL) { - for (it = map; it != NULL; it = it->next) - file->real_size += map->count; - } else { - file->real_size = size; - } - - ((sqfs_object_t *)base)->destroy = stdinout_destroy; - base->write_at = stdin_write_at; - base->get_size = stdinout_get_size; - base->truncate = stdinout_truncate; - - if (map == NULL) { - base->read_at = stdin_read_at; - } else { - base->read_at = stdin_read_condensed; - } - return base; -} |