Add oxfstool read and FileSystem base class
This commit is contained in:
@@ -6,3 +6,28 @@
|
|||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
#include "filesystem.hpp"
|
#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
@@ -26,8 +26,21 @@ struct FileStat {
|
|||||||
uint64_t size;
|
uint64_t size;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename FileStore>
|
|
||||||
class FileSystem {
|
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:
|
private:
|
||||||
struct DirectoryEntry {
|
struct DirectoryEntry {
|
||||||
@@ -62,33 +75,46 @@ class FileSystem {
|
|||||||
FileStore *store = nullptr;
|
FileStore *store = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
FileSystemTemplate(void *buff);
|
||||||
|
|
||||||
int mkdir(const char *path);
|
int mkdir(const char *path);
|
||||||
|
|
||||||
int read(const char *path, void *buffer);
|
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(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>
|
template<typename FileStore>
|
||||||
typename FileStore::InodeId_t FileSystem<FileStore>::INODE_ROOT_DIR = 2;
|
FileSystemTemplate<FileStore>::FileSystemTemplate(void *buff) {
|
||||||
|
store = (FileStore*) buff;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename FileStore>
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename FileStore>
|
template<typename FileStore>
|
||||||
FileStat FileSystem<FileStore>::stat(const char *path) {
|
FileStat FileSystemTemplate<FileStore>::stat(const char *path) {
|
||||||
FileStat stat;
|
FileStat stat;
|
||||||
return stat;
|
return stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename FileStore>
|
template<typename FileStore>
|
||||||
FileStat FileSystem<FileStore>::stat(typename FileStore::InodeId_t inode) {
|
FileStat FileSystemTemplate<FileStore>::stat(ox::std::uint64_t inode) {
|
||||||
FileStat stat;
|
FileStat stat;
|
||||||
auto s = store->stat(inode);
|
auto s = store->stat(inode);
|
||||||
stat.size = s.size;
|
stat.size = s.size;
|
||||||
@@ -97,21 +123,52 @@ FileStat FileSystem<FileStore>::stat(typename FileStore::InodeId_t inode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename FileStore>
|
template<typename FileStore>
|
||||||
uint8_t *FileSystem<FileStore>::format(uint8_t *buffer, typename FileStore::FsSize_t size) {
|
int FileSystemTemplate<FileStore>::read(ox::std::uint64_t inode, void *buffer, ox::std::uint64_t size) {
|
||||||
buffer = FileStore::format(buffer, size);
|
auto err = 1;
|
||||||
char dirBuff[sizeof(Directory) + sizeof(DirectoryEntry) + 2];
|
auto s = store->stat(inode);
|
||||||
auto *dir = (Directory*) dirBuff;
|
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();
|
dir->files();
|
||||||
}
|
}
|
||||||
|
|
||||||
return buffer;
|
return (ox::std::uint8_t*) buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef FileSystem<FileStore16> FileSystem16;
|
typedef FileSystemTemplate<FileStore16> FileSystem16;
|
||||||
typedef FileSystem<FileStore32> FileSystem32;
|
typedef FileSystemTemplate<FileStore32> FileSystem32;
|
||||||
typedef FileSystem<FileStore64> FileSystem64;
|
typedef FileSystemTemplate<FileStore64> FileSystem64;
|
||||||
|
|
||||||
|
FileSystem *createFileSystem(void *buff);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+57
-34
@@ -14,13 +14,15 @@ using namespace ox::fs;
|
|||||||
|
|
||||||
const char *usage = "usage:\n"
|
const char *usage = "usage:\n"
|
||||||
"\toxfs format [16,32,64] <size> <path>\n"
|
"\toxfs format [16,32,64] <size> <path>\n"
|
||||||
|
"\toxfs read <FS file> <inode>\n"
|
||||||
"\toxfs write <FS file> <inode> <insertion file>";
|
"\toxfs write <FS file> <inode> <insertion file>";
|
||||||
|
|
||||||
char *loadFileBuff(const char *path, ::size_t *sizeOut = nullptr) {
|
char *loadFileBuff(const char *path, ::size_t *sizeOut = nullptr) {
|
||||||
FILE *file = fopen(path, "rw");
|
FILE *file = fopen(path, "rb");
|
||||||
if (file) {
|
if (file) {
|
||||||
fseek(file, 0, SEEK_END);
|
fseek(file, 0, SEEK_END);
|
||||||
const auto size = ftell(file);
|
const auto size = ftell(file);
|
||||||
|
rewind(file);
|
||||||
auto buff = (char*) malloc(size);
|
auto buff = (char*) malloc(size);
|
||||||
fread(buff, size, 1, file);
|
fread(buff, size, 1, file);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
@@ -57,8 +59,9 @@ int format(int argc, char **args) {
|
|||||||
FileStore64::format(buff, size, ox::fs::OxFS64);
|
FileStore64::format(buff, size, ox::fs::OxFS64);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
createFileSystem(buff);
|
||||||
|
|
||||||
FILE *file = fopen(path, "w");
|
auto file = fopen(path, "wb");
|
||||||
if (file) {
|
if (file) {
|
||||||
fwrite(buff, size, 1, file);
|
fwrite(buff, size, 1, file);
|
||||||
err = fclose(file);
|
err = fclose(file);
|
||||||
@@ -77,6 +80,28 @@ int format(int argc, char **args) {
|
|||||||
return err;
|
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) {
|
int write(int argc, char **args) {
|
||||||
auto err = 0;
|
auto err = 0;
|
||||||
if (argc >= 5) {
|
if (argc >= 5) {
|
||||||
@@ -85,50 +110,46 @@ int write(int argc, char **args) {
|
|||||||
auto srcPath = args[4];
|
auto srcPath = args[4];
|
||||||
::size_t srcSize;
|
::size_t srcSize;
|
||||||
|
|
||||||
FILE *fsFile = fopen(fsPath, "rw");
|
auto fsFile = fopen(fsPath, "rwb");
|
||||||
if (fsFile) {
|
if (fsFile) {
|
||||||
fseek(fsFile, 0, SEEK_END);
|
fseek(fsFile, 0, SEEK_END);
|
||||||
|
|
||||||
const auto fsSize = ftell(fsFile);
|
const auto fsSize = (::size_t) ftell(fsFile);
|
||||||
auto fs = (char*) malloc(fsSize);
|
rewind(fsFile);
|
||||||
fread(fs, fsSize, 1, fsFile);
|
auto fsBuff = (char*) malloc(fsSize);
|
||||||
|
fread(fsBuff, fsSize, 1, fsFile);
|
||||||
|
fclose(fsFile);
|
||||||
|
|
||||||
auto srcBuff = loadFileBuff(srcPath, &srcSize);
|
auto srcBuff = loadFileBuff(srcPath, &srcSize);
|
||||||
if (srcBuff) {
|
if (srcBuff) {
|
||||||
auto type = *((ox::std::uint32_t*) fs);
|
auto fs = createFileSystem(fsBuff);
|
||||||
switch (type) {
|
if (fs) {
|
||||||
case ox::fs::OxFS16:
|
err |= fs->write(inode, srcBuff, srcSize);
|
||||||
err |= ((FileStore16*) fs)->write(inode, srcBuff, srcSize);
|
} else {
|
||||||
break;
|
fprintf(stderr, "Invalid file system.\n");
|
||||||
case ox::fs::OxFS32:
|
}
|
||||||
err |= ((FileStore32*) fs)->write(inode, srcBuff, srcSize);
|
|
||||||
break;
|
if (err) {
|
||||||
case ox::fs::OxFS64:
|
fprintf(stderr, "Could not write to file system.\n");
|
||||||
err |= ((FileStore64*) fs)->write(inode, srcBuff, srcSize);
|
} else {
|
||||||
break;
|
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 {
|
} else {
|
||||||
err = 1;
|
err = 1;
|
||||||
fprintf(stderr, "Could not load source file.\n");
|
fprintf(stderr, "Could not load source file.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err) {
|
free(fsBuff);
|
||||||
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(srcBuff);
|
free(srcBuff);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Could not open file system\n");
|
fprintf(stderr, "Could not open file system\n");
|
||||||
@@ -143,6 +164,8 @@ int main(int argc, char **args) {
|
|||||||
auto cmd = args[1];
|
auto cmd = args[1];
|
||||||
if (::strcmp(cmd, "format") == 0) {
|
if (::strcmp(cmd, "format") == 0) {
|
||||||
err = format(argc, args);
|
err = format(argc, args);
|
||||||
|
} else if (::strcmp(cmd, "read") == 0) {
|
||||||
|
err = read(argc, args);
|
||||||
} else if (::strcmp(cmd, "write") == 0) {
|
} else if (::strcmp(cmd, "write") == 0) {
|
||||||
err = write(argc, args);
|
err = write(argc, args);
|
||||||
} else if (::strcmp(cmd, "help") == 0) {
|
} else if (::strcmp(cmd, "help") == 0) {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ template<typename FileSystem>
|
|||||||
int test() {
|
int test() {
|
||||||
const ox::std::uint16_t size = ~0;
|
const ox::std::uint16_t size = ~0;
|
||||||
ox::std::uint8_t volume[size];
|
ox::std::uint8_t volume[size];
|
||||||
FileSystem::format(volume, size);
|
FileSystem::format(volume, size, true);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user