Squashed 'deps/ox/' changes from a5166e0..68c144f
68c144f Add ls to file system 1ce2797 Flatten out namespaces to only ox e0063a7 Cleanup oxfstool format output a2dfb41 Fix FS read by type to read byte by byte git-subtree-dir: deps/ox git-subtree-split: 68c144fe755e1f1a6cebb841b6c37b618a35fa43
This commit is contained in:
parent
b1e548b96a
commit
f92c8ab577
@ -10,7 +10,6 @@
|
||||
#include "clargs.hpp"
|
||||
|
||||
namespace ox {
|
||||
namespace clargs {
|
||||
|
||||
using namespace ::std;
|
||||
|
||||
@ -52,4 +51,3 @@ int ClArgs::getInt(const char *arg) {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include <string>
|
||||
|
||||
namespace ox {
|
||||
namespace clargs {
|
||||
|
||||
class ClArgs {
|
||||
private:
|
||||
@ -31,4 +30,3 @@ class ClArgs {
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include <ox/std/std.hpp>
|
||||
|
||||
namespace ox {
|
||||
namespace fs {
|
||||
|
||||
template<typename FsT, typename InodeId>
|
||||
struct __attribute__((packed)) FileStoreHeader {
|
||||
@ -46,52 +45,52 @@ struct __attribute__((packed)) FileStoreHeader {
|
||||
|
||||
template<typename FsSize_t, typename InodeId_t>
|
||||
void FileStoreHeader<FsSize_t, InodeId_t>::setVersion(uint16_t version) {
|
||||
m_version = std::bigEndianAdapt(version);
|
||||
m_version = bigEndianAdapt(version);
|
||||
}
|
||||
|
||||
template<typename FsSize_t, typename InodeId_t>
|
||||
uint16_t FileStoreHeader<FsSize_t, InodeId_t>::getVersion() {
|
||||
return std::bigEndianAdapt(m_version);
|
||||
return bigEndianAdapt(m_version);
|
||||
}
|
||||
|
||||
template<typename FsSize_t, typename InodeId_t>
|
||||
void FileStoreHeader<FsSize_t, InodeId_t>::setFsType(uint16_t fsType) {
|
||||
m_fsType = std::bigEndianAdapt(fsType);
|
||||
m_fsType = bigEndianAdapt(fsType);
|
||||
}
|
||||
|
||||
template<typename FsSize_t, typename InodeId_t>
|
||||
uint16_t FileStoreHeader<FsSize_t, InodeId_t>::getFsType() {
|
||||
return std::bigEndianAdapt(m_fsType);
|
||||
return bigEndianAdapt(m_fsType);
|
||||
}
|
||||
|
||||
template<typename FsSize_t, typename InodeId_t>
|
||||
void FileStoreHeader<FsSize_t, InodeId_t>::setSize(FsSize_t size) {
|
||||
m_size = std::bigEndianAdapt(size);
|
||||
m_size = bigEndianAdapt(size);
|
||||
}
|
||||
|
||||
template<typename FsSize_t, typename InodeId_t>
|
||||
FsSize_t FileStoreHeader<FsSize_t, InodeId_t>::getSize() {
|
||||
return std::bigEndianAdapt(m_size);
|
||||
return bigEndianAdapt(m_size);
|
||||
}
|
||||
|
||||
template<typename FsSize_t, typename InodeId_t>
|
||||
void FileStoreHeader<FsSize_t, InodeId_t>::setMemUsed(FsSize_t memUsed) {
|
||||
m_memUsed = std::bigEndianAdapt(memUsed);
|
||||
m_memUsed = bigEndianAdapt(memUsed);
|
||||
}
|
||||
|
||||
template<typename FsSize_t, typename InodeId_t>
|
||||
FsSize_t FileStoreHeader<FsSize_t, InodeId_t>::getMemUsed() {
|
||||
return std::bigEndianAdapt(m_memUsed);
|
||||
return bigEndianAdapt(m_memUsed);
|
||||
}
|
||||
|
||||
template<typename FsSize_t, typename InodeId_t>
|
||||
void FileStoreHeader<FsSize_t, InodeId_t>::setRootInode(FsSize_t rootInode) {
|
||||
m_rootInode = std::bigEndianAdapt(rootInode);
|
||||
m_rootInode = bigEndianAdapt(rootInode);
|
||||
}
|
||||
|
||||
template<typename FsSize_t, typename InodeId_t>
|
||||
FsSize_t FileStoreHeader<FsSize_t, InodeId_t>::getRootInode() {
|
||||
return std::bigEndianAdapt(m_rootInode);
|
||||
return bigEndianAdapt(m_rootInode);
|
||||
}
|
||||
|
||||
template<typename Header>
|
||||
@ -368,72 +367,72 @@ typename Header::FsSize_t FileStore<Header>::Inode::size() {
|
||||
|
||||
template<typename Header>
|
||||
void FileStore<Header>::Inode::setDataLen(typename Header::FsSize_t dataLen) {
|
||||
this->m_dataLen = std::bigEndianAdapt(dataLen);
|
||||
this->m_dataLen = bigEndianAdapt(dataLen);
|
||||
}
|
||||
|
||||
template<typename Header>
|
||||
typename Header::FsSize_t FileStore<Header>::Inode::getDataLen() {
|
||||
return std::bigEndianAdapt(m_dataLen);
|
||||
return bigEndianAdapt(m_dataLen);
|
||||
}
|
||||
|
||||
template<typename Header>
|
||||
void FileStore<Header>::Inode::setPrev(typename Header::FsSize_t prev) {
|
||||
this->m_prev = std::bigEndianAdapt(prev);
|
||||
this->m_prev = bigEndianAdapt(prev);
|
||||
}
|
||||
|
||||
template<typename Header>
|
||||
typename Header::FsSize_t FileStore<Header>::Inode::getPrev() {
|
||||
return std::bigEndianAdapt(m_prev);
|
||||
return bigEndianAdapt(m_prev);
|
||||
}
|
||||
|
||||
template<typename Header>
|
||||
void FileStore<Header>::Inode::setNext(typename Header::FsSize_t next) {
|
||||
this->m_next = std::bigEndianAdapt(next);
|
||||
this->m_next = bigEndianAdapt(next);
|
||||
}
|
||||
|
||||
template<typename Header>
|
||||
typename Header::FsSize_t FileStore<Header>::Inode::getNext() {
|
||||
return std::bigEndianAdapt(m_next);
|
||||
return bigEndianAdapt(m_next);
|
||||
}
|
||||
|
||||
template<typename Header>
|
||||
void FileStore<Header>::Inode::setId(InodeId_t id) {
|
||||
this->m_id = std::bigEndianAdapt(id);
|
||||
this->m_id = bigEndianAdapt(id);
|
||||
}
|
||||
|
||||
template<typename Header>
|
||||
typename Header::InodeId_t FileStore<Header>::Inode::getId() {
|
||||
return std::bigEndianAdapt(m_id);
|
||||
return bigEndianAdapt(m_id);
|
||||
}
|
||||
|
||||
template<typename Header>
|
||||
void FileStore<Header>::Inode::setFileType(uint8_t fileType) {
|
||||
this->m_fileType = std::bigEndianAdapt(fileType);
|
||||
this->m_fileType = bigEndianAdapt(fileType);
|
||||
}
|
||||
|
||||
template<typename Header>
|
||||
uint8_t FileStore<Header>::Inode::getFileType() {
|
||||
return std::bigEndianAdapt(m_fileType);
|
||||
return bigEndianAdapt(m_fileType);
|
||||
}
|
||||
|
||||
template<typename Header>
|
||||
void FileStore<Header>::Inode::setLeft(typename Header::FsSize_t left) {
|
||||
this->m_left = std::bigEndianAdapt(left);
|
||||
this->m_left = bigEndianAdapt(left);
|
||||
}
|
||||
|
||||
template<typename Header>
|
||||
typename Header::FsSize_t FileStore<Header>::Inode::getLeft() {
|
||||
return std::bigEndianAdapt(m_left);
|
||||
return bigEndianAdapt(m_left);
|
||||
}
|
||||
|
||||
template<typename Header>
|
||||
void FileStore<Header>::Inode::setRight(typename Header::FsSize_t right) {
|
||||
this->m_right = std::bigEndianAdapt(right);
|
||||
this->m_right = bigEndianAdapt(right);
|
||||
}
|
||||
|
||||
template<typename Header>
|
||||
typename Header::FsSize_t FileStore<Header>::Inode::getRight() {
|
||||
return std::bigEndianAdapt(m_right);
|
||||
return bigEndianAdapt(m_right);
|
||||
}
|
||||
|
||||
template<typename Header>
|
||||
@ -647,9 +646,13 @@ int FileStore<Header>::read(Inode *inode, typename Header::FsSize_t readStart,
|
||||
}
|
||||
|
||||
readSize /= sizeof(T);
|
||||
T *it = (T*) &(inode->getData()[readStart]);
|
||||
uint8_t *it = &(inode->getData()[readStart]);
|
||||
for (typename Header::FsSize_t i = 0; i < readSize; i++) {
|
||||
*(data++) = *(it++);
|
||||
T val;
|
||||
for (size_t i = 0; i < sizeof(T); i++) {
|
||||
((uint8_t*) (&val))[i] = *(it++);
|
||||
}
|
||||
*(data++) = val;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -848,4 +851,3 @@ typedef FileStore<FileStoreHeader<uint32_t, uint64_t>> FileStore32;
|
||||
typedef FileStore<FileStoreHeader<uint64_t, uint64_t>> FileStore64;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include "filesystem.hpp"
|
||||
|
||||
namespace ox {
|
||||
namespace fs {
|
||||
|
||||
FileSystem *createFileSystem(void *buff, size_t buffSize) {
|
||||
auto version = ((FileStore16*) buff)->version();
|
||||
@ -19,13 +18,13 @@ FileSystem *createFileSystem(void *buff, size_t buffSize) {
|
||||
switch (version) {
|
||||
case 5:
|
||||
switch (type) {
|
||||
case ox::fs::OxFS_16:
|
||||
case ox::OxFS_16:
|
||||
fs = new FileSystem16(buff);
|
||||
break;
|
||||
case ox::fs::OxFS_32:
|
||||
case ox::OxFS_32:
|
||||
fs = new FileSystem32(buff);
|
||||
break;
|
||||
case ox::fs::OxFS_64:
|
||||
case ox::OxFS_64:
|
||||
fs = new FileSystem64(buff);
|
||||
break;
|
||||
}
|
||||
@ -72,4 +71,3 @@ FileSystem *expandCopyCleanup(FileSystem *fs, size_t size) {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include "filestore.hpp"
|
||||
|
||||
namespace ox {
|
||||
namespace fs {
|
||||
|
||||
enum FsType {
|
||||
OxFS_16 = 1,
|
||||
@ -21,8 +20,8 @@ enum FsType {
|
||||
};
|
||||
|
||||
enum FileType {
|
||||
NormalFile = 1,
|
||||
Directory = 2
|
||||
FileType_NormalFile = 1,
|
||||
FileType_Directory = 2
|
||||
};
|
||||
|
||||
struct FileStat {
|
||||
@ -31,62 +30,19 @@ struct FileStat {
|
||||
uint8_t fileType;
|
||||
};
|
||||
|
||||
class FileSystem {
|
||||
public:
|
||||
virtual ~FileSystem() {};
|
||||
template<typename String>
|
||||
struct DirectoryListing {
|
||||
String name;
|
||||
FileStat stat;
|
||||
|
||||
virtual int stripDirectories() = 0;
|
||||
|
||||
virtual int mkdir(const char *path) = 0;
|
||||
|
||||
virtual int read(const char *path, void *buffer, size_t buffSize) = 0;
|
||||
|
||||
virtual int read(uint64_t inode, void *buffer, size_t size) = 0;
|
||||
|
||||
virtual int read(uint64_t inode, size_t readStart, size_t readSize, void *buffer, size_t *size) = 0;
|
||||
|
||||
virtual uint8_t *read(uint64_t inode, size_t *size) = 0;
|
||||
|
||||
virtual int remove(uint64_t inode, bool recursive = false) = 0;
|
||||
|
||||
virtual int remove(const char *path, bool recursive = false) = 0;
|
||||
|
||||
virtual void resize(uint64_t size = 0) = 0;
|
||||
|
||||
virtual int write(const char *path, void *buffer, uint64_t size, uint8_t fileType = NormalFile) = 0;
|
||||
|
||||
virtual int write(uint64_t inode, void *buffer, uint64_t size, uint8_t fileType = NormalFile) = 0;
|
||||
|
||||
virtual FileStat stat(uint64_t inode) = 0;
|
||||
|
||||
virtual uint64_t spaceNeeded(uint64_t size) = 0;
|
||||
|
||||
virtual uint64_t available() = 0;
|
||||
|
||||
virtual uint64_t size() = 0;
|
||||
|
||||
virtual uint8_t *buff() = 0;
|
||||
DirectoryListing(const char *name) {
|
||||
this->name = name;
|
||||
}
|
||||
};
|
||||
|
||||
FileSystem *createFileSystem(void *buff, size_t buffSize);
|
||||
|
||||
/**
|
||||
* Creates a larger version of the given FileSystem.
|
||||
*/
|
||||
FileSystem *expandCopy(FileSystem *src);
|
||||
|
||||
/**
|
||||
* Calls expandCopy and deletes the original FileSystem and buff a resize was
|
||||
* performed.
|
||||
*/
|
||||
FileSystem *expandCopyCleanup(FileSystem *fs, size_t size);
|
||||
|
||||
template<typename FileStore, FsType FS_TYPE>
|
||||
class FileSystemTemplate: public FileSystem {
|
||||
|
||||
private:
|
||||
template<typename InodeId_t>
|
||||
struct __attribute__((packed)) DirectoryEntry {
|
||||
typename FileStore::InodeId_t inode;
|
||||
InodeId_t inode;
|
||||
|
||||
char *getName() {
|
||||
return (char*) (this + 1);
|
||||
@ -111,24 +67,202 @@ class FileSystemTemplate: public FileSystem {
|
||||
}
|
||||
};
|
||||
|
||||
template<typename InodeId_t, typename FsSize_t>
|
||||
struct __attribute__((packed)) Directory {
|
||||
/**
|
||||
* Number of bytes after this Directory struct.
|
||||
*/
|
||||
typename FileStore::FsSize_t size = 0;
|
||||
typename FileStore::FsSize_t children = 0;
|
||||
FsSize_t size = 0;
|
||||
FsSize_t children = 0;
|
||||
|
||||
DirectoryEntry *files() {
|
||||
return size ? (DirectoryEntry*) (this + 1) : nullptr;
|
||||
DirectoryEntry<InodeId_t> *files() {
|
||||
return size ? (DirectoryEntry<InodeId_t>*) (this + 1) : nullptr;
|
||||
}
|
||||
|
||||
uint64_t getFileInode(const char *name, uint64_t buffSize);
|
||||
|
||||
int getChildrenInodes(typename FileStore::InodeId_t *inodes, size_t inodesLen);
|
||||
int getChildrenInodes(InodeId_t *inodes, size_t inodesLen);
|
||||
|
||||
int rmFile(const char *name);
|
||||
|
||||
int copy(Directory<uint64_t, uint64_t> *dirOut);
|
||||
|
||||
template<typename List>
|
||||
int ls(List *list);
|
||||
};
|
||||
|
||||
template<typename InodeId_t, typename FsSize_t>
|
||||
uint64_t Directory<InodeId_t, FsSize_t>::getFileInode(const char *name, uint64_t buffSize) {
|
||||
uint64_t inode = 0;
|
||||
auto current = files();
|
||||
if (current) {
|
||||
for (uint64_t i = 0; ox_strcmp(current->getName(), name) != 0;) {
|
||||
i += current->size();
|
||||
if (i < this->size) {
|
||||
current = (DirectoryEntry<InodeId_t>*) (((uint8_t*) current) + current->size());
|
||||
} else {
|
||||
current = nullptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (current) {
|
||||
inode = current->inode;
|
||||
}
|
||||
}
|
||||
return inode;
|
||||
}
|
||||
|
||||
template<typename InodeId_t, typename FsSize_t>
|
||||
int Directory<InodeId_t, FsSize_t>::getChildrenInodes(InodeId_t *inodes, size_t inodesLen) {
|
||||
if (inodesLen >= this->children) {
|
||||
auto current = files();
|
||||
if (current) {
|
||||
for (uint64_t i = 0; i < this->children; i++) {
|
||||
inodes[i] = current->inode;
|
||||
current = (DirectoryEntry<InodeId_t>*) (((uint8_t*) current) + current->size());
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename InodeId_t, typename FsSize_t>
|
||||
int Directory<InodeId_t, FsSize_t>::rmFile(const char *name) {
|
||||
int err = 1;
|
||||
auto current = files();
|
||||
if (current) {
|
||||
for (uint64_t i = 0; i < this->size;) {
|
||||
i += current->size();
|
||||
if (ox_strcmp(current->getName(), name) == 0) {
|
||||
auto dest = (uint8_t*) current;
|
||||
auto src = dest + current->size();
|
||||
ox_memcpy(dest, src, this->size - i);
|
||||
this->size -= current->size();
|
||||
this->children--;
|
||||
err = 0;
|
||||
break;
|
||||
}
|
||||
current = (DirectoryEntry<InodeId_t>*) (((uint8_t*) current) + current->size());
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
template<typename InodeId_t, typename FsSize_t>
|
||||
int Directory<InodeId_t, FsSize_t>::copy(Directory<uint64_t, uint64_t> *dirOut) {
|
||||
auto current = files();
|
||||
auto dirBuff = (uint8_t*) dirOut;
|
||||
dirBuff += sizeof(Directory<uint64_t, uint64_t>);
|
||||
dirOut->size = this->size;
|
||||
dirOut->children = this->children;
|
||||
if (current) {
|
||||
for (uint64_t i = 0; i < this->children; i++) {
|
||||
auto entry = (DirectoryEntry<uint64_t>*) dirBuff;
|
||||
entry->inode = current->inode;
|
||||
entry->setName(current->getName());
|
||||
|
||||
current = (DirectoryEntry<InodeId_t>*) (((uint8_t*) current) + current->size());
|
||||
dirBuff += entry->size();
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename InodeId_t, typename FsSize_t>
|
||||
template<typename List>
|
||||
int Directory<InodeId_t, FsSize_t>::ls(List *list) {
|
||||
auto current = files();
|
||||
if (current) {
|
||||
for (uint64_t i = 0; i < this->children; i++) {
|
||||
list->push_back(current->getName());
|
||||
list->at(i).stat.inode = current->inode;
|
||||
current = (DirectoryEntry<InodeId_t>*) (((uint8_t*) current) + current->size());
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class FileSystem {
|
||||
public:
|
||||
virtual ~FileSystem() {};
|
||||
|
||||
virtual int stripDirectories() = 0;
|
||||
|
||||
virtual int mkdir(const char *path) = 0;
|
||||
|
||||
template<typename List>
|
||||
int ls(const char *path, List *list);
|
||||
|
||||
virtual int read(const char *path, void *buffer, size_t buffSize) = 0;
|
||||
|
||||
virtual int read(uint64_t inode, void *buffer, size_t size) = 0;
|
||||
|
||||
virtual int read(uint64_t inode, size_t readStart, size_t readSize, void *buffer, size_t *size) = 0;
|
||||
|
||||
virtual uint8_t *read(uint64_t inode, size_t *size) = 0;
|
||||
|
||||
virtual int remove(uint64_t inode, bool recursive = false) = 0;
|
||||
|
||||
virtual int remove(const char *path, bool recursive = false) = 0;
|
||||
|
||||
virtual void resize(uint64_t size = 0) = 0;
|
||||
|
||||
virtual int write(const char *path, void *buffer, uint64_t size, uint8_t fileType = FileType_NormalFile) = 0;
|
||||
|
||||
virtual int write(uint64_t inode, void *buffer, uint64_t size, uint8_t fileType = FileType_NormalFile) = 0;
|
||||
|
||||
virtual FileStat stat(uint64_t inode) = 0;
|
||||
|
||||
virtual FileStat stat(const char *path) = 0;
|
||||
|
||||
virtual uint64_t spaceNeeded(uint64_t size) = 0;
|
||||
|
||||
virtual uint64_t available() = 0;
|
||||
|
||||
virtual uint64_t size() = 0;
|
||||
|
||||
virtual uint8_t *buff() = 0;
|
||||
|
||||
protected:
|
||||
virtual int readDirectory(const char *path, Directory<uint64_t, uint64_t> *dirOut) = 0;
|
||||
};
|
||||
|
||||
template<typename List>
|
||||
int FileSystem::ls(const char *path, List *list) {
|
||||
auto s = stat(path);
|
||||
uint8_t dirBuff[s.size * 4];
|
||||
auto dir = (Directory<uint64_t, uint64_t>*) dirBuff;
|
||||
auto err = readDirectory(path, dir);
|
||||
dir->ls(list);
|
||||
return err;
|
||||
}
|
||||
|
||||
FileSystem *createFileSystem(void *buff, size_t buffSize);
|
||||
|
||||
/**
|
||||
* Creates a larger version of the given FileSystem.
|
||||
*/
|
||||
FileSystem *expandCopy(FileSystem *src);
|
||||
|
||||
/**
|
||||
* Calls expandCopy and deletes the original FileSystem and buff a resize was
|
||||
* performed.
|
||||
*/
|
||||
FileSystem *expandCopyCleanup(FileSystem *fs, size_t size);
|
||||
|
||||
template<typename FileStore, FsType FS_TYPE>
|
||||
class FileSystemTemplate: public FileSystem {
|
||||
|
||||
private:
|
||||
FileStore *m_store = nullptr;
|
||||
|
||||
public:
|
||||
@ -141,6 +275,9 @@ class FileSystemTemplate: public FileSystem {
|
||||
|
||||
int stripDirectories() override;
|
||||
|
||||
template<typename List>
|
||||
int ls(const char *path, List *list);
|
||||
|
||||
int mkdir(const char *path) override;
|
||||
|
||||
int read(const char *path, void *buffer, size_t buffSize) override;
|
||||
@ -157,11 +294,11 @@ class FileSystemTemplate: public FileSystem {
|
||||
|
||||
int remove(const char *path, bool recursive = false) override;
|
||||
|
||||
int write(const char *path, void *buffer, uint64_t size, uint8_t fileType = NormalFile) override;
|
||||
int write(const char *path, void *buffer, uint64_t size, uint8_t fileType = FileType_NormalFile) override;
|
||||
|
||||
int write(uint64_t inode, void *buffer, uint64_t size, uint8_t fileType = NormalFile) override;
|
||||
int write(uint64_t inode, void *buffer, uint64_t size, uint8_t fileType = FileType_NormalFile) override;
|
||||
|
||||
FileStat stat(const char *path);
|
||||
FileStat stat(const char *path) override;
|
||||
|
||||
FileStat stat(uint64_t inode) override;
|
||||
|
||||
@ -189,6 +326,9 @@ class FileSystemTemplate: public FileSystem {
|
||||
|
||||
static uint8_t *format(void *buffer, typename FileStore::FsSize_t size, bool useDirectories);
|
||||
|
||||
protected:
|
||||
int readDirectory(const char *path, Directory<uint64_t, uint64_t> *dirOut) override;
|
||||
|
||||
private:
|
||||
uint64_t generateInodeId();
|
||||
|
||||
@ -211,13 +351,37 @@ typename FileStore::InodeId_t FileSystemTemplate<FileStore, FS_TYPE>::INODE_RESE
|
||||
|
||||
template<typename FileStore, FsType FS_TYPE>
|
||||
int FileSystemTemplate<FileStore, FS_TYPE>::stripDirectories() {
|
||||
return m_store->removeAllType(FileType::Directory);
|
||||
return m_store->removeAllType(FileType::FileType_Directory);
|
||||
}
|
||||
|
||||
template<typename FileStore, FsType FS_TYPE>
|
||||
template<typename List>
|
||||
int FileSystemTemplate<FileStore, FS_TYPE>::ls(const char *path, List *list) {
|
||||
int err = 0;
|
||||
auto inode = findInodeOf(path);
|
||||
auto dirStat = stat(inode);
|
||||
auto dirBuffLen = dirStat.size;
|
||||
uint8_t dirBuff[dirBuffLen];
|
||||
auto dir = (Directory<typename FileStore::InodeId_t, typename FileStore::FsSize_t>*) dirBuff;
|
||||
|
||||
err = read(dirStat.inode, dirBuff, dirBuffLen);
|
||||
if (!err) {
|
||||
dir->ls(list);
|
||||
|
||||
for (auto &i : *list) {
|
||||
i.stat = stat(i.stat.inode);
|
||||
}
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename FileStore, FsType FS_TYPE>
|
||||
int FileSystemTemplate<FileStore, FS_TYPE>::mkdir(const char *path) {
|
||||
Directory dir;
|
||||
return write(path, &dir, sizeof(dir), FileType::Directory);
|
||||
Directory<typename FileStore::InodeId_t, typename FileStore::FsSize_t> dir;
|
||||
return write(path, &dir, sizeof(dir), FileType::FileType_Directory);
|
||||
}
|
||||
|
||||
template<typename FileStore, FsType FS_TYPE>
|
||||
@ -336,14 +500,14 @@ int FileSystemTemplate<FileStore, FS_TYPE>::remove(const char *path, bool recurs
|
||||
template<typename FileStore, FsType FS_TYPE>
|
||||
int FileSystemTemplate<FileStore, FS_TYPE>::remove(uint64_t inode, bool recursive) {
|
||||
auto fileType = stat(inode).fileType;
|
||||
if (fileType != FileType::Directory) {
|
||||
if (fileType != FileType::FileType_Directory) {
|
||||
return m_store->remove(inode);
|
||||
} else if (fileType == FileType::Directory && recursive) {
|
||||
} else if (fileType == FileType::FileType_Directory && recursive) {
|
||||
int err = 0;
|
||||
auto dirStat = stat(inode);
|
||||
auto dirBuffLen = dirStat.size;
|
||||
uint8_t dirBuff[dirBuffLen];
|
||||
auto dir = (Directory*) dirBuff;
|
||||
auto dir = (Directory<typename FileStore::InodeId_t, typename FileStore::FsSize_t>*) dirBuff;
|
||||
|
||||
err = read(dirStat.inode, dirBuff, dirBuffLen);
|
||||
if (err) {
|
||||
@ -425,11 +589,11 @@ uint64_t FileSystemTemplate<FileStore, FS_TYPE>::findInodeOf(const char *path) {
|
||||
uint64_t inode = INODE_ROOT_DIR;
|
||||
while (it.hasNext()) {
|
||||
auto dirStat = stat(inode);
|
||||
if (dirStat.inode && dirStat.size >= sizeof(Directory)) {
|
||||
if (dirStat.inode && dirStat.size >= sizeof(Directory<typename FileStore::InodeId_t, typename FileStore::FsSize_t>)) {
|
||||
uint8_t dirBuffer[dirStat.size];
|
||||
auto dir = (Directory*) dirBuffer;
|
||||
auto dir = (Directory<typename FileStore::InodeId_t, typename FileStore::FsSize_t>*) dirBuffer;
|
||||
if (read(inode, dirBuffer, dirStat.size) == 0) {
|
||||
if (dirStat.fileType == FileType::Directory && it.next(fileName, pathLen) == 0) {
|
||||
if (dirStat.fileType == FileType::FileType_Directory && it.next(fileName, pathLen) == 0) {
|
||||
inode = dir->getFileInode(fileName, dirStat.size);
|
||||
} else {
|
||||
inode = 0; // null out inode and break
|
||||
@ -483,9 +647,9 @@ uint8_t *FileSystemTemplate<FileStore, FS_TYPE>::format(void *buffer, typename F
|
||||
buffer = FileStore::format((uint8_t*) buffer, size, (uint16_t) FS_TYPE);
|
||||
|
||||
if (buffer && useDirectories) {
|
||||
Directory dir;
|
||||
Directory<typename FileStore::InodeId_t, typename FileStore::FsSize_t> dir;
|
||||
FileSystemTemplate<FileStore, FS_TYPE> fs(buffer);
|
||||
fs.write(INODE_ROOT_DIR, &dir, sizeof(dir), FileType::Directory);
|
||||
fs.write(INODE_ROOT_DIR, &dir, sizeof(dir), FileType::FileType_Directory);
|
||||
}
|
||||
|
||||
return (uint8_t*) buffer;
|
||||
@ -524,19 +688,19 @@ template<typename FileStore, FsType FS_TYPE>
|
||||
int FileSystemTemplate<FileStore, FS_TYPE>::insertDirectoryEntry(const char *dirPath, const char *fileName, uint64_t inode) {
|
||||
auto s = stat(dirPath);
|
||||
if (s.inode) {
|
||||
auto spaceNeeded = DirectoryEntry::spaceNeeded(fileName);
|
||||
auto spaceNeeded = DirectoryEntry<typename FileStore::InodeId_t>::spaceNeeded(fileName);
|
||||
size_t dirBuffSize = s.size + spaceNeeded;
|
||||
uint8_t dirBuff[dirBuffSize];
|
||||
int err = read(s.inode, dirBuff, dirBuffSize);
|
||||
|
||||
if (!err) {
|
||||
auto dir = (Directory*) dirBuff;
|
||||
auto dir = (Directory<typename FileStore::InodeId_t, typename FileStore::FsSize_t>*) dirBuff;
|
||||
dir->size += spaceNeeded;
|
||||
dir->children++;
|
||||
auto entry = (DirectoryEntry*) &dirBuff[s.size];
|
||||
auto entry = (DirectoryEntry<typename FileStore::InodeId_t>*) &dirBuff[s.size];
|
||||
entry->inode = inode;
|
||||
entry->setName(fileName);
|
||||
return write(s.inode, dirBuff, dirBuffSize, FileType::Directory);
|
||||
return write(s.inode, dirBuff, dirBuffSize, FileType::FileType_Directory);
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
@ -612,85 +776,38 @@ int FileSystemTemplate<FileStore, FS_TYPE>::rmDirectoryEntry(const char *path) {
|
||||
return err;
|
||||
}
|
||||
|
||||
auto dir = (Directory*) dirBuff;
|
||||
auto dir = (Directory<typename FileStore::InodeId_t, typename FileStore::FsSize_t>*) dirBuff;
|
||||
err = dir->rmFile(fileName);
|
||||
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = write(dirStat.inode, dirBuff, dirBuffLen - DirectoryEntry::spaceNeeded(fileName));
|
||||
err = write(dirStat.inode, dirBuff, dirBuffLen - DirectoryEntry<typename FileStore::InodeId_t>::spaceNeeded(fileName));
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
// Directory
|
||||
|
||||
template<typename FileStore, FsType FS_TYPE>
|
||||
uint64_t FileSystemTemplate<FileStore, FS_TYPE>::Directory::getFileInode(const char *name, uint64_t buffSize) {
|
||||
uint64_t inode = 0;
|
||||
auto current = files();
|
||||
if (current) {
|
||||
for (uint64_t i = 0; ox_strcmp(current->getName(), name) != 0;) {
|
||||
i += current->size();
|
||||
if (i < this->size) {
|
||||
current = (DirectoryEntry*) (((uint8_t*) current) + current->size());
|
||||
} else {
|
||||
current = nullptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (current) {
|
||||
inode = current->inode;
|
||||
}
|
||||
}
|
||||
return inode;
|
||||
}
|
||||
int FileSystemTemplate<FileStore, FS_TYPE>::readDirectory(const char *path, Directory<uint64_t, uint64_t> *dirOut) {
|
||||
int err = 0;
|
||||
auto inode = findInodeOf(path);
|
||||
auto dirStat = stat(inode);
|
||||
auto dirBuffLen = dirStat.size;
|
||||
uint8_t dirBuff[dirBuffLen];
|
||||
auto dir = (Directory<uint64_t, uint64_t>*) dirBuff;
|
||||
|
||||
template<typename FileStore, FsType FS_TYPE>
|
||||
int FileSystemTemplate<FileStore, FS_TYPE>::Directory::getChildrenInodes(typename FileStore::InodeId_t *inodes, size_t inodesLen) {
|
||||
if (inodesLen >= this->children) {
|
||||
auto current = files();
|
||||
if (current) {
|
||||
for (uint64_t i = 0; i < this->children; i++) {
|
||||
inodes[i] = current->inode;
|
||||
current = (DirectoryEntry*) (((uint8_t*) current) + current->size());
|
||||
}
|
||||
return 0;
|
||||
err = read(dirStat.inode, dirBuff, dirBuffLen);
|
||||
if (!err) {
|
||||
return dir->copy(dirOut);
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename FileStore, FsType FS_TYPE>
|
||||
int FileSystemTemplate<FileStore, FS_TYPE>::Directory::rmFile(const char *name) {
|
||||
int err = 1;
|
||||
auto current = files();
|
||||
if (current) {
|
||||
for (uint64_t i = 0; i < this->size;) {
|
||||
i += current->size();
|
||||
if (ox_strcmp(current->getName(), name) == 0) {
|
||||
auto dest = (uint8_t*) current;
|
||||
auto src = dest + current->size();
|
||||
ox_memcpy(dest, src, this->size - i);
|
||||
this->size -= current->size();
|
||||
this->children--;
|
||||
err = 0;
|
||||
break;
|
||||
}
|
||||
current = (DirectoryEntry*) (((uint8_t*) current) + current->size());
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
typedef FileSystemTemplate<FileStore16, OxFS_16> FileSystem16;
|
||||
typedef FileSystemTemplate<FileStore32, OxFS_32> FileSystem32;
|
||||
typedef FileSystemTemplate<FileStore64, OxFS_64> FileSystem64;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@
|
||||
#pragma warning(disable:4996)
|
||||
#endif
|
||||
|
||||
using namespace ox::fs;
|
||||
using namespace ox;
|
||||
using namespace std;
|
||||
|
||||
const static auto oxfstoolVersion = "1.3.0";
|
||||
@ -128,9 +128,9 @@ int format(int argc, char **args) {
|
||||
delete []buff;
|
||||
|
||||
if (err == 0) {
|
||||
cerr << "Created file system of type " << type << " " << path << endl;
|
||||
cerr << "\ttype " << type << endl;
|
||||
cerr << "\twrote " << size << " bytes\n";
|
||||
cerr << "Created file system " << path << endl;
|
||||
cerr << " type " << type << endl;
|
||||
cerr << " wrote " << size << " bytes\n";
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Insufficient arguments\n");
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "pathiterator.hpp"
|
||||
|
||||
namespace ox {
|
||||
namespace fs {
|
||||
|
||||
PathIterator::PathIterator(const char *path, size_t maxSize) {
|
||||
m_path = path;
|
||||
@ -97,4 +96,3 @@ bool PathIterator::hasNext() {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include <ox/std/types.hpp>
|
||||
|
||||
namespace ox {
|
||||
namespace fs {
|
||||
|
||||
class PathIterator {
|
||||
private:
|
||||
@ -41,4 +40,3 @@ class PathIterator {
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -43,3 +43,4 @@ add_test("Test\\ FileSystem32::rmDirectoryEntry\\(string\\)" FSTests "FileSystem
|
||||
add_test("Test\\ FileSystem32::remove\\(string,\\ true\\)" FSTests "FileSystem32::remove(string, true)")
|
||||
add_test("Test\\ FileSystem32::move" FSTests "FileSystem32::move")
|
||||
add_test("Test\\ FileSystem32::stripDirectories" FSTests "FileSystem32::stripDirectories")
|
||||
add_test("Test\\ FileSystem32::ls" FSTests "FileSystem32::ls")
|
||||
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
#include <ox/fs/filestore.hpp>
|
||||
|
||||
using namespace ox::fs;
|
||||
using namespace ox;
|
||||
|
||||
int main() {
|
||||
const auto size = 65535;
|
||||
|
@ -9,8 +9,7 @@
|
||||
#include <ox/std/std.hpp>
|
||||
#include <ox/fs/filestore.hpp>
|
||||
|
||||
using namespace ox::fs;
|
||||
using namespace ox::std;
|
||||
using namespace ox;
|
||||
|
||||
template<typename FileStore>
|
||||
int test() {
|
||||
|
@ -8,8 +8,7 @@
|
||||
|
||||
#include <ox/fs/filesystem.hpp>
|
||||
|
||||
using namespace ox::fs;
|
||||
using namespace ox::std;
|
||||
using namespace ox;
|
||||
|
||||
template<typename FileSystem>
|
||||
int test() {
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include <ox/std/std.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace ox::fs;
|
||||
using namespace ox;
|
||||
|
||||
map<string, int(*)(string)> tests = {
|
||||
{
|
||||
@ -288,6 +288,40 @@ map<string, int(*)(string)> tests = {
|
||||
delete []buff;
|
||||
delete []dataOut;
|
||||
|
||||
return retval;
|
||||
}
|
||||
},
|
||||
{
|
||||
"FileSystem32::ls",
|
||||
[](string) {
|
||||
int retval = 0;
|
||||
auto dataIn = "test string";
|
||||
auto dataOutLen = ox_strlen(dataIn) + 1;
|
||||
auto dataOut = new char[dataOutLen];
|
||||
vector<uint64_t> inodes;
|
||||
vector<DirectoryListing<string>> files;
|
||||
|
||||
const auto size = 1024 * 1024;
|
||||
auto buff = new uint8_t[size];
|
||||
FileSystem32::format(buff, (FileStore32::FsSize_t) size, true);
|
||||
auto fs = (FileSystem32*) createFileSystem(buff, size);
|
||||
|
||||
retval |= fs->mkdir("/usr");
|
||||
retval |= fs->mkdir("/usr/share");
|
||||
retval |= fs->write("/usr/share/a.txt", (void*) dataIn, ox_strlen(dataIn) + 1);
|
||||
retval |= fs->write("/usr/share/b.txt", (void*) dataIn, ox_strlen(dataIn) + 1);
|
||||
retval |= fs->write("/usr/share/c.txt", (void*) dataIn, ox_strlen(dataIn) + 1);
|
||||
|
||||
fs->ls("/usr/share/", &files);
|
||||
|
||||
retval |= !(files[0].name == "a.txt");
|
||||
retval |= !(files[1].name == "b.txt");
|
||||
retval |= !(files[2].name == "c.txt");
|
||||
|
||||
delete fs;
|
||||
delete []buff;
|
||||
delete []dataOut;
|
||||
|
||||
return retval;
|
||||
}
|
||||
},
|
||||
|
@ -74,7 +74,7 @@ int MetalClawReader::op(const char*, ox::bstring<L> *val) {
|
||||
typedef uint32_t StringLength;
|
||||
size_t size = 0;
|
||||
if (m_buffIt + sizeof(StringLength) < m_buffLen) {
|
||||
size = ox::std::bigEndianAdapt(*((StringLength*) &m_buff[m_buffIt]));
|
||||
size = ox::bigEndianAdapt(*((StringLength*) &m_buff[m_buffIt]));
|
||||
m_buffIt += sizeof(StringLength);
|
||||
} else {
|
||||
err |= MC_BUFFENDED;
|
||||
@ -103,7 +103,7 @@ int MetalClawReader::readInteger(I *val) {
|
||||
int err = 0;
|
||||
if (m_fieldPresence.get(m_field)) {
|
||||
if (m_buffIt + sizeof(I) < m_buffLen) {
|
||||
*val = ox::std::bigEndianAdapt(*((I*) &m_buff[m_buffIt]));
|
||||
*val = ox::bigEndianAdapt(*((I*) &m_buff[m_buffIt]));
|
||||
m_buffIt += sizeof(I);
|
||||
} else {
|
||||
err = MC_BUFFENDED;
|
||||
@ -123,7 +123,7 @@ int MetalClawReader::op(const char*, T *val, size_t valLen) {
|
||||
typedef uint32_t ArrayLength;
|
||||
size_t len = 0;
|
||||
if (m_buffIt + sizeof(ArrayLength) < m_buffLen) {
|
||||
len = ox::std::bigEndianAdapt(*((T*) &m_buff[m_buffIt]));
|
||||
len = ox::bigEndianAdapt(*((T*) &m_buff[m_buffIt]));
|
||||
m_buffIt += sizeof(ArrayLength);
|
||||
} else {
|
||||
err = MC_BUFFENDED;
|
||||
|
@ -62,7 +62,7 @@ int MetalClawWriter::op(const char*, ox::bstring<L> *val) {
|
||||
// write the length
|
||||
typedef uint32_t StringLength;
|
||||
if (m_buffIt + sizeof(StringLength) + val->size() < m_buffLen) {
|
||||
*((StringLength*) &m_buff[m_buffIt]) = ox::std::bigEndianAdapt((StringLength) val->size());
|
||||
*((StringLength*) &m_buff[m_buffIt]) = ox::bigEndianAdapt((StringLength) val->size());
|
||||
m_buffIt += sizeof(StringLength);
|
||||
|
||||
// write the string
|
||||
@ -99,7 +99,7 @@ int MetalClawWriter::appendInteger(I val) {
|
||||
bool fieldSet = false;
|
||||
if (val) {
|
||||
if (m_buffIt + sizeof(I) < m_buffLen) {
|
||||
*((I*) &m_buff[m_buffIt]) = ox::std::bigEndianAdapt(val);
|
||||
*((I*) &m_buff[m_buffIt]) = ox::bigEndianAdapt(val);
|
||||
fieldSet = true;
|
||||
m_buffIt += sizeof(I);
|
||||
} else {
|
||||
@ -120,7 +120,7 @@ int MetalClawWriter::op(const char*, T *val, size_t len) {
|
||||
// write the length
|
||||
typedef uint32_t ArrayLength;
|
||||
if (m_buffIt + sizeof(ArrayLength) < m_buffLen) {
|
||||
*((T*) &m_buff[m_buffIt]) = ox::std::bigEndianAdapt((ArrayLength) len);
|
||||
*((T*) &m_buff[m_buffIt]) = ox::bigEndianAdapt((ArrayLength) len);
|
||||
m_buffIt += sizeof(ArrayLength);
|
||||
} else {
|
||||
err = MC_BUFFENDED;
|
||||
|
@ -11,8 +11,6 @@
|
||||
#include "types.hpp"
|
||||
|
||||
namespace ox {
|
||||
namespace std {
|
||||
|
||||
|
||||
inline int16_t byteSwap(int16_t i) {
|
||||
return (i << 8) | (i >> 8);
|
||||
@ -140,6 +138,4 @@ inline uint64_t bigEndianAdapt(uint64_t i) {
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include <ox/std/std.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace ox::std;
|
||||
using namespace ox;
|
||||
|
||||
template<typename T>
|
||||
int testBigEndianAdapt(string str) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user