From 359d71e90050a8b83f7bc7d2ecd4ff29c477cc22 Mon Sep 17 00:00:00 2001
From: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Date: Sun, 26 Jun 2022 22:51:27 +0200
Subject: Cleanup: rename libfstream to libio, split headers

Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
---
 lib/io/win32/istream.c | 138 ++++++++++++++++++++++++++++++++++
 lib/io/win32/ostream.c | 197 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 335 insertions(+)
 create mode 100644 lib/io/win32/istream.c
 create mode 100644 lib/io/win32/ostream.c

(limited to 'lib/io/win32')

diff --git a/lib/io/win32/istream.c b/lib/io/win32/istream.c
new file mode 100644
index 0000000..b591584
--- /dev/null
+++ b/lib/io/win32/istream.c
@@ -0,0 +1,138 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+/*
+ * istream.c
+ *
+ * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
+ */
+#include "../internal.h"
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+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));
+	sqfs_object_t *obj = (sqfs_object_t *)file;
+	istream_t *strm = (istream_t *)file;
+	WCHAR *wpath = NULL;
+
+	if (file == NULL) {
+		perror(path);
+		return 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;
+	obj->destroy = file_destroy;
+	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));
+	sqfs_object_t *obj = (sqfs_object_t *)file;
+	istream_t *strm = (istream_t *)file;
+
+	if (file == NULL) {
+		perror("stdin");
+		return NULL;
+	}
+
+	strm->buffer = file->buffer;
+	strm->precache = file_precache;
+	strm->get_filename = file_get_filename;
+	obj->destroy = file_destroy;
+	return strm;
+}
diff --git a/lib/io/win32/ostream.c b/lib/io/win32/ostream.c
new file mode 100644
index 0000000..2bd78c8
--- /dev/null
+++ b/lib/io/win32/ostream.c
@@ -0,0 +1,197 @@
+/* SPDX-License-Identifier: GPL-3.0-or-later */
+/*
+ * ostream.c
+ *
+ * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
+ */
+#include "../internal.h"
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+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;
+	}
+
+	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;
+	obj->destroy = file_destroy;
+	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;
+	}
+
+	strm->append = stdout_append;
+	strm->flush = stdout_flush;
+	strm->get_filename = stdout_get_filename;
+	obj->destroy = stdout_destroy;
+	return strm;
+}
-- 
cgit v1.2.3