From 3ff94d8797361f509bed3290bf0335ce2ed401ee Mon Sep 17 00:00:00 2001 From: mcc Date: Tue, 17 Dec 2019 20:06:42 -0500 Subject: [PATCH] Bring back old File C API (read-only currently) This code path is not used anywhere in this commit, but aids in developing Lovr addons. --- CMakeLists.txt | 1 + src/modules/filesystem/file.c | 90 +++++++++++++++++++++++++++++++++++ src/modules/filesystem/file.h | 26 ++++++++++ 3 files changed, 117 insertions(+) create mode 100644 src/modules/filesystem/file.c create mode 100644 src/modules/filesystem/file.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 68cea588..f3809454 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -381,6 +381,7 @@ if(LOVR_ENABLE_FILESYSTEM) add_definitions(-DLOVR_ENABLE_FILESYSTEM) target_sources(lovr PRIVATE src/modules/filesystem/filesystem.c + src/modules/filesystem/file.c src/api/l_filesystem.c ) endif() diff --git a/src/modules/filesystem/file.c b/src/modules/filesystem/file.c new file mode 100644 index 00000000..6e3ff5f1 --- /dev/null +++ b/src/modules/filesystem/file.c @@ -0,0 +1,90 @@ +#include "filesystem/file.h" +#include "filesystem/filesystem.h" +#include "core/util.h" +#include +#include + +// Currently only read operations are supported by File and all files are read into memory fully on open + +typedef struct { + uint8_t* data; + size_t offset; + size_t size; +} FileInner; + +File* lovrFileInit(File* file ,const char* path) { + file->path = path; + file->handle = NULL; + file->mode = 0; + return file; +} + +void lovrFileDestroy(void* ref) { + File* file = ref; + if (file->handle) { + lovrFileClose(ref); + } +} + +bool lovrFileOpen(File* file, FileMode mode) { + lovrAssert(!file->handle, "File is already open"); + file->mode = mode; + + if (mode == OPEN_WRITE || mode == OPEN_APPEND) + return false; + + FileInner *fileInner = malloc(sizeof(FileInner)); + fileInner->offset = 0; + fileInner->data = lovrFilesystemRead(file->path, -1, &fileInner->size); + file->handle = fileInner; + + if (!fileInner->data) { + fileInner->size = 0; + return false; + } + + return true; +} + +void lovrFileClose(File* file) { + lovrAssert(file->handle, "File must be open to close it"); + FileInner *fileInner = (FileInner *)file->handle; + free(fileInner->data); + free(file->handle); + file->handle = NULL; +} + +size_t lovrFileRead(File* file, void* data, size_t bytes) { + lovrAssert(file->handle && file->mode == OPEN_READ, "File must be open for reading"); + FileInner *fileInner = (FileInner *)file->handle; + if (fileInner->offset + bytes > fileInner->size) + return 0; + memcpy(data, fileInner->data + fileInner->offset, bytes); + fileInner->offset += bytes; + return bytes; +} + +size_t lovrFileWrite(File* file, const void* data, size_t bytes) { + lovrThrow("Writing not supported"); +} + +size_t lovrFileGetSize(File* file) { + lovrAssert(file->handle, "File must be open to get its size"); + FileInner *fileInner = (FileInner *)file->handle; + return fileInner->size; +} + +bool lovrFileSeek(File* file, size_t position) { + lovrAssert(file->handle, "File must be open to seek"); + FileInner *fileInner = (FileInner *)file->handle; + if (position >= fileInner->size) // FIXME: Should seeking to fileInner->size exactly be allowed? + return false; + fileInner->offset = position; + return true; +} + +size_t lovrFileTell(File* file) { + lovrAssert(file->handle, "File must be open to tell"); + FileInner *fileInner = (FileInner *)file->handle; + return fileInner->offset; +} diff --git a/src/modules/filesystem/file.h b/src/modules/filesystem/file.h new file mode 100644 index 00000000..96ed5550 --- /dev/null +++ b/src/modules/filesystem/file.h @@ -0,0 +1,26 @@ +#include +#include + +#pragma once + +typedef enum { + OPEN_READ, + OPEN_WRITE, + OPEN_APPEND +} FileMode; + +typedef struct { + const char* path; + void* handle; + FileMode mode; +} File; + +File* lovrFileInit(File* file, const char* filename); +void lovrFileDestroy(void* ref); +bool lovrFileOpen(File* file, FileMode mode); +void lovrFileClose(File* file); +size_t lovrFileRead(File* file, void* data, size_t bytes); +size_t lovrFileWrite(File* file, const void* data, size_t bytes); +size_t lovrFileGetSize(File* file); +bool lovrFileSeek(File* file, size_t position); +size_t lovrFileTell(File* file);