diff --git a/src/ox/fs/filesystem.cpp b/src/ox/fs/filesystem.cpp index 2b1aef861..9e35d402d 100644 --- a/src/ox/fs/filesystem.cpp +++ b/src/ox/fs/filesystem.cpp @@ -6,3 +6,28 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "filesystem.hpp" + +namespace ox { +namespace fs { + +FileSystem *createFileSystem(void *buff) { + auto type = *((ox::std::uint32_t*) buff); + FileSystem *fs = nullptr; + + switch (type) { + case ox::fs::OxFS16: + fs = new FileSystem16(buff); + break; + case ox::fs::OxFS32: + fs = new FileSystem32(buff); + break; + case ox::fs::OxFS64: + fs = new FileSystem64(buff); + break; + } + + return fs; +} + +} +} diff --git a/src/ox/fs/filesystem.hpp b/src/ox/fs/filesystem.hpp index 035970100..780439fd3 100644 --- a/src/ox/fs/filesystem.hpp +++ b/src/ox/fs/filesystem.hpp @@ -26,8 +26,21 @@ struct FileStat { uint64_t size; }; -template class FileSystem { + public: + virtual ~FileSystem() {}; + + virtual int read(ox::std::uint64_t inode, void *buffer, ox::std::uint64_t size) = 0; + + virtual ox::std::uint8_t *read(ox::std::uint64_t inode, ox::std::uint64_t *size) = 0; + + virtual int write(ox::std::uint64_t inode, void *buffer, ox::std::uint64_t size) = 0; + + virtual FileStat stat(ox::std::uint64_t inode) = 0; +}; + +template +class FileSystemTemplate: public FileSystem { private: struct DirectoryEntry { @@ -62,33 +75,46 @@ class FileSystem { FileStore *store = nullptr; public: + FileSystemTemplate(void *buff); + int mkdir(const char *path); int read(const char *path, void *buffer); + ox::std::uint8_t *read(ox::std::uint64_t inode, ox::std::uint64_t *size) override; + + int read(ox::std::uint64_t inode, void *buffer, ox::std::uint64_t size) override; + + int write(ox::std::uint64_t inode, void *buffer, ox::std::uint64_t size) override; + FileStat stat(const char *path); - FileStat stat(typename FileStore::InodeId_t inode); + FileStat stat(ox::std::uint64_t inode) override; - static uint8_t *format(uint8_t *buffer, typename FileStore::FsSize_t size); + static ox::std::uint8_t *format(void *buffer, typename FileStore::FsSize_t size, bool useDirectories); }; template -typename FileStore::InodeId_t FileSystem::INODE_ROOT_DIR = 2; +FileSystemTemplate::FileSystemTemplate(void *buff) { + store = (FileStore*) buff; +} template -int FileSystem::mkdir(const char *path) { +typename FileStore::InodeId_t FileSystemTemplate::INODE_ROOT_DIR = 2; + +template +int FileSystemTemplate::mkdir(const char *path) { return 0; } template -FileStat FileSystem::stat(const char *path) { +FileStat FileSystemTemplate::stat(const char *path) { FileStat stat; return stat; } template -FileStat FileSystem::stat(typename FileStore::InodeId_t inode) { +FileStat FileSystemTemplate::stat(ox::std::uint64_t inode) { FileStat stat; auto s = store->stat(inode); stat.size = s.size; @@ -97,21 +123,52 @@ FileStat FileSystem::stat(typename FileStore::InodeId_t inode) { } template -uint8_t *FileSystem::format(uint8_t *buffer, typename FileStore::FsSize_t size) { - buffer = FileStore::format(buffer, size); - char dirBuff[sizeof(Directory) + sizeof(DirectoryEntry) + 2]; - auto *dir = (Directory*) dirBuff; +int FileSystemTemplate::read(ox::std::uint64_t inode, void *buffer, ox::std::uint64_t size) { + auto err = 1; + auto s = store->stat(inode); + if (size == s.size) { + err = store->read(inode, buffer, nullptr); + } + return err; +} - if (buffer) { +template +ox::std::uint8_t *FileSystemTemplate::read(ox::std::uint64_t inode, ox::std::uint64_t *size) { + auto s = store->stat(inode); + auto buff = new ox::std::uint8_t[s.size]; + if (size) { + *size = s.size; + } + if (store->read(inode, buff, nullptr)) { + delete []buff; + buff = nullptr; + } + return buff; +} + +template +int FileSystemTemplate::write(ox::std::uint64_t inode, void *buffer, ox::std::uint64_t size) { + return store->write(inode, buffer, size); +} + +template +ox::std::uint8_t *FileSystemTemplate::format(void *buffer, typename FileStore::FsSize_t size, bool useDirectories) { + buffer = FileStore::format((ox::std::uint8_t*) buffer, size); + + if (buffer && useDirectories) { + char dirBuff[sizeof(Directory) + sizeof(DirectoryEntry) + 2]; + auto *dir = (Directory*) dirBuff; dir->files(); } - return buffer; + return (ox::std::uint8_t*) buffer; } -typedef FileSystem FileSystem16; -typedef FileSystem FileSystem32; -typedef FileSystem FileSystem64; +typedef FileSystemTemplate FileSystem16; +typedef FileSystemTemplate FileSystem32; +typedef FileSystemTemplate FileSystem64; + +FileSystem *createFileSystem(void *buff); } } diff --git a/src/ox/fs/oxfstool.cpp b/src/ox/fs/oxfstool.cpp index 545016ec2..9d707edad 100644 --- a/src/ox/fs/oxfstool.cpp +++ b/src/ox/fs/oxfstool.cpp @@ -14,13 +14,15 @@ using namespace ox::fs; const char *usage = "usage:\n" "\toxfs format [16,32,64] \n" +"\toxfs read \n" "\toxfs write "; char *loadFileBuff(const char *path, ::size_t *sizeOut = nullptr) { - FILE *file = fopen(path, "rw"); + FILE *file = fopen(path, "rb"); if (file) { fseek(file, 0, SEEK_END); const auto size = ftell(file); + rewind(file); auto buff = (char*) malloc(size); fread(buff, size, 1, file); fclose(file); @@ -57,8 +59,9 @@ int format(int argc, char **args) { FileStore64::format(buff, size, ox::fs::OxFS64); break; } + createFileSystem(buff); - FILE *file = fopen(path, "w"); + auto file = fopen(path, "wb"); if (file) { fwrite(buff, size, 1, file); err = fclose(file); @@ -77,6 +80,28 @@ int format(int argc, char **args) { return err; } +int read(int argc, char **args) { + auto err = 1; + if (argc >= 4) { + auto fsPath = args[2]; + auto inode = ox::std::atoi(args[3]); + ::size_t fsSize; + ox::std::uint64_t fileSize; + + auto fs = createFileSystem(loadFileBuff(fsPath, &fsSize)); + + auto output = fs->read(inode, &fileSize); + + if (output) { + fwrite(output, fileSize, 1, stdout); + err = 0; + } + + delete fs; + } + return err; +} + int write(int argc, char **args) { auto err = 0; if (argc >= 5) { @@ -85,50 +110,46 @@ int write(int argc, char **args) { auto srcPath = args[4]; ::size_t srcSize; - FILE *fsFile = fopen(fsPath, "rw"); + auto fsFile = fopen(fsPath, "rwb"); if (fsFile) { fseek(fsFile, 0, SEEK_END); - const auto fsSize = ftell(fsFile); - auto fs = (char*) malloc(fsSize); - fread(fs, fsSize, 1, fsFile); + const auto fsSize = (::size_t) ftell(fsFile); + rewind(fsFile); + auto fsBuff = (char*) malloc(fsSize); + fread(fsBuff, fsSize, 1, fsFile); + fclose(fsFile); auto srcBuff = loadFileBuff(srcPath, &srcSize); if (srcBuff) { - auto type = *((ox::std::uint32_t*) fs); - switch (type) { - case ox::fs::OxFS16: - err |= ((FileStore16*) fs)->write(inode, srcBuff, srcSize); - break; - case ox::fs::OxFS32: - err |= ((FileStore32*) fs)->write(inode, srcBuff, srcSize); - break; - case ox::fs::OxFS64: - err |= ((FileStore64*) fs)->write(inode, srcBuff, srcSize); - break; + auto fs = createFileSystem(fsBuff); + if (fs) { + err |= fs->write(inode, srcBuff, srcSize); + } else { + fprintf(stderr, "Invalid file system.\n"); + } + + if (err) { + fprintf(stderr, "Could not write to file system.\n"); + } else { + fsFile = fopen(fsPath, "wb"); + + if (fsFile) { + err = fwrite(fsBuff, fsSize, 1, fsFile) != 1; + err |= fclose(fsFile); + if (err) { + fprintf(stderr, "Could not write to file system file.\n"); + } + } else { + err = 1; + } } } else { err = 1; fprintf(stderr, "Could not load source file.\n"); } - if (err) { - fprintf(stderr, "Could not write to file system.\n"); - err = 0; - } else { - err = fwrite(fs, fsSize, 1, fsFile); - if (err) { - fprintf(stderr, "Could not write to file system.\n"); - } - } - - err = fclose(fsFile); - - if (err) { - fprintf(stderr, "Could not write to file system file.\n"); - } - - free(fs); + free(fsBuff); free(srcBuff); } else { fprintf(stderr, "Could not open file system\n"); @@ -143,6 +164,8 @@ int main(int argc, char **args) { auto cmd = args[1]; if (::strcmp(cmd, "format") == 0) { err = format(argc, args); + } else if (::strcmp(cmd, "read") == 0) { + err = read(argc, args); } else if (::strcmp(cmd, "write") == 0) { err = write(argc, args); } else if (::strcmp(cmd, "help") == 0) { diff --git a/src/ox/fs/test/filesystem_format.cpp b/src/ox/fs/test/filesystem_format.cpp index 547cbdef8..0ae4be1e6 100644 --- a/src/ox/fs/test/filesystem_format.cpp +++ b/src/ox/fs/test/filesystem_format.cpp @@ -15,7 +15,7 @@ template int test() { const ox::std::uint16_t size = ~0; ox::std::uint8_t volume[size]; - FileSystem::format(volume, size); + FileSystem::format(volume, size, true); return 0; }