diff options
Diffstat (limited to 'source/fitz/directory.c')
-rw-r--r-- | source/fitz/directory.c | 87 |
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; +} |