summaryrefslogtreecommitdiff
path: root/source/fitz/directory.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/fitz/directory.c')
-rw-r--r--source/fitz/directory.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/source/fitz/directory.c b/source/fitz/directory.c
new file mode 100644
index 00000000..aba11eb9
--- /dev/null
+++ b/source/fitz/directory.c
@@ -0,0 +1,87 @@
+#include "mupdf/fitz.h"
+
+typedef struct fz_directory_s fz_directory;
+struct fz_directory_s
+{
+ fz_archive super;
+
+ char *path;
+};
+
+static void drop_directory(fz_context *ctx, fz_archive *arch)
+{
+ fz_directory *dir = (fz_directory *) arch;
+
+ fz_free(ctx, dir->path);
+}
+
+static fz_stream *open_dir_entry(fz_context *ctx, fz_archive *arch, const char *name)
+{
+ fz_directory *dir = (fz_directory *) arch;
+ char path[2048];
+ fz_strlcpy(path, dir->path, sizeof path);
+ fz_strlcat(path, "/", sizeof path);
+ fz_strlcat(path, name, sizeof path);
+ return fz_open_file(ctx, path);
+}
+
+static fz_buffer *read_dir_entry(fz_context *ctx, fz_archive *arch, const char *name)
+{
+ fz_directory *dir = (fz_directory *) arch;
+ char path[2048];
+ fz_strlcpy(path, dir->path, sizeof path);
+ fz_strlcat(path, "/", sizeof path);
+ fz_strlcat(path, name, sizeof path);
+ return fz_read_file(ctx, path);
+}
+
+static int has_dir_entry(fz_context *ctx, fz_archive *arch, const char *name)
+{
+ fz_directory *dir = (fz_directory *) arch;
+ char path[2048];
+ fz_strlcpy(path, dir->path, sizeof path);
+ fz_strlcat(path, "/", sizeof path);
+ fz_strlcat(path, name, sizeof path);
+ return fz_file_exists(ctx, path);
+}
+
+int
+fz_is_directory(fz_context *ctx, const char *path)
+{
+ struct stat info;
+
+ if (stat(path, &info) < 0)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "cannot stat: %s", strerror(errno));
+
+ return info.st_mode & S_IFDIR;
+}
+
+fz_archive *
+fz_open_directory(fz_context *ctx, const char *path)
+{
+ fz_directory *dir = NULL;
+
+ fz_var(dir);
+
+ fz_try(ctx)
+ {
+ if (!fz_is_directory(ctx, path))
+ fz_throw(ctx, FZ_ERROR_GENERIC, "'%s' is not a directory", path);
+
+ dir = fz_new_archive(ctx, NULL, fz_directory);
+ dir->super.format = "dir";
+ dir->super.has_entry = has_dir_entry;
+ dir->super.read_entry = read_dir_entry;
+ dir->super.open_entry = open_dir_entry;
+ dir->super.drop_archive = drop_directory;
+
+ dir->path = fz_strdup(ctx, path);
+ }
+ fz_catch(ctx)
+ {
+ fz_drop_archive(ctx, &dir->super);
+ fz_rethrow(ctx);
+ }
+
+ return &dir->super;
+}