diff --git a/deps/ox/src/ox/fs/filesystem2/filesystem.hpp b/deps/ox/src/ox/fs/filesystem2/filesystem.hpp new file mode 100644 index 00000000..7a615b50 --- /dev/null +++ b/deps/ox/src/ox/fs/filesystem2/filesystem.hpp @@ -0,0 +1,245 @@ +/* + * Copyright 2015 - 2018 gtalent2@gmail.com + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include +#include + +#include "directory.hpp" + +namespace ox::fs { + +template +class FileSystemTemplate { + private: + static constexpr InodeId_t InodeFsData = 2; + + struct __attribute__((packed)) FileSystemData { + LittleEndian rootDirInode; + }; + + FileStore *m_fs = nullptr; + + public: + FileSystemTemplate(FileStore *fs); + + ~FileSystemTemplate(); + + Error format(); + + Error mkdir(const char *path, bool recursive = false); + + /** + * Moves an entry from one directory to another. + * @param src the path to the file + * @param dest the path of the destination directory + */ + Error move(const char *src, const char *dest); + + Error read(const char *path, void *buffer, std::size_t buffSize); + + Error read(uint64_t inode, void *buffer, std::size_t size); + + Error read(uint64_t inode, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size); + + Error remove(const char *path, bool recursive = false); + + void resize(uint64_t size = 0); + + Error write(const char *path, void *buffer, uint64_t size, uint8_t fileType = FileType_NormalFile); + + Error write(uint64_t inode, void *buffer, uint64_t size, uint8_t fileType = FileType_NormalFile); + + FileStat stat(uint64_t inode); + + FileStat stat(const char *path); + + uint64_t spaceNeeded(uint64_t size); + + uint64_t available(); + + uint64_t size(); + + uint8_t *buff(); + + void walk(int(*cb)(const char*, uint64_t, uint64_t)); + + bool valid() const; + + private: + ValErr fileSystemData(); + +}; + +template +FileSystemTemplate::FileSystemTemplate(FileStore *fs) { + m_fs = fs; +} + +template +FileSystemTemplate::~FileSystemTemplate() { +} + +template +Error FileSystemTemplate::format() { + oxReturnError(m_fs->format()); + + constexpr auto rootDirInode = MaxValue / 2; + auto rootDir = ox_malloca(sizeof(ox::fs::Directory), ox::fs::Directory, m_fs, rootDirInode); + oxReturnError(rootDir->init()); + + FileSystemData fd; + fd.rootDirInode = rootDirInode; + oxTrace("ox::fs::FileSystemTemplate::format") << "rootDirInode:" << fd.rootDirInode; + oxReturnError(m_fs->write(InodeFsData, &fd, sizeof(fd))); + + if (m_fs->read(fd.rootDirInode).valid()) { + oxTrace("ox::fs::FileSystemTemplate::format::error") << "FileSystemTemplate::format did not correctly create root directory"; + } + + return OxError(0); +} + +template +Error FileSystemTemplate::mkdir(const char *path, bool recursive) { + auto fd = fileSystemData(); + if (fd.ok()) { + oxTrace("ox::fs::FileSystemTemplate::mkdir") << "rootDirInode:" << fd.value.rootDirInode; + auto rootDir = ox_malloca(sizeof(ox::fs::Directory), ox::fs::Directory, m_fs, fd.value.rootDirInode); + return rootDir->mkdir(path, recursive); + } else { + oxLogError(fd.error); + return fd.error; + } +} + +template +Error FileSystemTemplate::move(const char *src, const char *dest) { + auto fd = fileSystemData(); + if (fd.ok()) { + auto rootDir = ox_malloca(sizeof(ox::fs::Directory), ox::fs::Directory, m_fs, fd.value.rootDirInode); + auto inode = rootDir->find(src); + oxReturnError(inode.error); + oxReturnError(rootDir->write(dest, inode)); + oxReturnError(rootDir->remove(src)); + return OxError(0); + } else { + return fd.error; + } +} + +template +Error FileSystemTemplate::read(const char *path, void *buffer, std::size_t buffSize) { + auto fd = fileSystemData(); + if (fd.ok()) { + auto rootDir = ox_malloca(sizeof(ox::fs::Directory), ox::fs::Directory, m_fs, fd.value.rootDirInode); + auto inode = rootDir->find(path); + oxReturnError(inode.error); + return read(inode, buffer, buffSize); + } else { + return fd.error; + } +} + +template +Error FileSystemTemplate::read(uint64_t inode, void *buffer, std::size_t buffSize) { + return m_fs->read(inode, buffer, buffSize); +} + +template +Error FileSystemTemplate::read(uint64_t inode, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) { + return m_fs->read(inode, readStart, readSize, buffer, size); +} + +template +Error FileSystemTemplate::remove(const char *path, bool recursive) { + auto fd = fileSystemData(); + if (fd.ok()) { + auto rootDir = ox_malloca(sizeof(ox::fs::Directory), ox::fs::Directory, m_fs, fd.value.rootDirInode); + auto inode = rootDir->find(path); + oxReturnError(inode.error); + if (auto err = rootDir->remove(path)) { + // removal failed, try putting the index back + oxLogError(rootDir->write(path, inode)); + return err; + } + return OxError(0); + } else { + return fd.error; + } +} + +template +void FileSystemTemplate::resize(uint64_t size) { +} + +template +Error FileSystemTemplate::write(const char *path, void *buffer, uint64_t size, uint8_t fileType) { + return OxError(0); +} + +template +Error FileSystemTemplate::write(uint64_t inode, void *buffer, uint64_t size, uint8_t fileType) { + return OxError(0); +} + +template +FileStat FileSystemTemplate::stat(uint64_t inode) { + return {}; +} + +template +FileStat FileSystemTemplate::stat(const char *path) { + return {}; +} + +template +uint64_t FileSystemTemplate::spaceNeeded(uint64_t size) { + return 0; +} + +template +uint64_t FileSystemTemplate::available() { + return 0; +} + +template +uint64_t FileSystemTemplate::size() { + return 0; +} + +template +uint8_t *FileSystemTemplate::buff() { + return nullptr; +} + +template +void FileSystemTemplate::walk(int(*cb)(const char*, uint64_t, uint64_t)) { +} + +template +ValErr::FileSystemData> FileSystemTemplate::fileSystemData() { + FileSystemData fd; + auto err = m_fs->read(InodeFsData, &fd, sizeof(fd)); + if (err != 0) { + return {fd, err}; + } + return fd; +} + +extern template class Directory; +extern template class Directory; + +extern template class FileSystemTemplate; +extern template class FileSystemTemplate; + +using FileSystem16 = FileSystemTemplate; +using FileSystem32 = FileSystemTemplate; + +}