Add oxfstool read and FileSystem base class

This commit is contained in:
2016-07-03 16:43:37 -05:00
parent 3f941517ea
commit 19c2b9580a
4 changed files with 156 additions and 51 deletions
+25
View File
@@ -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;
}
}
}
+73 -16
View File
@@ -26,8 +26,21 @@ struct FileStat {
uint64_t size;
};
template<typename FileStore>
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<typename FileStore>
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>
typename FileStore::InodeId_t FileSystem<FileStore>::INODE_ROOT_DIR = 2;
FileSystemTemplate<FileStore>::FileSystemTemplate(void *buff) {
store = (FileStore*) buff;
}
template<typename FileStore>
int FileSystem<FileStore>::mkdir(const char *path) {
typename FileStore::InodeId_t FileSystemTemplate<FileStore>::INODE_ROOT_DIR = 2;
template<typename FileStore>
int FileSystemTemplate<FileStore>::mkdir(const char *path) {
return 0;
}
template<typename FileStore>
FileStat FileSystem<FileStore>::stat(const char *path) {
FileStat FileSystemTemplate<FileStore>::stat(const char *path) {
FileStat stat;
return stat;
}
template<typename FileStore>
FileStat FileSystem<FileStore>::stat(typename FileStore::InodeId_t inode) {
FileStat FileSystemTemplate<FileStore>::stat(ox::std::uint64_t inode) {
FileStat stat;
auto s = store->stat(inode);
stat.size = s.size;
@@ -97,21 +123,52 @@ FileStat FileSystem<FileStore>::stat(typename FileStore::InodeId_t inode) {
}
template<typename FileStore>
uint8_t *FileSystem<FileStore>::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<FileStore>::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<typename FileStore>
ox::std::uint8_t *FileSystemTemplate<FileStore>::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<typename FileStore>
int FileSystemTemplate<FileStore>::write(ox::std::uint64_t inode, void *buffer, ox::std::uint64_t size) {
return store->write(inode, buffer, size);
}
template<typename FileStore>
ox::std::uint8_t *FileSystemTemplate<FileStore>::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<FileStore16> FileSystem16;
typedef FileSystem<FileStore32> FileSystem32;
typedef FileSystem<FileStore64> FileSystem64;
typedef FileSystemTemplate<FileStore16> FileSystem16;
typedef FileSystemTemplate<FileStore32> FileSystem32;
typedef FileSystemTemplate<FileStore64> FileSystem64;
FileSystem *createFileSystem(void *buff);
}
}
+57 -34
View File
@@ -14,13 +14,15 @@ using namespace ox::fs;
const char *usage = "usage:\n"
"\toxfs format [16,32,64] <size> <path>\n"
"\toxfs read <FS file> <inode>\n"
"\toxfs write <FS file> <inode> <insertion file>";
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) {
+1 -1
View File
@@ -15,7 +15,7 @@ template<typename FileSystem>
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;
}