From 2be5b0f6bccb0503359ebcb21483d9d0aded470a Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Fri, 28 Jan 2022 01:22:37 -0600 Subject: [PATCH] [ox] Add a new oxfs tool --- deps/ox/src/ox/fs/CMakeLists.txt | 20 +++++ deps/ox/src/ox/fs/filesystem/directory.hpp | 6 +- deps/ox/src/ox/fs/filesystem/filelocation.hpp | 2 - deps/ox/src/ox/fs/filesystem/filesystem.hpp | 8 +- deps/ox/src/ox/fs/tool.cpp | 84 +++++++++++++++++++ 5 files changed, 114 insertions(+), 6 deletions(-) create mode 100644 deps/ox/src/ox/fs/tool.cpp diff --git a/deps/ox/src/ox/fs/CMakeLists.txt b/deps/ox/src/ox/fs/CMakeLists.txt index 792e8597..620e15be 100644 --- a/deps/ox/src/ox/fs/CMakeLists.txt +++ b/deps/ox/src/ox/fs/CMakeLists.txt @@ -29,6 +29,26 @@ target_link_libraries( OxMetalClaw ) +if(NOT OX_BARE_METAL) + add_executable( + oxfs + tool.cpp + ) + + target_link_libraries( + oxfs + OxFS + OxStd + ) + + install( + TARGETS + oxfs + DESTINATION + bin + ) +endif() + install( FILES filestore/filestoretemplate.hpp diff --git a/deps/ox/src/ox/fs/filesystem/directory.hpp b/deps/ox/src/ox/fs/filesystem/directory.hpp index 4b3d9b53..b60e812f 100644 --- a/deps/ox/src/ox/fs/filesystem/directory.hpp +++ b/deps/ox/src/ox/fs/filesystem/directory.hpp @@ -41,9 +41,9 @@ struct OX_PACKED DirectoryEntry { LittleEndian m_bufferSize = sizeof(DirectoryEntry); public: - DirectoryEntry() = default; + constexpr DirectoryEntry() noexcept = default; - Error init(InodeId_t inode, const char *name, InodeId_t bufferSize) { + Error init(InodeId_t inode, const char *name, InodeId_t bufferSize) noexcept { m_bufferSize = bufferSize; auto d = data(); if (d.valid()) { @@ -54,7 +54,7 @@ struct OX_PACKED DirectoryEntry { return OxError(1); } - ptrarith::Ptr data() { + ptrarith::Ptr data() noexcept { oxTracef("ox::fs::DirectoryEntry::data", "{} {} {}", this->fullSize(), sizeof(*this), this->size()); return ptrarith::Ptr(this, this->fullSize(), sizeof(*this), this->size(), this->size()); } diff --git a/deps/ox/src/ox/fs/filesystem/filelocation.hpp b/deps/ox/src/ox/fs/filesystem/filelocation.hpp index 928353cf..414c5e2b 100644 --- a/deps/ox/src/ox/fs/filesystem/filelocation.hpp +++ b/deps/ox/src/ox/fs/filesystem/filelocation.hpp @@ -28,11 +28,9 @@ class FileAddress { public: static constexpr auto TypeName = "net.drinkingtea.ox.FileAddress"; - static constexpr auto Fields = 2; union Data { static constexpr auto TypeName = "net.drinkingtea.ox.FileAddress.Data"; - static constexpr auto Fields = 3; char *path = nullptr; const char *constPath; uint64_t inode; diff --git a/deps/ox/src/ox/fs/filesystem/filesystem.hpp b/deps/ox/src/ox/fs/filesystem/filesystem.hpp index f7b2d355..cddc7ba8 100644 --- a/deps/ox/src/ox/fs/filesystem/filesystem.hpp +++ b/deps/ox/src/ox/fs/filesystem/filesystem.hpp @@ -18,6 +18,12 @@ namespace ox { +namespace detail { +static inline void fsBuffFree(char *buff) noexcept { + delete buff; +} +} + class FileSystem { public: @@ -111,7 +117,7 @@ class FileSystemTemplate: public FileSystem { public: FileSystemTemplate() noexcept = default; - FileSystemTemplate(void *buffer, uint64_t bufferSize, void(*freeBuffer)(char*) = [](const char *buff) { delete buff; }) noexcept; + FileSystemTemplate(void *buffer, uint64_t bufferSize, void(*freeBuffer)(char*) = detail::fsBuffFree) noexcept; explicit FileSystemTemplate(FileStore fs) noexcept; diff --git a/deps/ox/src/ox/fs/tool.cpp b/deps/ox/src/ox/fs/tool.cpp new file mode 100644 index 00000000..02fdaaf1 --- /dev/null +++ b/deps/ox/src/ox/fs/tool.cpp @@ -0,0 +1,84 @@ +/* + * Copyright 2015 - 2022 gary@drinkingtea.net + * + * 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/. + */ + +#include +#include + +#include + +struct Buff { + char *data = nullptr; + std::size_t size = 0; +}; + +static ox::Result loadFsBuff(const char *path) noexcept { + std::ifstream file(path, std::ios::binary | std::ios::ate); + if (!file.good()) { + oxErrorf("Could not find OxFS file: {}", path); + return OxError(1, "Could not find OxFS file"); + } + try { + const auto size = static_cast(file.tellg()); + file.seekg(0, std::ios::beg); + const auto buff = new char[size]; + file.read(buff, size); + return Buff{buff, size}; + } catch (const std::ios_base::failure &e) { + oxErrorf("Could not read OxFS file: {}", e.what()); + return OxError(2, "Could not read OxFS file"); + } +} + +static ox::Result> loadFs(const char *path) noexcept { + oxRequire(buff, loadFsBuff(path)); + return {ox::make_unique(buff.data, buff.size)}; +} + +static ox::Error runLs(ox::FileSystem *fs, int argc, const char **argv) noexcept { + if (argc < 2) { + oxErr("Must provide a directory to ls\n"); + return OxError(1); + } + oxRequire(files, fs->ls(argv[1])); + for (const auto &file : files) { + oxOutf("{}\n", file); + } + return OxError(0); +} + +static ox::Error runRead(ox::FileSystem *fs, int argc, const char **argv) noexcept { + if (argc < 2) { + oxErr("Must provide a path to a file to read\n"); + return OxError(1); + } + oxRequire(buff, fs->read(argv[1])); + fwrite(buff.data(), sizeof(decltype(buff)::value_type), buff.size(), stdout); + return OxError(0); +} + +static ox::Error run(int argc, const char **argv) noexcept { + if (argc < 2) { + oxErr("Subcommand and OxFS file arguments are required\n"); + return OxError(1); + } + const auto fsPath = argv[1]; + ox::String subCmd = argv[2]; + oxRequire(fs, loadFs(fsPath)); + if (subCmd == "ls") { + return runLs(fs.get(), argc - 2, argv + 2); + } else if (subCmd == "read") { + return runRead(fs.get(), argc - 2, argv + 2); + } + return OxError(1); +} + +int main(int argc, const char **argv) { + auto err = run(argc, argv); + oxAssert(err, "unhandled error"); + return static_cast(err); +}