changeset 332:8eee6f92e9ce

core: implement vfs and vfs-directory
author David Demelier <markand@malikania.fr>
date Wed, 13 Oct 2021 15:03:18 +0200
parents 5c3f2aa95343
children 2ac41a176b5d
files src/libmlk-core/CMakeLists.txt src/libmlk-core/core/vfs-directory.c src/libmlk-core/core/vfs-directory.h src/libmlk-core/core/vfs.c src/libmlk-core/core/vfs.h
diffstat 5 files changed, 293 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/libmlk-core/CMakeLists.txt	Mon Oct 11 13:02:10 2021 +0200
+++ b/src/libmlk-core/CMakeLists.txt	Wed Oct 13 15:03:18 2021 +0200
@@ -74,6 +74,10 @@
 	${libmlk-core_SOURCE_DIR}/core/translate.h
 	${libmlk-core_SOURCE_DIR}/core/util.c
 	${libmlk-core_SOURCE_DIR}/core/util.h
+	${libmlk-core_SOURCE_DIR}/core/vfs-directory.c
+	${libmlk-core_SOURCE_DIR}/core/vfs-directory.h
+	${libmlk-core_SOURCE_DIR}/core/vfs.c
+	${libmlk-core_SOURCE_DIR}/core/vfs.h
 	${libmlk-core_SOURCE_DIR}/core/window.c
 	${libmlk-core_SOURCE_DIR}/core/window.h
 	${libmlk-core_SOURCE_DIR}/core/window_p.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/libmlk-core/core/vfs-directory.c	Wed Oct 13 15:03:18 2021 +0200
@@ -0,0 +1,116 @@
+/*
+ * vfs-directory.c -- VFS subsystem for directories
+ *
+ * Copyright (c) 2020-2021 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <port/port.h>
+
+#include "alloc.h"
+#include "error.h"
+#include "vfs.h"
+
+struct self {
+	char base[PATH_MAX];
+};
+
+static inline void
+normalize(char *path)
+{
+	size_t len = strlen(path);
+
+	for (char *p = path; *p; ++p)
+		if (*p == '\\')
+			*p = '/';
+
+	while (len && path[len - 1] == '/')
+		path[--len] = 0;
+}
+
+static size_t
+file_read(struct vfs_file *file, void *buf, size_t bufsz)
+{
+	return fread(buf, 1, bufsz, file->data);
+}
+
+static size_t
+file_write(struct vfs_file *file, const void *buf, size_t bufsz)
+{
+	return fwrite(buf, 1, bufsz, file->data);
+}
+
+static int
+file_flush(struct vfs_file *file)
+{
+	return fflush(file->data) == EOF ? -1 : 0;
+}
+
+static void
+file_finish(struct vfs_file *file)
+{
+	fclose(file->data);
+}
+
+static int
+dir_open(struct vfs *vfs, struct vfs_file *file, const char *entry, const char *mode)
+{
+	struct self *self = vfs->data;
+	char path[PATH_MAX];
+
+	snprintf(path, sizeof (path), "%s/%s", self->base, entry);
+	memset(file, 0, sizeof (*file));
+
+	if (!(file->data = fopen(path, mode)))
+		return errorf("%s: %s", path, strerror(errno));
+
+	file->read = file_read;
+	file->write = file_write;
+	file->flush = file_flush;
+	file->finish = file_finish;
+
+	return 0;
+}
+
+static void
+dir_finish(struct vfs *vfs)
+{
+	free(vfs->data);
+}
+
+void
+vfs_directory(struct vfs *vfs, const char *path)
+{
+	assert(vfs);
+	assert(path);
+
+	struct self *self;
+
+	self = alloc_new(sizeof (*self));
+	strlcpy(self->base, path, sizeof (self->base));
+
+	/* Remove terminator and switch to UNIX paths. */
+	normalize(self->base);
+
+	vfs->data = self;
+	vfs->open = dir_open;
+	vfs->finish = dir_finish;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/libmlk-core/core/vfs-directory.h	Wed Oct 13 15:03:18 2021 +0200
@@ -0,0 +1,33 @@
+/*
+ * vfs-directory.h -- VFS subsystem for directories
+ *
+ * Copyright (c) 2020-2021 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef MLK_CORE_VFS_DIRECTORY_H
+#define MLK_CORE_VFS_DIRECTORY_H
+
+#include "core.h"
+
+struct vfs;
+
+CORE_BEGIN_DECLS
+
+void
+vfs_directory(struct vfs *, const char *);
+
+CORE_END_DECLS
+
+#endif /* !MLK_CORE_VFS_DIRECTORY_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/libmlk-core/core/vfs.c	Wed Oct 13 15:03:18 2021 +0200
@@ -0,0 +1,74 @@
+/*
+ * vfs.c -- virtual file system abstraction
+ *
+ * Copyright (c) 2020-2021 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <assert.h>
+#include <string.h>
+
+#include "vfs.h"
+
+int
+vfs_open(struct vfs *vfs, struct vfs_file *file, const char *entry, const char *mode)
+{
+	assert(vfs);
+	assert(entry);
+
+	return vfs->open(vfs, file, entry, mode);
+}
+
+void
+vfs_finish(struct vfs *vfs)
+{
+	assert(vfs);
+
+	vfs->finish(vfs);
+	memset(vfs, 0, sizeof (*vfs));
+}
+
+size_t
+vfs_file_read(struct vfs_file *file, void *buf, size_t bufsz)
+{
+	assert(file);
+	assert(buf);
+
+	return file->read(file, buf, bufsz);
+}
+
+size_t
+vfs_file_write(struct vfs_file *file, void *buf, size_t bufsz)
+{
+	assert(file);
+	assert(buf);
+
+	return file->write(file, buf, bufsz);
+}
+
+int
+vfs_file_flush(struct vfs_file *file)
+{
+	assert(file);
+
+	return file->flush(file);
+}
+
+void
+vfs_file_finish(struct vfs_file *file)
+{
+	assert(file);
+
+	file->finish(file);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/libmlk-core/core/vfs.h	Wed Oct 13 15:03:18 2021 +0200
@@ -0,0 +1,66 @@
+/*
+ * vfs.h -- virtual file system abstraction
+ *
+ * Copyright (c) 2020-2021 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef MLK_CORE_VFS_H
+#define MLK_CORE_VFS_H
+
+#include "core.h"
+
+struct vfs_file;
+
+struct vfs {
+	void *data;
+	int (*open)(struct vfs *, struct vfs_file *, const char *, const char *);
+	void (*finish)(struct vfs *);
+};
+
+struct vfs_file {
+	void *data;
+	size_t (*read)(struct vfs_file *, void *, size_t);
+	size_t (*write)(struct vfs_file *, const void *, size_t);
+	int (*flush)(struct vfs_file *);
+	void (*finish)(struct vfs_file *);
+};
+
+CORE_BEGIN_DECLS
+
+/* vfs */
+
+int
+vfs_open(struct vfs *, struct vfs_file *, const char *, const char *);
+
+void
+vfs_finish(struct vfs *);
+
+/* vfs_file */
+
+size_t
+vfs_file_read(struct vfs_file *, void *, size_t);
+
+size_t
+vfs_file_write(struct vfs_file *, void *, size_t);
+
+int
+vfs_file_flush(struct vfs_file *);
+
+void
+vfs_file_finish(struct vfs_file *);
+
+CORE_END_DECLS
+
+#endif /* MLK_CORE_VFS_H */