[ox] Add a new oxfs tool

This commit is contained in:
Gary Talent 2022-01-28 01:22:37 -06:00
parent df782129bb
commit 2be5b0f6bc
5 changed files with 114 additions and 6 deletions

View File

@ -29,6 +29,26 @@ target_link_libraries(
OxMetalClaw OxMetalClaw
) )
if(NOT OX_BARE_METAL)
add_executable(
oxfs
tool.cpp
)
target_link_libraries(
oxfs
OxFS
OxStd
)
install(
TARGETS
oxfs
DESTINATION
bin
)
endif()
install( install(
FILES FILES
filestore/filestoretemplate.hpp filestore/filestoretemplate.hpp

View File

@ -41,9 +41,9 @@ struct OX_PACKED DirectoryEntry {
LittleEndian<InodeId_t> m_bufferSize = sizeof(DirectoryEntry); LittleEndian<InodeId_t> m_bufferSize = sizeof(DirectoryEntry);
public: 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; m_bufferSize = bufferSize;
auto d = data(); auto d = data();
if (d.valid()) { if (d.valid()) {
@ -54,7 +54,7 @@ struct OX_PACKED DirectoryEntry {
return OxError(1); return OxError(1);
} }
ptrarith::Ptr<DirectoryEntryData, InodeId_t> data() { ptrarith::Ptr<DirectoryEntryData, InodeId_t> data() noexcept {
oxTracef("ox::fs::DirectoryEntry::data", "{} {} {}", this->fullSize(), sizeof(*this), this->size()); oxTracef("ox::fs::DirectoryEntry::data", "{} {} {}", this->fullSize(), sizeof(*this), this->size());
return ptrarith::Ptr<DirectoryEntryData, InodeId_t>(this, this->fullSize(), sizeof(*this), this->size(), this->size()); return ptrarith::Ptr<DirectoryEntryData, InodeId_t>(this, this->fullSize(), sizeof(*this), this->size(), this->size());
} }

View File

@ -28,11 +28,9 @@ class FileAddress {
public: public:
static constexpr auto TypeName = "net.drinkingtea.ox.FileAddress"; static constexpr auto TypeName = "net.drinkingtea.ox.FileAddress";
static constexpr auto Fields = 2;
union Data { union Data {
static constexpr auto TypeName = "net.drinkingtea.ox.FileAddress.Data"; static constexpr auto TypeName = "net.drinkingtea.ox.FileAddress.Data";
static constexpr auto Fields = 3;
char *path = nullptr; char *path = nullptr;
const char *constPath; const char *constPath;
uint64_t inode; uint64_t inode;

View File

@ -18,6 +18,12 @@
namespace ox { namespace ox {
namespace detail {
static inline void fsBuffFree(char *buff) noexcept {
delete buff;
}
}
class FileSystem { class FileSystem {
public: public:
@ -111,7 +117,7 @@ class FileSystemTemplate: public FileSystem {
public: public:
FileSystemTemplate() noexcept = default; 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; explicit FileSystemTemplate(FileStore fs) noexcept;

84
deps/ox/src/ox/fs/tool.cpp vendored Normal file
View File

@ -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 <cstdio>
#include <fstream>
#include <ox/fs/fs.hpp>
struct Buff {
char *data = nullptr;
std::size_t size = 0;
};
static ox::Result<Buff> 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<std::size_t>(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<ox::UniquePtr<ox::FileSystem>> loadFs(const char *path) noexcept {
oxRequire(buff, loadFsBuff(path));
return {ox::make_unique<ox::FileSystem32>(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<int>(err);
}