diff --git a/src/ox/fs/filestore.hpp b/src/ox/fs/filestore.hpp index 5b0fc32b0..c33b2bd41 100644 --- a/src/ox/fs/filestore.hpp +++ b/src/ox/fs/filestore.hpp @@ -13,12 +13,24 @@ namespace ox { namespace fs { template +struct FileStoreHeader { + typedef FsT FsSize_t; + const static auto VERSION = 2; + + uint16_t version; + uint16_t fsType; + FsSize_t size; + FsSize_t memUsed; + FsSize_t rootInode; +}; + +template class FileStore { public: typedef uint16_t InodeId_t; typedef FsT FsSize_t; - const static auto VERSION = 2; + const static auto VERSION = Header::VERSION; struct StatInfo { InodeId_t inodeId; @@ -42,17 +54,13 @@ class FileStore { void *data(); }; - uint16_t m_version; - uint16_t m_fsType; - FsSize_t m_size; - FsSize_t m_memUsed; - FsSize_t m_rootInode; + Header m_header; public: /** * Dumps this file store's inodes to the given file store. */ - int dumpTo(FileStore *dest); + int dumpTo(FileStore *dest); /** * Compacts and resizes the file store to the minimum possible size for @@ -196,7 +204,7 @@ class FileStore { } uint8_t *end() { - return begin() + this->m_size; + return begin() + this->m_header.size; } /** @@ -214,33 +222,33 @@ class FileStore { }; -template -FsSize_t FileStore::Inode::size() { +template +FsSize_t FileStore::Inode::size() { return sizeof(Inode) + dataLen; } -template -void FileStore::Inode::setId(InodeId_t id) { +template +void FileStore::Inode::setId(InodeId_t id) { this->id = id; } -template -void FileStore::Inode::setData(void *data, FsSize_t size) { +template +void FileStore::Inode::setData(void *data, FsSize_t size) { ox_memcpy(this->data(), data, size); dataLen = size; } -template -void *FileStore::Inode::data() { +template +void *FileStore::Inode::data() { return this + 1; } // FileStore -template -int FileStore::dumpTo(FileStore *dest) { +template +int FileStore::dumpTo(FileStore *dest) { if (dest->size() >= size()) { auto i = ptr(firstInode()); do { @@ -253,33 +261,33 @@ int FileStore::dumpTo(FileStore *dest) { } } -template -void FileStore::resize(FsSize_t size) { - if (size < m_size) { +template +void FileStore::resize(FsSize_t size) { + if (size < m_header.size) { // shrink file store - if (m_memUsed > size) { - size = m_memUsed; + if (m_header.memUsed > size) { + size = m_header.memUsed; } compact(); - m_size = size; - } else if (size > m_size) { + m_header.size = size; + } else if (size > m_header.size) { // grow file store - m_size = size; + m_header.size = size; } } -template -int FileStore::write(InodeId_t id, void *data, FsSize_t dataLen, uint8_t fileType) { +template +int FileStore::write(InodeId_t id, void *data, FsSize_t dataLen, uint8_t fileType) { auto retval = 1; const FsSize_t size = sizeof(Inode) + dataLen; - if (size <= (m_size - m_memUsed)) { + if (size <= (m_header.size - m_header.memUsed)) { auto inode = (Inode*) alloc(size); if (inode) { remove(id); inode->id = id; inode->fileType = fileType; inode->setData(data, dataLen); - auto root = ptr(m_rootInode); + auto root = ptr(m_header.rootInode); if (insert(root, inode) || root == inode) { retval = 0; } @@ -288,13 +296,13 @@ int FileStore::write(InodeId_t id, void *data, FsSize_t dataLen, uint8 return retval; } -template -int FileStore::remove(InodeId_t id) { - return remove(ptr(m_rootInode), id); +template +int FileStore::remove(InodeId_t id) { + return remove(ptr(m_header.rootInode), id); } -template -int FileStore::remove(Inode *root, InodeId_t id) { +template +int FileStore::remove(Inode *root, InodeId_t id) { auto err = 1; if (root->id > id) { @@ -337,10 +345,10 @@ int FileStore::remove(Inode *root, InodeId_t id) { err = 0; } } - } else if (ptr(m_rootInode)->id == id) { - m_rootInode = root->right; + } else if (ptr(m_header.rootInode)->id == id) { + m_header.rootInode = root->right; if (root->left) { - insert(ptr(m_rootInode), ptr(root->left)); + insert(ptr(m_header.rootInode), ptr(root->left)); } dealloc(root); root->id = 0; @@ -352,21 +360,21 @@ int FileStore::remove(Inode *root, InodeId_t id) { return err; } -template -void FileStore::dealloc(Inode *inode) { +template +void FileStore::dealloc(Inode *inode) { auto next = ptr(inode->next); auto prev = ptr(inode->prev); prev->next = ptr(next); next->prev = ptr(prev); - m_memUsed -= inode->size(); + m_header.memUsed -= inode->size(); ox_memset(inode, 0, inode->size()); } -template -void FileStore::updateInodeAddress(InodeId_t id, FsSize_t oldAddr, FsSize_t newAddr) { - auto parent = getInodeParent(ptr(m_rootInode), id, oldAddr); +template +void FileStore::updateInodeAddress(InodeId_t id, FsSize_t oldAddr, FsSize_t newAddr) { + auto parent = getInodeParent(ptr(m_header.rootInode), id, oldAddr); if (parent) { if (parent->left == oldAddr) { parent->left = newAddr; @@ -376,9 +384,9 @@ void FileStore::updateInodeAddress(InodeId_t id, FsSize_t oldAddr, FsS } } -template -int FileStore::read(InodeId_t id, void *data, FsSize_t *size) { - auto inode = getInode(ptr(m_rootInode), id); +template +int FileStore::read(InodeId_t id, void *data, FsSize_t *size) { + auto inode = getInode(ptr(m_header.rootInode), id); int retval = 1; if (inode) { if (size) { @@ -390,9 +398,9 @@ int FileStore::read(InodeId_t id, void *data, FsSize_t *size) { return retval; } -template -typename FileStore::StatInfo FileStore::stat(InodeId_t id) { - auto inode = getInode(ptr(m_rootInode), id); +template +typename FileStore::StatInfo FileStore::stat(InodeId_t id) { + auto inode = getInode(ptr(m_header.rootInode), id); StatInfo stat; if (inode) { stat.size = inode->dataLen; @@ -404,28 +412,28 @@ typename FileStore::StatInfo FileStore::stat(InodeId_t id) { return stat; } -template -FsSize_t FileStore::spaceNeeded(InodeId_t id, FsSize_t size) { +template +FsSize_t FileStore::spaceNeeded(InodeId_t id, FsSize_t size) { FsSize_t needed = sizeof(Inode) + size;; - auto inode = getInode(ptr(m_rootInode), id); + auto inode = getInode(ptr(m_header.rootInode), id); if (inode) { needed -= inode->size(); } return needed; } -template -FsSize_t FileStore::size() { - return m_size; +template +FsSize_t FileStore::size() { + return m_header.size; } -template -FsSize_t FileStore::available() { - return m_size - m_memUsed; +template +FsSize_t FileStore::available() { + return m_header.size - m_header.memUsed; } -template -typename FileStore::Inode *FileStore::getInode(Inode *root, InodeId_t id) { +template +typename FileStore::Inode *FileStore::getInode(Inode *root, InodeId_t id) { Inode *retval = nullptr; if (root->id > id) { @@ -443,8 +451,8 @@ typename FileStore::Inode *FileStore::getInode(Inode *root, return retval; } -template -typename FileStore::Inode *FileStore::getInodeParent(Inode *root, InodeId_t id, FsSize_t targetAddr) { +template +typename FileStore::Inode *FileStore::getInodeParent(Inode *root, InodeId_t id, FsSize_t targetAddr) { Inode *retval = nullptr; if (root->id > id) { @@ -468,14 +476,14 @@ typename FileStore::Inode *FileStore::getInodeParent(Inode * return retval; } -template -FsSize_t FileStore::nextInodeAddr() { +template +FsSize_t FileStore::nextInodeAddr() { FsSize_t next = ptr(lastInode()) + lastInode()->size(); return next; } -template -void *FileStore::alloc(FsSize_t size) { +template +void *FileStore::alloc(FsSize_t size) { FsSize_t next = nextInodeAddr(); if ((next + size) > (uint64_t) end()) { compact(); @@ -490,13 +498,13 @@ void *FileStore::alloc(FsSize_t size) { ox_memset(inode, 0, size); inode->prev = ptr(firstInode())->prev; inode->next = retval + size; - m_memUsed += size; + m_header.memUsed += size; ptr(firstInode())->prev = retval; return inode; } -template -void FileStore::compact() { +template +void FileStore::compact() { auto dest = ptr(firstInode()); auto current = ptr(firstInode()); while (current->next > firstInode() && current->next < ptr(end())) { @@ -511,8 +519,8 @@ void FileStore::compact() { } } -template -bool FileStore::insert(Inode *root, Inode *insertValue) { +template +bool FileStore::insert(Inode *root, Inode *insertValue) { auto retval = false; if (root->id > insertValue->id) { @@ -529,21 +537,21 @@ bool FileStore::insert(Inode *root, Inode *insertValue) { root->right = ptr(insertValue); retval = true; } - } else if (m_rootInode == 0) { - m_rootInode = ptr(insertValue); + } else if (m_header.rootInode == 0) { + m_header.rootInode = ptr(insertValue); retval = true; } return retval; } -template -FsSize_t FileStore::iterator() { +template +FsSize_t FileStore::iterator() { return ptr(lastInode()) + lastInode()->size(); } -template -FsSize_t FileStore::ptr(void *ptr) { +template +FsSize_t FileStore::ptr(void *ptr) { #ifdef _MSC_VER #pragma warning(disable:4244) #endif @@ -553,45 +561,45 @@ FsSize_t FileStore::ptr(void *ptr) { #endif } -template -FsSize_t FileStore::firstInode() { - return sizeof(FileStore); +template +FsSize_t FileStore::firstInode() { + return sizeof(FileStore); } -template -typename FileStore::Inode *FileStore::lastInode() { +template +typename FileStore::Inode *FileStore::lastInode() { return ptr(ptr(firstInode())->prev); } -template -uint16_t FileStore::fsType() { - return m_fsType; +template +uint16_t FileStore::fsType() { + return m_header.fsType; }; -template -uint16_t FileStore::version() { - return m_version; +template +uint16_t FileStore::version() { + return m_header.version; }; -template -uint8_t *FileStore::format(uint8_t *buffer, FsSize_t size, uint16_t fsType) { +template +uint8_t *FileStore::format(uint8_t *buffer, FsSize_t size, uint16_t fsType) { ox_memset(buffer, 0, size); auto *fs = (FileStore*) buffer; - fs->m_fsType = fsType; - fs->m_version = VERSION; - fs->m_size = size; - fs->m_memUsed = sizeof(FileStore) + sizeof(Inode); - fs->m_rootInode = sizeof(FileStore); - ((Inode*) (fs + 1))->prev = sizeof(FileStore); - fs->lastInode()->next = sizeof(FileStore); + fs->m_header.fsType = fsType; + fs->m_header.version = Header::VERSION; + fs->m_header.size = size; + fs->m_header.memUsed = sizeof(FileStore) + sizeof(Inode); + fs->m_header.rootInode = sizeof(FileStore); + ((Inode*) (fs + 1))->prev = sizeof(FileStore); + fs->lastInode()->next = sizeof(FileStore); return (uint8_t*) buffer; } -typedef FileStore FileStore16; -typedef FileStore FileStore32; -typedef FileStore FileStore64; +typedef FileStore> FileStore16; +typedef FileStore> FileStore32; +typedef FileStore> FileStore64; } }