From cdccc69c62579b0c13b35fad0728079652b8f3c9 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Tue, 31 Jan 2023 11:21:30 +0100 Subject: Move library source into src sub-directory Signed-off-by: David Oberhollenzer --- lib/io/Makemodule.am | 17 ++-- lib/io/get_line.c | 118 --------------------------- lib/io/internal.h | 31 ------- lib/io/istream.c | 86 -------------------- lib/io/ostream.c | 68 ---------------- lib/io/printf.c | 30 ------- lib/io/src/get_line.c | 118 +++++++++++++++++++++++++++ lib/io/src/internal.h | 31 +++++++ lib/io/src/istream.c | 86 ++++++++++++++++++++ lib/io/src/ostream.c | 68 ++++++++++++++++ lib/io/src/printf.c | 30 +++++++ lib/io/src/unix/istream.c | 123 ++++++++++++++++++++++++++++ lib/io/src/unix/ostream.c | 173 +++++++++++++++++++++++++++++++++++++++ lib/io/src/win32/istream.c | 138 +++++++++++++++++++++++++++++++ lib/io/src/win32/ostream.c | 199 +++++++++++++++++++++++++++++++++++++++++++++ lib/io/src/xfrm/istream.c | 106 ++++++++++++++++++++++++ lib/io/src/xfrm/ostream.c | 144 ++++++++++++++++++++++++++++++++ lib/io/unix/istream.c | 123 ---------------------------- lib/io/unix/ostream.c | 173 --------------------------------------- lib/io/win32/istream.c | 138 ------------------------------- lib/io/win32/ostream.c | 199 --------------------------------------------- lib/io/xfrm/istream.c | 106 ------------------------ lib/io/xfrm/ostream.c | 144 -------------------------------- 23 files changed, 1223 insertions(+), 1226 deletions(-) delete mode 100644 lib/io/get_line.c delete mode 100644 lib/io/internal.h delete mode 100644 lib/io/istream.c delete mode 100644 lib/io/ostream.c delete mode 100644 lib/io/printf.c create mode 100644 lib/io/src/get_line.c create mode 100644 lib/io/src/internal.h create mode 100644 lib/io/src/istream.c create mode 100644 lib/io/src/ostream.c create mode 100644 lib/io/src/printf.c create mode 100644 lib/io/src/unix/istream.c create mode 100644 lib/io/src/unix/ostream.c create mode 100644 lib/io/src/win32/istream.c create mode 100644 lib/io/src/win32/ostream.c create mode 100644 lib/io/src/xfrm/istream.c create mode 100644 lib/io/src/xfrm/ostream.c delete mode 100644 lib/io/unix/istream.c delete mode 100644 lib/io/unix/ostream.c delete mode 100644 lib/io/win32/istream.c delete mode 100644 lib/io/win32/ostream.c delete mode 100644 lib/io/xfrm/istream.c delete mode 100644 lib/io/xfrm/ostream.c (limited to 'lib/io') diff --git a/lib/io/Makemodule.am b/lib/io/Makemodule.am index 918ce50..c331124 100644 --- a/lib/io/Makemodule.am +++ b/lib/io/Makemodule.am @@ -1,19 +1,16 @@ -libio_a_SOURCES = lib/io/internal.h -libio_a_SOURCES += include/io/istream.h lib/io/ostream.c lib/io/printf.c -libio_a_SOURCES += include/io/ostream.h lib/io/istream.c lib/io/get_line.c -libio_a_SOURCES += include/io/xfrm.h include/io/file.h include/io/std.h -libio_a_SOURCES += lib/io/xfrm/ostream.c lib/io/xfrm/istream.c +libio_a_SOURCES = include/io/istream.h include/io/ostream.h include/io/xfrm.h \ + include/io/file.h include/io/std.h \ + lib/io/src/internal.h lib/io/src/ostream.c lib/io/src/printf.c \ + lib/io/src/istream.c lib/io/src/get_line.c lib/io/src/xfrm/ostream.c \ + lib/io/src/xfrm/istream.c libio_a_CFLAGS = $(AM_CFLAGS) $(ZLIB_CFLAGS) $(XZ_CFLAGS) libio_a_CFLAGS += $(ZSTD_CFLAGS) $(BZIP2_CFLAGS) -libio_a_CPPFLAGS = $(AM_CPPFLAGS) if WINDOWS -libio_a_SOURCES += lib/io/win32/ostream.c -libio_a_SOURCES += lib/io/win32/istream.c +libio_a_SOURCES += lib/io/src/win32/ostream.c lib/io/src/win32/istream.c libio_a_CFLAGS += -DWINVER=0x0600 -D_WIN32_WINNT=0x0600 else -libio_a_SOURCES += lib/io/unix/ostream.c -libio_a_SOURCES += lib/io/unix/istream.c +libio_a_SOURCES += lib/io/src/unix/ostream.c lib/io/src/unix/istream.c endif noinst_LIBRARIES += libio.a diff --git a/lib/io/get_line.c b/lib/io/get_line.c deleted file mode 100644 index f7e0b59..0000000 --- a/lib/io/get_line.c +++ /dev/null @@ -1,118 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * get_line.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "internal.h" - -static void ltrim(char *buffer) -{ - size_t i = 0; - - while (isspace(buffer[i])) - ++i; - - if (i > 0) - memmove(buffer, buffer + i, strlen(buffer + i) + 1); -} - -static void rtrim(char *buffer) -{ - size_t i = strlen(buffer); - - while (i > 0 && isspace(buffer[i - 1])) - --i; - - buffer[i] = '\0'; -} - -static size_t trim(char *buffer, int flags) -{ - if (flags & ISTREAM_LINE_LTRIM) - ltrim(buffer); - - if (flags & ISTREAM_LINE_RTRIM) - rtrim(buffer); - - return strlen(buffer); -} - -int istream_get_line(istream_t *strm, char **out, - size_t *line_num, int flags) -{ - char *line = NULL, *new; - size_t i, line_len = 0; - bool have_line = false; - - *out = NULL; - - for (;;) { - if (istream_precache(strm)) - return -1; - - if (strm->buffer_used == 0) { - if (line_len == 0) - goto out_eof; - - line_len = trim(line, flags); - - if (line_len == 0 && - (flags & ISTREAM_LINE_SKIP_EMPTY)) { - goto out_eof; - } - break; - } - - for (i = 0; i < strm->buffer_used; ++i) { - if (strm->buffer[i] == '\n') - break; - } - - if (i < strm->buffer_used) { - have_line = true; - strm->buffer_offset = i + 1; - - if (i > 0 && strm->buffer[i - 1] == '\r') - --i; - } else { - strm->buffer_offset = i; - } - - new = realloc(line, line_len + i + 1); - if (new == NULL) - goto fail_errno; - - line = new; - memcpy(line + line_len, strm->buffer, i); - line_len += i; - line[line_len] = '\0'; - - if (have_line) { - line_len = trim(line, flags); - - if (line_len == 0 && - (flags & ISTREAM_LINE_SKIP_EMPTY)) { - free(line); - line = NULL; - have_line = false; - *line_num += 1; - continue; - } - break; - } - } - - *out = line; - return 0; -fail_errno: - fprintf(stderr, "%s: " PRI_SZ ": %s.\n", strm->get_filename(strm), - *line_num, strerror(errno)); - free(line); - *out = NULL; - return -1; -out_eof: - free(line); - *out = NULL; - return 1; -} diff --git a/lib/io/internal.h b/lib/io/internal.h deleted file mode 100644 index 25a0196..0000000 --- a/lib/io/internal.h +++ /dev/null @@ -1,31 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * internal.h - * - * Copyright (C) 2019 David Oberhollenzer - */ -#ifndef INTERNAL_H -#define INTERNAL_H - -#include "config.h" -#include "compat.h" -#include "io/istream.h" -#include "io/ostream.h" -#include "io/file.h" -#include "io/xfrm.h" -#include "io/std.h" -#include "xfrm/compress.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define BUFSZ (262144) - -#endif /* INTERNAL_H */ diff --git a/lib/io/istream.c b/lib/io/istream.c deleted file mode 100644 index 64fa478..0000000 --- a/lib/io/istream.c +++ /dev/null @@ -1,86 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * istream.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "internal.h" - - -sqfs_s32 istream_read(istream_t *strm, void *data, size_t size) -{ - sqfs_s32 total = 0; - size_t diff; - - if (size > 0x7FFFFFFF) - size = 0x7FFFFFFF; - - while (size > 0) { - if (strm->buffer_offset >= strm->buffer_used) { - if (istream_precache(strm)) - return -1; - - if (strm->buffer_used == 0) - break; - } - - diff = strm->buffer_used - strm->buffer_offset; - if (diff > size) - diff = size; - - memcpy(data, strm->buffer + strm->buffer_offset, diff); - data = (char *)data + diff; - strm->buffer_offset += diff; - size -= diff; - total += diff; - } - - return total; -} - -int istream_precache(istream_t *strm) -{ - if (strm->buffer_offset >= strm->buffer_used) { - strm->buffer_offset = 0; - strm->buffer_used = 0; - } else if (strm->buffer_offset > 0) { - memmove(strm->buffer, - strm->buffer + strm->buffer_offset, - strm->buffer_used - strm->buffer_offset); - - strm->buffer_used -= strm->buffer_offset; - strm->buffer_offset = 0; - } - - if (strm->eof) - return 0; - - return strm->precache(strm); -} - -int istream_skip(istream_t *strm, sqfs_u64 size) -{ - size_t diff; - - while (size > 0) { - if (strm->buffer_offset >= strm->buffer_used) { - if (istream_precache(strm)) - return -1; - - if (strm->buffer_used == 0) { - fprintf(stderr, "%s: unexpected end-of-file\n", - strm->get_filename(strm)); - return -1; - } - } - - diff = strm->buffer_used - strm->buffer_offset; - if ((sqfs_u64)diff > size) - diff = size; - - strm->buffer_offset += diff; - size -= diff; - } - - return 0; -} diff --git a/lib/io/ostream.c b/lib/io/ostream.c deleted file mode 100644 index da0b7b3..0000000 --- a/lib/io/ostream.c +++ /dev/null @@ -1,68 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * ostream.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "internal.h" - - -static int append_sparse_fallback(ostream_t *strm, size_t size) -{ - char buffer[512]; - size_t diff; - - memset(buffer, 0, sizeof(buffer)); - - while (size > 0) { - diff = size < sizeof(buffer) ? size : sizeof(buffer); - - if (strm->append(strm, buffer, diff)) - return -1; - - size -= diff; - } - - return 0; -} - -int ostream_append_sparse(ostream_t *strm, size_t size) -{ - if (strm->append_sparse == NULL) - return append_sparse_fallback(strm, size); - - return strm->append_sparse(strm, size); -} - -sqfs_s32 ostream_append_from_istream(ostream_t *out, istream_t *in, - sqfs_u32 size) -{ - sqfs_s32 total = 0; - size_t diff; - - if (size > 0x7FFFFFFF) - size = 0x7FFFFFFF; - - while (size > 0) { - if (in->buffer_offset >= in->buffer_used) { - if (istream_precache(in)) - return -1; - - if (in->buffer_used == 0) - break; - } - - diff = in->buffer_used - in->buffer_offset; - if (diff > size) - diff = size; - - if (out->append(out, in->buffer + in->buffer_offset, diff)) - return -1; - - in->buffer_offset += diff; - size -= diff; - total += diff; - } - - return total; -} diff --git a/lib/io/printf.c b/lib/io/printf.c deleted file mode 100644 index 3850487..0000000 --- a/lib/io/printf.c +++ /dev/null @@ -1,30 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * printf.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "internal.h" - -int ostream_printf(ostream_t *strm, const char *fmt, ...) -{ - char *temp = NULL; - va_list ap; - int ret; - - va_start(ap, fmt); - - ret = vasprintf(&temp, fmt, ap); - if (ret < 0) - perror(strm->get_filename(strm)); - va_end(ap); - - if (ret < 0) - return -1; - - if (strm->append(strm, temp, ret)) - ret = -1; - - free(temp); - return ret; -} diff --git a/lib/io/src/get_line.c b/lib/io/src/get_line.c new file mode 100644 index 0000000..f7e0b59 --- /dev/null +++ b/lib/io/src/get_line.c @@ -0,0 +1,118 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * get_line.c + * + * Copyright (C) 2019 David Oberhollenzer + */ +#include "internal.h" + +static void ltrim(char *buffer) +{ + size_t i = 0; + + while (isspace(buffer[i])) + ++i; + + if (i > 0) + memmove(buffer, buffer + i, strlen(buffer + i) + 1); +} + +static void rtrim(char *buffer) +{ + size_t i = strlen(buffer); + + while (i > 0 && isspace(buffer[i - 1])) + --i; + + buffer[i] = '\0'; +} + +static size_t trim(char *buffer, int flags) +{ + if (flags & ISTREAM_LINE_LTRIM) + ltrim(buffer); + + if (flags & ISTREAM_LINE_RTRIM) + rtrim(buffer); + + return strlen(buffer); +} + +int istream_get_line(istream_t *strm, char **out, + size_t *line_num, int flags) +{ + char *line = NULL, *new; + size_t i, line_len = 0; + bool have_line = false; + + *out = NULL; + + for (;;) { + if (istream_precache(strm)) + return -1; + + if (strm->buffer_used == 0) { + if (line_len == 0) + goto out_eof; + + line_len = trim(line, flags); + + if (line_len == 0 && + (flags & ISTREAM_LINE_SKIP_EMPTY)) { + goto out_eof; + } + break; + } + + for (i = 0; i < strm->buffer_used; ++i) { + if (strm->buffer[i] == '\n') + break; + } + + if (i < strm->buffer_used) { + have_line = true; + strm->buffer_offset = i + 1; + + if (i > 0 && strm->buffer[i - 1] == '\r') + --i; + } else { + strm->buffer_offset = i; + } + + new = realloc(line, line_len + i + 1); + if (new == NULL) + goto fail_errno; + + line = new; + memcpy(line + line_len, strm->buffer, i); + line_len += i; + line[line_len] = '\0'; + + if (have_line) { + line_len = trim(line, flags); + + if (line_len == 0 && + (flags & ISTREAM_LINE_SKIP_EMPTY)) { + free(line); + line = NULL; + have_line = false; + *line_num += 1; + continue; + } + break; + } + } + + *out = line; + return 0; +fail_errno: + fprintf(stderr, "%s: " PRI_SZ ": %s.\n", strm->get_filename(strm), + *line_num, strerror(errno)); + free(line); + *out = NULL; + return -1; +out_eof: + free(line); + *out = NULL; + return 1; +} diff --git a/lib/io/src/internal.h b/lib/io/src/internal.h new file mode 100644 index 0000000..25a0196 --- /dev/null +++ b/lib/io/src/internal.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * internal.h + * + * Copyright (C) 2019 David Oberhollenzer + */ +#ifndef INTERNAL_H +#define INTERNAL_H + +#include "config.h" +#include "compat.h" +#include "io/istream.h" +#include "io/ostream.h" +#include "io/file.h" +#include "io/xfrm.h" +#include "io/std.h" +#include "xfrm/compress.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BUFSZ (262144) + +#endif /* INTERNAL_H */ diff --git a/lib/io/src/istream.c b/lib/io/src/istream.c new file mode 100644 index 0000000..64fa478 --- /dev/null +++ b/lib/io/src/istream.c @@ -0,0 +1,86 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * istream.c + * + * Copyright (C) 2019 David Oberhollenzer + */ +#include "internal.h" + + +sqfs_s32 istream_read(istream_t *strm, void *data, size_t size) +{ + sqfs_s32 total = 0; + size_t diff; + + if (size > 0x7FFFFFFF) + size = 0x7FFFFFFF; + + while (size > 0) { + if (strm->buffer_offset >= strm->buffer_used) { + if (istream_precache(strm)) + return -1; + + if (strm->buffer_used == 0) + break; + } + + diff = strm->buffer_used - strm->buffer_offset; + if (diff > size) + diff = size; + + memcpy(data, strm->buffer + strm->buffer_offset, diff); + data = (char *)data + diff; + strm->buffer_offset += diff; + size -= diff; + total += diff; + } + + return total; +} + +int istream_precache(istream_t *strm) +{ + if (strm->buffer_offset >= strm->buffer_used) { + strm->buffer_offset = 0; + strm->buffer_used = 0; + } else if (strm->buffer_offset > 0) { + memmove(strm->buffer, + strm->buffer + strm->buffer_offset, + strm->buffer_used - strm->buffer_offset); + + strm->buffer_used -= strm->buffer_offset; + strm->buffer_offset = 0; + } + + if (strm->eof) + return 0; + + return strm->precache(strm); +} + +int istream_skip(istream_t *strm, sqfs_u64 size) +{ + size_t diff; + + while (size > 0) { + if (strm->buffer_offset >= strm->buffer_used) { + if (istream_precache(strm)) + return -1; + + if (strm->buffer_used == 0) { + fprintf(stderr, "%s: unexpected end-of-file\n", + strm->get_filename(strm)); + return -1; + } + } + + diff = strm->buffer_used - strm->buffer_offset; + if ((sqfs_u64)diff > size) + diff = size; + + strm->buffer_offset += diff; + size -= diff; + } + + return 0; +} diff --git a/lib/io/src/ostream.c b/lib/io/src/ostream.c new file mode 100644 index 0000000..da0b7b3 --- /dev/null +++ b/lib/io/src/ostream.c @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * ostream.c + * + * Copyright (C) 2019 David Oberhollenzer + */ +#include "internal.h" + + +static int append_sparse_fallback(ostream_t *strm, size_t size) +{ + char buffer[512]; + size_t diff; + + memset(buffer, 0, sizeof(buffer)); + + while (size > 0) { + diff = size < sizeof(buffer) ? size : sizeof(buffer); + + if (strm->append(strm, buffer, diff)) + return -1; + + size -= diff; + } + + return 0; +} + +int ostream_append_sparse(ostream_t *strm, size_t size) +{ + if (strm->append_sparse == NULL) + return append_sparse_fallback(strm, size); + + return strm->append_sparse(strm, size); +} + +sqfs_s32 ostream_append_from_istream(ostream_t *out, istream_t *in, + sqfs_u32 size) +{ + sqfs_s32 total = 0; + size_t diff; + + if (size > 0x7FFFFFFF) + size = 0x7FFFFFFF; + + while (size > 0) { + if (in->buffer_offset >= in->buffer_used) { + if (istream_precache(in)) + return -1; + + if (in->buffer_used == 0) + break; + } + + diff = in->buffer_used - in->buffer_offset; + if (diff > size) + diff = size; + + if (out->append(out, in->buffer + in->buffer_offset, diff)) + return -1; + + in->buffer_offset += diff; + size -= diff; + total += diff; + } + + return total; +} diff --git a/lib/io/src/printf.c b/lib/io/src/printf.c new file mode 100644 index 0000000..3850487 --- /dev/null +++ b/lib/io/src/printf.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * printf.c + * + * Copyright (C) 2019 David Oberhollenzer + */ +#include "internal.h" + +int ostream_printf(ostream_t *strm, const char *fmt, ...) +{ + char *temp = NULL; + va_list ap; + int ret; + + va_start(ap, fmt); + + ret = vasprintf(&temp, fmt, ap); + if (ret < 0) + perror(strm->get_filename(strm)); + va_end(ap); + + if (ret < 0) + return -1; + + if (strm->append(strm, temp, ret)) + ret = -1; + + free(temp); + return ret; +} diff --git a/lib/io/src/unix/istream.c b/lib/io/src/unix/istream.c new file mode 100644 index 0000000..f8cffad --- /dev/null +++ b/lib/io/src/unix/istream.c @@ -0,0 +1,123 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * istream.c + * + * Copyright (C) 2019 David Oberhollenzer + */ +#include "../internal.h" + +typedef struct { + istream_t base; + char *path; + int fd; + + sqfs_u8 buffer[BUFSZ]; +} file_istream_t; + +static int file_precache(istream_t *strm) +{ + file_istream_t *file = (file_istream_t *)strm; + ssize_t ret; + size_t diff; + + while (strm->buffer_used < sizeof(file->buffer)) { + diff = sizeof(file->buffer) - strm->buffer_used; + + ret = read(file->fd, strm->buffer + strm->buffer_used, diff); + + if (ret == 0) { + strm->eof = true; + break; + } + + if (ret < 0) { + if (errno == EINTR) + continue; + + perror(file->path); + return -1; + } + + strm->buffer_used += ret; + } + + return 0; +} + +static const char *file_get_filename(istream_t *strm) +{ + file_istream_t *file = (file_istream_t *)strm; + + return file->path; +} + +static void file_destroy(sqfs_object_t *obj) +{ + file_istream_t *file = (file_istream_t *)obj; + + if (file->fd != STDIN_FILENO) + close(file->fd); + + free(file->path); + free(file); +} + +istream_t *istream_open_file(const char *path) +{ + file_istream_t *file = calloc(1, sizeof(*file)); + istream_t *strm = (istream_t *)file; + + if (file == NULL) { + perror(path); + return NULL; + } + + sqfs_object_init(file, file_destroy, NULL); + + file->path = strdup(path); + if (file->path == NULL) { + perror(path); + goto fail_free; + } + + file->fd = open(path, O_RDONLY); + if (file->fd < 0) { + perror(path); + goto fail_path; + } + + strm->buffer = file->buffer; + strm->precache = file_precache; + strm->get_filename = file_get_filename; + return strm; +fail_path: + free(file->path); +fail_free: + free(file); + return NULL; +} + +istream_t *istream_open_stdin(void) +{ + file_istream_t *file = calloc(1, sizeof(*file)); + istream_t *strm = (istream_t *)file; + + if (file == NULL) + goto fail; + + sqfs_object_init(file, file_destroy, NULL); + + file->path = strdup("stdin"); + if (file->path == NULL) + goto fail; + + file->fd = STDIN_FILENO; + strm->buffer = file->buffer; + strm->precache = file_precache; + strm->get_filename = file_get_filename; + return strm; +fail: + perror("creating file wrapper for stdin"); + free(file); + return NULL; +} diff --git a/lib/io/src/unix/ostream.c b/lib/io/src/unix/ostream.c new file mode 100644 index 0000000..5ef2af2 --- /dev/null +++ b/lib/io/src/unix/ostream.c @@ -0,0 +1,173 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * ostream.c + * + * Copyright (C) 2019 David Oberhollenzer + */ +#include "../internal.h" + +typedef struct { + ostream_t base; + char *path; + int fd; + + off_t sparse_count; + off_t size; +} file_ostream_t; + +static int file_append(ostream_t *strm, const void *data, size_t size) +{ + file_ostream_t *file = (file_ostream_t *)strm; + ssize_t ret; + + if (size == 0) + return 0; + + if (file->sparse_count > 0) { + if (lseek(file->fd, file->sparse_count, SEEK_CUR) == (off_t)-1) + goto fail_errno; + + file->sparse_count = 0; + } + + while (size > 0) { + ret = write(file->fd, data, size); + + if (ret == 0) { + fprintf(stderr, "%s: truncated data write.\n", + file->path); + return -1; + } + + if (ret < 0) { + if (errno == EINTR) + continue; + goto fail_errno; + } + + file->size += ret; + size -= ret; + data = (const char *)data + ret; + } + + return 0; +fail_errno: + perror(file->path); + return -1; +} + +static int file_append_sparse(ostream_t *strm, size_t size) +{ + file_ostream_t *file = (file_ostream_t *)strm; + + file->sparse_count += size; + file->size += size; + return 0; +} + +static int file_flush(ostream_t *strm) +{ + file_ostream_t *file = (file_ostream_t *)strm; + + if (file->sparse_count > 0) { + if (ftruncate(file->fd, file->size) != 0) + goto fail; + } + + if (fsync(file->fd) != 0) { + if (errno == EINVAL) + return 0; + goto fail; + } + + return 0; +fail: + perror(file->path); + return -1; +} + +static void file_destroy(sqfs_object_t *obj) +{ + file_ostream_t *file = (file_ostream_t *)obj; + + if (file->fd != STDOUT_FILENO) + close(file->fd); + + free(file->path); + free(file); +} + +static const char *file_get_filename(ostream_t *strm) +{ + file_ostream_t *file = (file_ostream_t *)strm; + + return file->path; +} + +ostream_t *ostream_open_file(const char *path, int flags) +{ + file_ostream_t *file = calloc(1, sizeof(*file)); + ostream_t *strm = (ostream_t *)file; + + if (file == NULL) { + perror(path); + return NULL; + } + + sqfs_object_init(file, file_destroy, NULL); + + file->path = strdup(path); + if (file->path == NULL) { + perror(path); + goto fail_free; + } + + if (flags & OSTREAM_OPEN_OVERWRITE) { + file->fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); + } else { + file->fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0644); + } + + if (file->fd < 0) { + perror(path); + goto fail_path; + } + + if (flags & OSTREAM_OPEN_SPARSE) + strm->append_sparse = file_append_sparse; + + strm->append = file_append; + strm->flush = file_flush; + strm->get_filename = file_get_filename; + return strm; +fail_path: + free(file->path); +fail_free: + free(file); + return NULL; +} + +ostream_t *ostream_open_stdout(void) +{ + file_ostream_t *file = calloc(1, sizeof(*file)); + ostream_t *strm = (ostream_t *)file; + + if (file == NULL) + goto fail; + + file->path = strdup("stdout"); + if (file->path == NULL) + goto fail; + + file->fd = STDOUT_FILENO; + strm->append = file_append; + strm->flush = file_flush; + strm->get_filename = file_get_filename; + + sqfs_object_init(file, file_destroy, NULL); + return strm; +fail: + perror("creating file wrapper for stdout"); + free(file); + return NULL; +} diff --git a/lib/io/src/win32/istream.c b/lib/io/src/win32/istream.c new file mode 100644 index 0000000..be3d829 --- /dev/null +++ b/lib/io/src/win32/istream.c @@ -0,0 +1,138 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * istream.c + * + * Copyright (C) 2019 David Oberhollenzer + */ +#include "../internal.h" + +#define WIN32_LEAN_AND_MEAN +#include + +typedef struct { + istream_t base; + char *path; + HANDLE hnd; + + sqfs_u8 buffer[BUFSZ]; +} file_istream_t; + +static int file_precache(istream_t *strm) +{ + file_istream_t *file = (file_istream_t *)strm; + DWORD diff, actual; + HANDLE hnd; + + hnd = file->path == NULL ? GetStdHandle(STD_INPUT_HANDLE) : file->hnd; + + while (strm->buffer_used < sizeof(file->buffer)) { + diff = sizeof(file->buffer) - strm->buffer_used; + + if (!ReadFile(hnd, strm->buffer + strm->buffer_used, + diff, &actual, NULL)) { + DWORD error = GetLastError(); + + if (error == ERROR_HANDLE_EOF || + error == ERROR_BROKEN_PIPE) { + strm->eof = true; + break; + } + + SetLastError(error); + + w32_perror(file->path == NULL ? "stdin" : file->path); + return -1; + } + + if (actual == 0) { + strm->eof = true; + break; + } + + strm->buffer_used += actual; + } + + return 0; +} + +static const char *file_get_filename(istream_t *strm) +{ + file_istream_t *file = (file_istream_t *)strm; + + return file->path == NULL ? "stdin" : file->path; +} + +static void file_destroy(sqfs_object_t *obj) +{ + file_istream_t *file = (file_istream_t *)obj; + + if (file->path != NULL) { + CloseHandle(file->hnd); + free(file->path); + } + + free(file); +} + +istream_t *istream_open_file(const char *path) +{ + file_istream_t *file = calloc(1, sizeof(*file)); + istream_t *strm = (istream_t *)file; + WCHAR *wpath = NULL; + + if (file == NULL) { + perror(path); + return NULL; + } + + sqfs_object_init(file, file_destroy, NULL); + + wpath = path_to_windows(path); + if (wpath == NULL) + goto fail_free; + + file->path = strdup(path); + if (file->path == NULL) { + perror(path); + goto fail_free; + } + + file->hnd = CreateFileW(wpath, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + + if (file->hnd == INVALID_HANDLE_VALUE) { + perror(path); + goto fail_path; + } + + free(wpath); + + strm->buffer = file->buffer; + strm->precache = file_precache; + strm->get_filename = file_get_filename; + return strm; +fail_path: + free(file->path); +fail_free: + free(wpath); + free(file); + return NULL; +} + +istream_t *istream_open_stdin(void) +{ + file_istream_t *file = calloc(1, sizeof(*file)); + istream_t *strm = (istream_t *)file; + + if (file == NULL) { + perror("stdin"); + return NULL; + } + + sqfs_object_init(file, file_destroy, NULL); + + strm->buffer = file->buffer; + strm->precache = file_precache; + strm->get_filename = file_get_filename; + return strm; +} diff --git a/lib/io/src/win32/ostream.c b/lib/io/src/win32/ostream.c new file mode 100644 index 0000000..0fe04f3 --- /dev/null +++ b/lib/io/src/win32/ostream.c @@ -0,0 +1,199 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * ostream.c + * + * Copyright (C) 2019 David Oberhollenzer + */ +#include "../internal.h" + +#define WIN32_LEAN_AND_MEAN +#include + +typedef struct { + ostream_t base; + char *path; + HANDLE hnd; +} file_ostream_t; + +static int w32_append(HANDLE hnd, const char *filename, + const void *data, size_t size) +{ + DWORD diff; + + while (size > 0) { + if (!WriteFile(hnd, data, size, &diff, NULL)) { + w32_perror(filename); + return -1; + } + + size -= diff; + data = (const char *)data + diff; + } + + return 0; +} + +static int w32_flush(HANDLE hnd, const char *filename) +{ + if (!FlushFileBuffers(hnd)) { + w32_perror(filename); + return -1; + } + + return 0; +} + +/*****************************************************************************/ + +static int file_append(ostream_t *strm, const void *data, size_t size) +{ + file_ostream_t *file = (file_ostream_t *)strm; + + return w32_append(file->hnd, file->path, data, size); +} + +static int file_append_sparse(ostream_t *strm, size_t size) +{ + file_ostream_t *file = (file_ostream_t *)strm; + LARGE_INTEGER pos; + + pos.QuadPart = size; + + if (!SetFilePointerEx(file->hnd, pos, NULL, FILE_CURRENT)) + goto fail; + + if (!SetEndOfFile(file->hnd)) + goto fail; + + return 0; +fail: + w32_perror(file->path); + return -1; +} + +static int file_flush(ostream_t *strm) +{ + file_ostream_t *file = (file_ostream_t *)strm; + + return w32_flush(file->hnd, file->path); +} + +static void file_destroy(sqfs_object_t *obj) +{ + file_ostream_t *file = (file_ostream_t *)obj; + + CloseHandle(file->hnd); + free(file->path); + free(file); +} + +static const char *file_get_filename(ostream_t *strm) +{ + file_ostream_t *file = (file_ostream_t *)strm; + + return file->path; +} + +/*****************************************************************************/ + +static int stdout_append(ostream_t *strm, const void *data, size_t size) +{ + (void)strm; + return w32_append(GetStdHandle(STD_OUTPUT_HANDLE), "stdout", + data, size); +} + +static int stdout_flush(ostream_t *strm) +{ + (void)strm; + return w32_flush(GetStdHandle(STD_OUTPUT_HANDLE), "stdout"); +} + +static void stdout_destroy(sqfs_object_t *obj) +{ + free(obj); +} + +static const char *stdout_get_filename(ostream_t *strm) +{ + (void)strm; + return "stdout"; +} + +/*****************************************************************************/ + +ostream_t *ostream_open_file(const char *path, int flags) +{ + file_ostream_t *file = calloc(1, sizeof(*file)); + sqfs_object_t *obj = (sqfs_object_t *)file; + ostream_t *strm = (ostream_t *)file; + int access_flags, creation_mode; + WCHAR *wpath = NULL; + + if (file == NULL) { + perror(path); + return NULL; + } + + sqfs_object_init(file, file_destroy, NULL); + + wpath = path_to_windows(path); + if (wpath == NULL) + goto fail_free; + + file->path = strdup(path); + if (file->path == NULL) { + perror(path); + goto fail_free; + } + + access_flags = GENERIC_WRITE; + + if (flags & OSTREAM_OPEN_OVERWRITE) { + creation_mode = CREATE_ALWAYS; + } else { + creation_mode = CREATE_NEW; + } + + file->hnd = CreateFileW(wpath, access_flags, 0, NULL, creation_mode, + FILE_ATTRIBUTE_NORMAL, NULL); + + if (file->hnd == INVALID_HANDLE_VALUE) { + w32_perror(path); + goto fail_path; + } + + free(wpath); + + if (flags & OSTREAM_OPEN_SPARSE) + strm->append_sparse = file_append_sparse; + + strm->append = file_append; + strm->flush = file_flush; + strm->get_filename = file_get_filename; + return strm; +fail_path: + free(file->path); +fail_free: + free(file); + free(wpath); + return NULL; +} + +ostream_t *ostream_open_stdout(void) +{ + ostream_t *strm = calloc(1, sizeof(*strm)); + sqfs_object_t *obj = (sqfs_object_t *)strm; + + if (strm == NULL) { + perror("creating stdout file wrapper"); + return NULL; + } + + sqfs_object_init(strm, stdout_destroy, NULL); + + strm->append = stdout_append; + strm->flush = stdout_flush; + strm->get_filename = stdout_get_filename; + return strm; +} diff --git a/lib/io/src/xfrm/istream.c b/lib/io/src/xfrm/istream.c new file mode 100644 index 0000000..4a1ad77 --- /dev/null +++ b/lib/io/src/xfrm/istream.c @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * istream.c + * + * Copyright (C) 2019 David Oberhollenzer + */ +#include "../internal.h" + +typedef struct istream_xfrm_t { + istream_t base; + + istream_t *wrapped; + xfrm_stream_t *xfrm; + + sqfs_u8 uncompressed[BUFSZ]; +} istream_xfrm_t; + +static int xfrm_precache(istream_t *base) +{ + istream_xfrm_t *xfrm = (istream_xfrm_t *)base; + int ret; + + ret = istream_precache(xfrm->wrapped); + if (ret != 0) + return ret; + + for (;;) { + const sqfs_u32 in_sz = xfrm->wrapped->buffer_used; + const sqfs_u32 out_sz = sizeof(xfrm->uncompressed); + sqfs_u32 in_off = 0, out_off = base->buffer_used; + int mode = XFRM_STREAM_FLUSH_NONE; + + if (xfrm->wrapped->eof) + mode = XFRM_STREAM_FLUSH_FULL; + + ret = xfrm->xfrm->process_data(xfrm->xfrm, + xfrm->wrapped->buffer, in_sz, + base->buffer + out_off, + out_sz - out_off, + &in_off, &out_off, mode); + + if (ret == XFRM_STREAM_ERROR) { + fprintf(stderr, "%s: internal error in decompressor.\n", + base->get_filename(base)); + return -1; + } + + base->buffer_used = out_off; + xfrm->wrapped->buffer_offset = in_off; + + if (ret == XFRM_STREAM_BUFFER_FULL || out_off >= out_sz) + break; + + ret = istream_precache(xfrm->wrapped); + if (ret != 0) + return ret; + + if (xfrm->wrapped->eof && xfrm->wrapped->buffer_used == 0) { + if (base->buffer_used == 0) + base->eof = true; + break; + } + } + + return 0; +} + +static const char *xfrm_get_filename(istream_t *strm) +{ + istream_xfrm_t *xfrm = (istream_xfrm_t *)strm; + + return xfrm->wrapped->get_filename(xfrm->wrapped); +} + +static void xfrm_destroy(sqfs_object_t *obj) +{ + istream_xfrm_t *xfrm = (istream_xfrm_t *)obj; + + sqfs_drop(xfrm->xfrm); + sqfs_drop(xfrm->wrapped); + free(xfrm); +} + +istream_t *istream_xfrm_create(istream_t *strm, xfrm_stream_t *xfrm) +{ + istream_xfrm_t *stream = calloc(1, sizeof(*stream)); + istream_t *base = (istream_t *)stream; + + if (stream == NULL) + goto fail; + + sqfs_object_init(stream, xfrm_destroy, NULL); + + stream->wrapped = sqfs_grab(strm); + stream->xfrm = sqfs_grab(xfrm); + + base->precache = xfrm_precache; + base->get_filename = xfrm_get_filename; + base->buffer = stream->uncompressed; + base->eof = false; + return base; +fail: + fprintf(stderr, "%s: error initializing decompressor stream.\n", + strm->get_filename(strm)); + return NULL; +} diff --git a/lib/io/src/xfrm/ostream.c b/lib/io/src/xfrm/ostream.c new file mode 100644 index 0000000..bd94515 --- /dev/null +++ b/lib/io/src/xfrm/ostream.c @@ -0,0 +1,144 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +/* + * ostream.c + * + * Copyright (C) 2019 David Oberhollenzer + */ +#include "../internal.h" + +typedef struct ostream_xfrm_t { + ostream_t base; + + ostream_t *wrapped; + xfrm_stream_t *xfrm; + + size_t inbuf_used; + + sqfs_u8 inbuf[BUFSZ]; + sqfs_u8 outbuf[BUFSZ]; +} ostream_xfrm_t; + +static int flush_inbuf(ostream_xfrm_t *xfrm, bool finish) +{ + const sqfs_u32 avail_out = sizeof(xfrm->outbuf); + const sqfs_u32 avail_in = xfrm->inbuf_used; + const int mode = finish ? XFRM_STREAM_FLUSH_FULL : + XFRM_STREAM_FLUSH_NONE; + sqfs_u32 off_in = 0, off_out = 0; + int ret; + + while (finish || off_in < avail_in) { + ret = xfrm->xfrm->process_data(xfrm->xfrm, + xfrm->inbuf + off_in, + avail_in - off_in, + xfrm->outbuf + off_out, + avail_out - off_out, + &off_in, &off_out, mode); + + if (ret == XFRM_STREAM_ERROR) { + fprintf(stderr, + "%s: internal error in compressor.\n", + xfrm->wrapped->get_filename(xfrm->wrapped)); + return -1; + } + + if (ostream_append(xfrm->wrapped, xfrm->outbuf, off_out)) + return -1; + + off_out = 0; + + if (ret == XFRM_STREAM_END) + break; + } + + if (off_out > 0) { + if (ostream_append(xfrm->wrapped, xfrm->outbuf, off_out)) + return -1; + } + + if (off_in < avail_in) { + memmove(xfrm->inbuf, xfrm->inbuf + off_in, avail_in - off_in); + xfrm->inbuf_used -= off_in; + } else { + xfrm->inbuf_used = 0; + } + + return 0; +} + +static int xfrm_append(ostream_t *strm, const void *data, size_t size) +{ + ostream_xfrm_t *xfrm = (ostream_xfrm_t *)strm; + size_t diff; + + while (size > 0) { + if (xfrm->inbuf_used >= BUFSZ) { + if (flush_inbuf(xfrm, false)) + return -1; + } + + diff = BUFSZ - xfrm->inbuf_used; + + if (diff > size) + diff = size; + + memcpy(xfrm->inbuf + xfrm->inbuf_used, data, diff); + + xfrm->inbuf_used += diff; + data = (const char *)data + diff; + size -= diff; + } + + return 0; +} + +static int xfrm_flush(ostream_t *strm) +{ + ostream_xfrm_t *xfrm = (ostream_xfrm_t *)strm; + + if (xfrm->inbuf_used > 0) { + if (flush_inbuf(xfrm, true)) + return -1; + } + + return xfrm->wrapped->flush(xfrm->wrapped); +} + +static const char *xfrm_get_filename(ostream_t *strm) +{ + ostream_xfrm_t *xfrm = (ostream_xfrm_t *)strm; + + return xfrm->wrapped->get_filename(xfrm->wrapped); +} + +static void xfrm_destroy(sqfs_object_t *obj) +{ + ostream_xfrm_t *xfrm = (ostream_xfrm_t *)obj; + + sqfs_drop(xfrm->wrapped); + sqfs_drop(xfrm->xfrm); + free(xfrm); +} + +ostream_t *ostream_xfrm_create(ostream_t *strm, xfrm_stream_t *xfrm) +{ + ostream_xfrm_t *stream = calloc(1, sizeof(*stream)); + ostream_t *base = (ostream_t *)stream; + + if (stream == NULL) + goto fail; + + sqfs_object_init(stream, xfrm_destroy, NULL); + + stream->wrapped = sqfs_grab(strm); + stream->xfrm = sqfs_grab(xfrm); + stream->inbuf_used = 0; + base->append = xfrm_append; + base->flush = xfrm_flush; + base->get_filename = xfrm_get_filename; + return base; +fail: + fprintf(stderr, "%s: error initializing compressor.\n", + strm->get_filename(strm)); + return NULL; +} diff --git a/lib/io/unix/istream.c b/lib/io/unix/istream.c deleted file mode 100644 index f8cffad..0000000 --- a/lib/io/unix/istream.c +++ /dev/null @@ -1,123 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * istream.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "../internal.h" - -typedef struct { - istream_t base; - char *path; - int fd; - - sqfs_u8 buffer[BUFSZ]; -} file_istream_t; - -static int file_precache(istream_t *strm) -{ - file_istream_t *file = (file_istream_t *)strm; - ssize_t ret; - size_t diff; - - while (strm->buffer_used < sizeof(file->buffer)) { - diff = sizeof(file->buffer) - strm->buffer_used; - - ret = read(file->fd, strm->buffer + strm->buffer_used, diff); - - if (ret == 0) { - strm->eof = true; - break; - } - - if (ret < 0) { - if (errno == EINTR) - continue; - - perror(file->path); - return -1; - } - - strm->buffer_used += ret; - } - - return 0; -} - -static const char *file_get_filename(istream_t *strm) -{ - file_istream_t *file = (file_istream_t *)strm; - - return file->path; -} - -static void file_destroy(sqfs_object_t *obj) -{ - file_istream_t *file = (file_istream_t *)obj; - - if (file->fd != STDIN_FILENO) - close(file->fd); - - free(file->path); - free(file); -} - -istream_t *istream_open_file(const char *path) -{ - file_istream_t *file = calloc(1, sizeof(*file)); - istream_t *strm = (istream_t *)file; - - if (file == NULL) { - perror(path); - return NULL; - } - - sqfs_object_init(file, file_destroy, NULL); - - file->path = strdup(path); - if (file->path == NULL) { - perror(path); - goto fail_free; - } - - file->fd = open(path, O_RDONLY); - if (file->fd < 0) { - perror(path); - goto fail_path; - } - - strm->buffer = file->buffer; - strm->precache = file_precache; - strm->get_filename = file_get_filename; - return strm; -fail_path: - free(file->path); -fail_free: - free(file); - return NULL; -} - -istream_t *istream_open_stdin(void) -{ - file_istream_t *file = calloc(1, sizeof(*file)); - istream_t *strm = (istream_t *)file; - - if (file == NULL) - goto fail; - - sqfs_object_init(file, file_destroy, NULL); - - file->path = strdup("stdin"); - if (file->path == NULL) - goto fail; - - file->fd = STDIN_FILENO; - strm->buffer = file->buffer; - strm->precache = file_precache; - strm->get_filename = file_get_filename; - return strm; -fail: - perror("creating file wrapper for stdin"); - free(file); - return NULL; -} diff --git a/lib/io/unix/ostream.c b/lib/io/unix/ostream.c deleted file mode 100644 index 5ef2af2..0000000 --- a/lib/io/unix/ostream.c +++ /dev/null @@ -1,173 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * ostream.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "../internal.h" - -typedef struct { - ostream_t base; - char *path; - int fd; - - off_t sparse_count; - off_t size; -} file_ostream_t; - -static int file_append(ostream_t *strm, const void *data, size_t size) -{ - file_ostream_t *file = (file_ostream_t *)strm; - ssize_t ret; - - if (size == 0) - return 0; - - if (file->sparse_count > 0) { - if (lseek(file->fd, file->sparse_count, SEEK_CUR) == (off_t)-1) - goto fail_errno; - - file->sparse_count = 0; - } - - while (size > 0) { - ret = write(file->fd, data, size); - - if (ret == 0) { - fprintf(stderr, "%s: truncated data write.\n", - file->path); - return -1; - } - - if (ret < 0) { - if (errno == EINTR) - continue; - goto fail_errno; - } - - file->size += ret; - size -= ret; - data = (const char *)data + ret; - } - - return 0; -fail_errno: - perror(file->path); - return -1; -} - -static int file_append_sparse(ostream_t *strm, size_t size) -{ - file_ostream_t *file = (file_ostream_t *)strm; - - file->sparse_count += size; - file->size += size; - return 0; -} - -static int file_flush(ostream_t *strm) -{ - file_ostream_t *file = (file_ostream_t *)strm; - - if (file->sparse_count > 0) { - if (ftruncate(file->fd, file->size) != 0) - goto fail; - } - - if (fsync(file->fd) != 0) { - if (errno == EINVAL) - return 0; - goto fail; - } - - return 0; -fail: - perror(file->path); - return -1; -} - -static void file_destroy(sqfs_object_t *obj) -{ - file_ostream_t *file = (file_ostream_t *)obj; - - if (file->fd != STDOUT_FILENO) - close(file->fd); - - free(file->path); - free(file); -} - -static const char *file_get_filename(ostream_t *strm) -{ - file_ostream_t *file = (file_ostream_t *)strm; - - return file->path; -} - -ostream_t *ostream_open_file(const char *path, int flags) -{ - file_ostream_t *file = calloc(1, sizeof(*file)); - ostream_t *strm = (ostream_t *)file; - - if (file == NULL) { - perror(path); - return NULL; - } - - sqfs_object_init(file, file_destroy, NULL); - - file->path = strdup(path); - if (file->path == NULL) { - perror(path); - goto fail_free; - } - - if (flags & OSTREAM_OPEN_OVERWRITE) { - file->fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); - } else { - file->fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0644); - } - - if (file->fd < 0) { - perror(path); - goto fail_path; - } - - if (flags & OSTREAM_OPEN_SPARSE) - strm->append_sparse = file_append_sparse; - - strm->append = file_append; - strm->flush = file_flush; - strm->get_filename = file_get_filename; - return strm; -fail_path: - free(file->path); -fail_free: - free(file); - return NULL; -} - -ostream_t *ostream_open_stdout(void) -{ - file_ostream_t *file = calloc(1, sizeof(*file)); - ostream_t *strm = (ostream_t *)file; - - if (file == NULL) - goto fail; - - file->path = strdup("stdout"); - if (file->path == NULL) - goto fail; - - file->fd = STDOUT_FILENO; - strm->append = file_append; - strm->flush = file_flush; - strm->get_filename = file_get_filename; - - sqfs_object_init(file, file_destroy, NULL); - return strm; -fail: - perror("creating file wrapper for stdout"); - free(file); - return NULL; -} diff --git a/lib/io/win32/istream.c b/lib/io/win32/istream.c deleted file mode 100644 index be3d829..0000000 --- a/lib/io/win32/istream.c +++ /dev/null @@ -1,138 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * istream.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "../internal.h" - -#define WIN32_LEAN_AND_MEAN -#include - -typedef struct { - istream_t base; - char *path; - HANDLE hnd; - - sqfs_u8 buffer[BUFSZ]; -} file_istream_t; - -static int file_precache(istream_t *strm) -{ - file_istream_t *file = (file_istream_t *)strm; - DWORD diff, actual; - HANDLE hnd; - - hnd = file->path == NULL ? GetStdHandle(STD_INPUT_HANDLE) : file->hnd; - - while (strm->buffer_used < sizeof(file->buffer)) { - diff = sizeof(file->buffer) - strm->buffer_used; - - if (!ReadFile(hnd, strm->buffer + strm->buffer_used, - diff, &actual, NULL)) { - DWORD error = GetLastError(); - - if (error == ERROR_HANDLE_EOF || - error == ERROR_BROKEN_PIPE) { - strm->eof = true; - break; - } - - SetLastError(error); - - w32_perror(file->path == NULL ? "stdin" : file->path); - return -1; - } - - if (actual == 0) { - strm->eof = true; - break; - } - - strm->buffer_used += actual; - } - - return 0; -} - -static const char *file_get_filename(istream_t *strm) -{ - file_istream_t *file = (file_istream_t *)strm; - - return file->path == NULL ? "stdin" : file->path; -} - -static void file_destroy(sqfs_object_t *obj) -{ - file_istream_t *file = (file_istream_t *)obj; - - if (file->path != NULL) { - CloseHandle(file->hnd); - free(file->path); - } - - free(file); -} - -istream_t *istream_open_file(const char *path) -{ - file_istream_t *file = calloc(1, sizeof(*file)); - istream_t *strm = (istream_t *)file; - WCHAR *wpath = NULL; - - if (file == NULL) { - perror(path); - return NULL; - } - - sqfs_object_init(file, file_destroy, NULL); - - wpath = path_to_windows(path); - if (wpath == NULL) - goto fail_free; - - file->path = strdup(path); - if (file->path == NULL) { - perror(path); - goto fail_free; - } - - file->hnd = CreateFileW(wpath, GENERIC_READ, FILE_SHARE_READ, NULL, - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - - if (file->hnd == INVALID_HANDLE_VALUE) { - perror(path); - goto fail_path; - } - - free(wpath); - - strm->buffer = file->buffer; - strm->precache = file_precache; - strm->get_filename = file_get_filename; - return strm; -fail_path: - free(file->path); -fail_free: - free(wpath); - free(file); - return NULL; -} - -istream_t *istream_open_stdin(void) -{ - file_istream_t *file = calloc(1, sizeof(*file)); - istream_t *strm = (istream_t *)file; - - if (file == NULL) { - perror("stdin"); - return NULL; - } - - sqfs_object_init(file, file_destroy, NULL); - - strm->buffer = file->buffer; - strm->precache = file_precache; - strm->get_filename = file_get_filename; - return strm; -} diff --git a/lib/io/win32/ostream.c b/lib/io/win32/ostream.c deleted file mode 100644 index 0fe04f3..0000000 --- a/lib/io/win32/ostream.c +++ /dev/null @@ -1,199 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * ostream.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "../internal.h" - -#define WIN32_LEAN_AND_MEAN -#include - -typedef struct { - ostream_t base; - char *path; - HANDLE hnd; -} file_ostream_t; - -static int w32_append(HANDLE hnd, const char *filename, - const void *data, size_t size) -{ - DWORD diff; - - while (size > 0) { - if (!WriteFile(hnd, data, size, &diff, NULL)) { - w32_perror(filename); - return -1; - } - - size -= diff; - data = (const char *)data + diff; - } - - return 0; -} - -static int w32_flush(HANDLE hnd, const char *filename) -{ - if (!FlushFileBuffers(hnd)) { - w32_perror(filename); - return -1; - } - - return 0; -} - -/*****************************************************************************/ - -static int file_append(ostream_t *strm, const void *data, size_t size) -{ - file_ostream_t *file = (file_ostream_t *)strm; - - return w32_append(file->hnd, file->path, data, size); -} - -static int file_append_sparse(ostream_t *strm, size_t size) -{ - file_ostream_t *file = (file_ostream_t *)strm; - LARGE_INTEGER pos; - - pos.QuadPart = size; - - if (!SetFilePointerEx(file->hnd, pos, NULL, FILE_CURRENT)) - goto fail; - - if (!SetEndOfFile(file->hnd)) - goto fail; - - return 0; -fail: - w32_perror(file->path); - return -1; -} - -static int file_flush(ostream_t *strm) -{ - file_ostream_t *file = (file_ostream_t *)strm; - - return w32_flush(file->hnd, file->path); -} - -static void file_destroy(sqfs_object_t *obj) -{ - file_ostream_t *file = (file_ostream_t *)obj; - - CloseHandle(file->hnd); - free(file->path); - free(file); -} - -static const char *file_get_filename(ostream_t *strm) -{ - file_ostream_t *file = (file_ostream_t *)strm; - - return file->path; -} - -/*****************************************************************************/ - -static int stdout_append(ostream_t *strm, const void *data, size_t size) -{ - (void)strm; - return w32_append(GetStdHandle(STD_OUTPUT_HANDLE), "stdout", - data, size); -} - -static int stdout_flush(ostream_t *strm) -{ - (void)strm; - return w32_flush(GetStdHandle(STD_OUTPUT_HANDLE), "stdout"); -} - -static void stdout_destroy(sqfs_object_t *obj) -{ - free(obj); -} - -static const char *stdout_get_filename(ostream_t *strm) -{ - (void)strm; - return "stdout"; -} - -/*****************************************************************************/ - -ostream_t *ostream_open_file(const char *path, int flags) -{ - file_ostream_t *file = calloc(1, sizeof(*file)); - sqfs_object_t *obj = (sqfs_object_t *)file; - ostream_t *strm = (ostream_t *)file; - int access_flags, creation_mode; - WCHAR *wpath = NULL; - - if (file == NULL) { - perror(path); - return NULL; - } - - sqfs_object_init(file, file_destroy, NULL); - - wpath = path_to_windows(path); - if (wpath == NULL) - goto fail_free; - - file->path = strdup(path); - if (file->path == NULL) { - perror(path); - goto fail_free; - } - - access_flags = GENERIC_WRITE; - - if (flags & OSTREAM_OPEN_OVERWRITE) { - creation_mode = CREATE_ALWAYS; - } else { - creation_mode = CREATE_NEW; - } - - file->hnd = CreateFileW(wpath, access_flags, 0, NULL, creation_mode, - FILE_ATTRIBUTE_NORMAL, NULL); - - if (file->hnd == INVALID_HANDLE_VALUE) { - w32_perror(path); - goto fail_path; - } - - free(wpath); - - if (flags & OSTREAM_OPEN_SPARSE) - strm->append_sparse = file_append_sparse; - - strm->append = file_append; - strm->flush = file_flush; - strm->get_filename = file_get_filename; - return strm; -fail_path: - free(file->path); -fail_free: - free(file); - free(wpath); - return NULL; -} - -ostream_t *ostream_open_stdout(void) -{ - ostream_t *strm = calloc(1, sizeof(*strm)); - sqfs_object_t *obj = (sqfs_object_t *)strm; - - if (strm == NULL) { - perror("creating stdout file wrapper"); - return NULL; - } - - sqfs_object_init(strm, stdout_destroy, NULL); - - strm->append = stdout_append; - strm->flush = stdout_flush; - strm->get_filename = stdout_get_filename; - return strm; -} diff --git a/lib/io/xfrm/istream.c b/lib/io/xfrm/istream.c deleted file mode 100644 index 4a1ad77..0000000 --- a/lib/io/xfrm/istream.c +++ /dev/null @@ -1,106 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * istream.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "../internal.h" - -typedef struct istream_xfrm_t { - istream_t base; - - istream_t *wrapped; - xfrm_stream_t *xfrm; - - sqfs_u8 uncompressed[BUFSZ]; -} istream_xfrm_t; - -static int xfrm_precache(istream_t *base) -{ - istream_xfrm_t *xfrm = (istream_xfrm_t *)base; - int ret; - - ret = istream_precache(xfrm->wrapped); - if (ret != 0) - return ret; - - for (;;) { - const sqfs_u32 in_sz = xfrm->wrapped->buffer_used; - const sqfs_u32 out_sz = sizeof(xfrm->uncompressed); - sqfs_u32 in_off = 0, out_off = base->buffer_used; - int mode = XFRM_STREAM_FLUSH_NONE; - - if (xfrm->wrapped->eof) - mode = XFRM_STREAM_FLUSH_FULL; - - ret = xfrm->xfrm->process_data(xfrm->xfrm, - xfrm->wrapped->buffer, in_sz, - base->buffer + out_off, - out_sz - out_off, - &in_off, &out_off, mode); - - if (ret == XFRM_STREAM_ERROR) { - fprintf(stderr, "%s: internal error in decompressor.\n", - base->get_filename(base)); - return -1; - } - - base->buffer_used = out_off; - xfrm->wrapped->buffer_offset = in_off; - - if (ret == XFRM_STREAM_BUFFER_FULL || out_off >= out_sz) - break; - - ret = istream_precache(xfrm->wrapped); - if (ret != 0) - return ret; - - if (xfrm->wrapped->eof && xfrm->wrapped->buffer_used == 0) { - if (base->buffer_used == 0) - base->eof = true; - break; - } - } - - return 0; -} - -static const char *xfrm_get_filename(istream_t *strm) -{ - istream_xfrm_t *xfrm = (istream_xfrm_t *)strm; - - return xfrm->wrapped->get_filename(xfrm->wrapped); -} - -static void xfrm_destroy(sqfs_object_t *obj) -{ - istream_xfrm_t *xfrm = (istream_xfrm_t *)obj; - - sqfs_drop(xfrm->xfrm); - sqfs_drop(xfrm->wrapped); - free(xfrm); -} - -istream_t *istream_xfrm_create(istream_t *strm, xfrm_stream_t *xfrm) -{ - istream_xfrm_t *stream = calloc(1, sizeof(*stream)); - istream_t *base = (istream_t *)stream; - - if (stream == NULL) - goto fail; - - sqfs_object_init(stream, xfrm_destroy, NULL); - - stream->wrapped = sqfs_grab(strm); - stream->xfrm = sqfs_grab(xfrm); - - base->precache = xfrm_precache; - base->get_filename = xfrm_get_filename; - base->buffer = stream->uncompressed; - base->eof = false; - return base; -fail: - fprintf(stderr, "%s: error initializing decompressor stream.\n", - strm->get_filename(strm)); - return NULL; -} diff --git a/lib/io/xfrm/ostream.c b/lib/io/xfrm/ostream.c deleted file mode 100644 index bd94515..0000000 --- a/lib/io/xfrm/ostream.c +++ /dev/null @@ -1,144 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later */ -/* - * ostream.c - * - * Copyright (C) 2019 David Oberhollenzer - */ -#include "../internal.h" - -typedef struct ostream_xfrm_t { - ostream_t base; - - ostream_t *wrapped; - xfrm_stream_t *xfrm; - - size_t inbuf_used; - - sqfs_u8 inbuf[BUFSZ]; - sqfs_u8 outbuf[BUFSZ]; -} ostream_xfrm_t; - -static int flush_inbuf(ostream_xfrm_t *xfrm, bool finish) -{ - const sqfs_u32 avail_out = sizeof(xfrm->outbuf); - const sqfs_u32 avail_in = xfrm->inbuf_used; - const int mode = finish ? XFRM_STREAM_FLUSH_FULL : - XFRM_STREAM_FLUSH_NONE; - sqfs_u32 off_in = 0, off_out = 0; - int ret; - - while (finish || off_in < avail_in) { - ret = xfrm->xfrm->process_data(xfrm->xfrm, - xfrm->inbuf + off_in, - avail_in - off_in, - xfrm->outbuf + off_out, - avail_out - off_out, - &off_in, &off_out, mode); - - if (ret == XFRM_STREAM_ERROR) { - fprintf(stderr, - "%s: internal error in compressor.\n", - xfrm->wrapped->get_filename(xfrm->wrapped)); - return -1; - } - - if (ostream_append(xfrm->wrapped, xfrm->outbuf, off_out)) - return -1; - - off_out = 0; - - if (ret == XFRM_STREAM_END) - break; - } - - if (off_out > 0) { - if (ostream_append(xfrm->wrapped, xfrm->outbuf, off_out)) - return -1; - } - - if (off_in < avail_in) { - memmove(xfrm->inbuf, xfrm->inbuf + off_in, avail_in - off_in); - xfrm->inbuf_used -= off_in; - } else { - xfrm->inbuf_used = 0; - } - - return 0; -} - -static int xfrm_append(ostream_t *strm, const void *data, size_t size) -{ - ostream_xfrm_t *xfrm = (ostream_xfrm_t *)strm; - size_t diff; - - while (size > 0) { - if (xfrm->inbuf_used >= BUFSZ) { - if (flush_inbuf(xfrm, false)) - return -1; - } - - diff = BUFSZ - xfrm->inbuf_used; - - if (diff > size) - diff = size; - - memcpy(xfrm->inbuf + xfrm->inbuf_used, data, diff); - - xfrm->inbuf_used += diff; - data = (const char *)data + diff; - size -= diff; - } - - return 0; -} - -static int xfrm_flush(ostream_t *strm) -{ - ostream_xfrm_t *xfrm = (ostream_xfrm_t *)strm; - - if (xfrm->inbuf_used > 0) { - if (flush_inbuf(xfrm, true)) - return -1; - } - - return xfrm->wrapped->flush(xfrm->wrapped); -} - -static const char *xfrm_get_filename(ostream_t *strm) -{ - ostream_xfrm_t *xfrm = (ostream_xfrm_t *)strm; - - return xfrm->wrapped->get_filename(xfrm->wrapped); -} - -static void xfrm_destroy(sqfs_object_t *obj) -{ - ostream_xfrm_t *xfrm = (ostream_xfrm_t *)obj; - - sqfs_drop(xfrm->wrapped); - sqfs_drop(xfrm->xfrm); - free(xfrm); -} - -ostream_t *ostream_xfrm_create(ostream_t *strm, xfrm_stream_t *xfrm) -{ - ostream_xfrm_t *stream = calloc(1, sizeof(*stream)); - ostream_t *base = (ostream_t *)stream; - - if (stream == NULL) - goto fail; - - sqfs_object_init(stream, xfrm_destroy, NULL); - - stream->wrapped = sqfs_grab(strm); - stream->xfrm = sqfs_grab(xfrm); - stream->inbuf_used = 0; - base->append = xfrm_append; - base->flush = xfrm_flush; - base->get_filename = xfrm_get_filename; - return base; -fail: - fprintf(stderr, "%s: error initializing compressor.\n", - strm->get_filename(strm)); - return NULL; -} -- cgit v1.2.3