[ox/fs] Wrap overloaded virtual functions in FileSystem

This commit is contained in:
Gary Talent 2023-01-27 00:00:35 -06:00
parent 94cb2e982a
commit 1cfa594c92
6 changed files with 225 additions and 167 deletions

View File

@ -324,7 +324,7 @@ Error FileStoreTemplate<size_t>::read(InodeId_t id, void *out, FsSize_t outSize,
auto srcData = m_buffer->template dataOf<uint8_t>(src); auto srcData = m_buffer->template dataOf<uint8_t>(src);
oxTracef("ox::fs::FileStoreTemplate::read::found", "{} found at {} with data section at {}", oxTracef("ox::fs::FileStoreTemplate::read::found", "{} found at {} with data section at {}",
id, src.offset(), srcData.offset()); id, src.offset(), srcData.offset());
oxTracef("ox::fs::FileStoreTemplate::read::outSize", "{} {} {}", srcData.offset(), srcData.size(), outSize); oxTracef("ox::fs::FileStoreTemplate::read::outSize", "{} {} {}", srcData.offset(), srcData.size(), outSize);
// error check // error check
@ -344,40 +344,67 @@ Error FileStoreTemplate<size_t>::read(InodeId_t id, void *out, FsSize_t outSize,
} }
template<typename size_t> template<typename size_t>
Error FileStoreTemplate<size_t>::read(InodeId_t id, FsSize_t readStart, FsSize_t readSize, void *data, FsSize_t *size) const { Error FileStoreTemplate<size_t>::read(InodeId_t id, FsSize_t readStart, FsSize_t readSize, void *out, FsSize_t *size) const {
oxRequireM(src, find(id).validate()); oxTracef("ox::fs::FileStoreTemplate::read", "Attempting to read from inode {}", id);
oxRequireM(srcData, src->data().validate()); auto src = find(id);
oxRequire(sub, srcData.template subPtr<uint8_t>(readStart, readSize).validate()); // error check
memcpy(data, sub, sub.size()); if (!src.valid()) {
if (size) { oxTracef("ox::fs::FileStoreTemplate::read::fail", "Could not find requested item: {}", id);
*size = sub.size(); return OxError(1);
} }
return OxError(0);
auto srcData = m_buffer->template dataOf<uint8_t>(src);
oxTracef("ox::fs::FileStoreTemplate::read::found", "{} found at {} with data section at {}",
id, src.offset(), srcData.offset());
oxTracef("ox::fs::FileStoreTemplate::read::readSize", "{} {} {}", srcData.offset(), srcData.size(), readSize);
// error check
if (!(srcData.valid() && srcData.size() - readStart <= readSize)) {
oxTracef("ox::fs::FileStoreTemplate::read::fail", "Could not read data section of item: {}", id);
oxTracef("ox::fs::FileStoreTemplate::read::fail",
"Item data section size: {}, Expected size: {}", srcData.size(), readSize);
return OxError(1);
}
ox_memcpy(out, srcData.get() + readStart, readSize);
if (size) {
*size = src.size();
}
return {};
} }
template<typename size_t> template<typename size_t>
template<typename T> template<typename T>
Error FileStoreTemplate<size_t>::read(InodeId_t id, FsSize_t readStart, Error FileStoreTemplate<size_t>::read(InodeId_t id, FsSize_t readStart,
FsSize_t readSize, T *data, FsSize_t *size) const { FsSize_t readSize, T *out, FsSize_t *size) const {
oxRequireM(src, find(id).validate()); oxTracef("ox::fs::FileStoreTemplate::read", "Attempting to read from inode {}", id);
oxRequireM(srcData, src->data().validate()); auto src = find(id);
auto sub = srcData.template subPtr<uint8_t>(readStart, readSize); // error check
if (sub.valid() && sub.size() % sizeof(T)) { if (!src.valid()) {
for (FsSize_t i = 0; i < sub.size() / sizeof(T); i++) { oxTracef("ox::fs::FileStoreTemplate::read::fail", "Could not find requested item: {}", id);
// do byte-by-byte copy to ensure alignment is right when return OxError(1);
// copying to final destination
T tmp;
for (size_t ii = 0; ii < sizeof(T); ii++) {
reinterpret_cast<uint8_t*>(&tmp)[ii] = *(sub.get() + ii);
}
*(data + i) = tmp;
}
if (size) {
*size = sub.size();
}
return OxError(0);
} }
return OxError(1);
auto srcData = m_buffer->template dataOf<uint8_t>(src);
oxTracef("ox::fs::FileStoreTemplate::read::found", "{} found at {} with data section at {}",
id, src.offset(), srcData.offset());
oxTracef("ox::fs::FileStoreTemplate::read::readSize", "{} {} {}", srcData.offset(), srcData.size(), readSize);
// error check
if (!(srcData.valid() && srcData.size() - readStart <= readSize)) {
oxTracef("ox::fs::FileStoreTemplate::read::fail", "Could not read data section of item: {}", id);
oxTracef("ox::fs::FileStoreTemplate::read::fail",
"Item data section size: {}, Expected size: {}", srcData.size(), readSize);
return OxError(1);
}
ox_memcpy(out, srcData.get() + readStart, readSize);
if (size) {
*size = src.size();
}
return {};
} }
template<typename size_t> template<typename size_t>

View File

@ -13,7 +13,7 @@
namespace ox { namespace ox {
Result<const char*> FileSystem::directAccess(const FileAddress &addr) noexcept { Result<const char*> MemFS::directAccess(const FileAddress &addr) noexcept {
switch (addr.type()) { switch (addr.type()) {
case FileAddressType::Inode: case FileAddressType::Inode:
return directAccess(addr.getInode().value); return directAccess(addr.getInode().value);
@ -28,10 +28,10 @@ Result<const char*> FileSystem::directAccess(const FileAddress &addr) noexcept {
Error FileSystem::read(const FileAddress &addr, void *buffer, std::size_t size) noexcept { Error FileSystem::read(const FileAddress &addr, void *buffer, std::size_t size) noexcept {
switch (addr.type()) { switch (addr.type()) {
case FileAddressType::Inode: case FileAddressType::Inode:
return read(addr.getInode().value, buffer, size); return readFileInode(addr.getInode().value, buffer, size);
case FileAddressType::ConstPath: case FileAddressType::ConstPath:
case FileAddressType::Path: case FileAddressType::Path:
return read(StringView(addr.getPath().value), buffer, size); return readFilePath(StringView(addr.getPath().value), buffer, size);
default: default:
return OxError(1); return OxError(1);
} }
@ -45,9 +45,9 @@ Result<Buffer> FileSystem::read(const FileAddress &addr) noexcept {
} }
Result<Buffer> FileSystem::read(CRStringView path) noexcept { Result<Buffer> FileSystem::read(CRStringView path) noexcept {
oxRequire(s, stat(path)); oxRequire(s, statPath(path));
Buffer buff(s.size); Buffer buff(s.size);
oxReturnError(read(path, buff.data(), buff.size())); oxReturnError(readFilePath(path, buff.data(), buff.size()));
return buff; return buff;
} }
@ -78,10 +78,10 @@ Error FileSystem::remove(const FileAddress &addr, bool recursive) noexcept {
Error FileSystem::write(const FileAddress &addr, const void *buffer, uint64_t size, FileType fileType) noexcept { Error FileSystem::write(const FileAddress &addr, const void *buffer, uint64_t size, FileType fileType) noexcept {
switch (addr.type()) { switch (addr.type()) {
case FileAddressType::Inode: case FileAddressType::Inode:
return write(addr.getInode().value, buffer, size, fileType); return writeFileInode(addr.getInode().value, buffer, size, fileType);
case FileAddressType::ConstPath: case FileAddressType::ConstPath:
case FileAddressType::Path: case FileAddressType::Path:
return write(StringView(addr.getPath().value), buffer, size, fileType); return writeFilePath(StringView(addr.getPath().value), buffer, size, fileType);
default: default:
return OxError(1); return OxError(1);
} }
@ -90,10 +90,10 @@ Error FileSystem::write(const FileAddress &addr, const void *buffer, uint64_t si
Result<FileStat> FileSystem::stat(const FileAddress &addr) const noexcept { Result<FileStat> FileSystem::stat(const FileAddress &addr) const noexcept {
switch (addr.type()) { switch (addr.type()) {
case FileAddressType::Inode: case FileAddressType::Inode:
return stat(addr.getInode().value); return statInode(addr.getInode().value);
case FileAddressType::ConstPath: case FileAddressType::ConstPath:
case FileAddressType::Path: case FileAddressType::Path:
return stat(StringView(addr.getPath().value)); return statPath(StringView(addr.getPath().value));
default: default:
return OxError(1); return OxError(1);
} }

View File

@ -38,26 +38,21 @@ class FileSystem {
*/ */
virtual Error move(CRStringView src, CRStringView dest) noexcept = 0; virtual Error move(CRStringView src, CRStringView dest) noexcept = 0;
virtual Error read(CRStringView path, void *buffer, std::size_t buffSize) noexcept = 0;
virtual Result<const char*> directAccess(CRStringView path) noexcept = 0;
virtual Error read(uint64_t inode, void *buffer, std::size_t size) noexcept = 0;
virtual Error read(uint64_t inode, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept = 0;
virtual Result<const char*> directAccess(uint64_t inode) noexcept = 0;
Error read(const FileAddress &addr, void *buffer, std::size_t size) noexcept; Error read(const FileAddress &addr, void *buffer, std::size_t size) noexcept;
Result<Buffer> read(const FileAddress &addr) noexcept; Result<Buffer> read(const FileAddress &addr) noexcept;
Result<Buffer> read(CRStringView path) noexcept; Result<Buffer> read(CRStringView path) noexcept;
Error read(const FileAddress &addr, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept; inline Error read(CRStringView path, void *buffer, std::size_t buffSize) noexcept {
return readFilePath(path, buffer, buffSize);
}
[[maybe_unused]] inline Error read(uint64_t inode, void *buffer, std::size_t buffSize) noexcept {
Result<const char*> directAccess(const FileAddress &addr) noexcept; return readFileInode(inode, buffer, buffSize);
}
Error read(const FileAddress &addr, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept;
virtual Result<Vector<String>> ls(CRStringView dir) const noexcept = 0; virtual Result<Vector<String>> ls(CRStringView dir) const noexcept = 0;
@ -67,12 +62,8 @@ class FileSystem {
virtual Error resize(uint64_t size, void *buffer) noexcept = 0; virtual Error resize(uint64_t size, void *buffer) noexcept = 0;
virtual Error write(CRStringView path, const void *buffer, uint64_t size, FileType fileType) noexcept = 0;
virtual Error write(uint64_t inode, const void *buffer, uint64_t size, FileType fileType) noexcept = 0;
Error write(CRStringView path, const void *buffer, uint64_t size) noexcept { Error write(CRStringView path, const void *buffer, uint64_t size) noexcept {
return write(path, buffer, size, FileType::NormalFile); return writeFilePath(path, buffer, size, FileType::NormalFile);
} }
Error write(uint64_t inode, const void *buffer, uint64_t size) noexcept { Error write(uint64_t inode, const void *buffer, uint64_t size) noexcept {
@ -81,9 +72,21 @@ class FileSystem {
Error write(const FileAddress &addr, const void *buffer, uint64_t size, FileType fileType = FileType::NormalFile) noexcept; Error write(const FileAddress &addr, const void *buffer, uint64_t size, FileType fileType = FileType::NormalFile) noexcept;
virtual Result<FileStat> stat(uint64_t inode) const noexcept = 0; inline Error write(CRStringView path, const void *buffer, uint64_t size, FileType fileType) noexcept {
return writeFilePath(path, buffer, size, fileType);
}
virtual Result<FileStat> stat(CRStringView path) const noexcept = 0; inline Error write(uint64_t inode, const void *buffer, uint64_t size, FileType fileType) noexcept {
return writeFileInode(inode, buffer, size, fileType);
}
inline Result<FileStat> stat(uint64_t inode) const noexcept {
return statInode(inode);
}
inline Result<FileStat> stat(CRStringView path) const noexcept {
return statPath(path);
}
Result<FileStat> stat(const FileAddress &addr) const noexcept; Result<FileStat> stat(const FileAddress &addr) const noexcept;
@ -104,6 +107,39 @@ class FileSystem {
[[nodiscard]] [[nodiscard]]
virtual bool valid() const noexcept = 0; virtual bool valid() const noexcept = 0;
protected:
virtual Result<FileStat> statInode(uint64_t inode) const noexcept = 0;
virtual Result<FileStat> statPath(CRStringView path) const noexcept = 0;
virtual Error readFilePath(CRStringView path, void *buffer, std::size_t buffSize) noexcept = 0;
virtual Error readFileInode(uint64_t inode, void *buffer, std::size_t size) noexcept = 0;
virtual Error readFileInodeRange(uint64_t inode, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept = 0;
virtual Error writeFilePath(CRStringView path, const void *buffer, uint64_t size, FileType fileType) noexcept = 0;
virtual Error writeFileInode(uint64_t inode, const void *buffer, uint64_t size, FileType fileType) noexcept = 0;
};
class MemFS: public FileSystem {
public:
Result<const char*> directAccess(const FileAddress &addr) noexcept;
inline Result<const char*> directAccess(CRStringView path) noexcept {
return directAccessPath(path);
}
inline Result<const char*> directAccess(uint64_t inode) noexcept {
return directAccessInode(inode);
}
protected:
virtual Result<const char*> directAccessPath(CRStringView path) noexcept = 0;
virtual Result<const char*> directAccessInode(uint64_t inode) noexcept = 0;
}; };
/** /**
@ -113,7 +149,7 @@ class FileSystem {
* Note: Directory parameter must have a default constructor. * Note: Directory parameter must have a default constructor.
*/ */
template<typename FileStore, typename Directory> template<typename FileStore, typename Directory>
class FileSystemTemplate: public FileSystem { class FileSystemTemplate: public MemFS {
private: private:
static constexpr auto InodeFsData = 2; static constexpr auto InodeFsData = 2;
@ -139,15 +175,15 @@ class FileSystemTemplate: public FileSystem {
Error move(CRStringView src, CRStringView dest) noexcept override; Error move(CRStringView src, CRStringView dest) noexcept override;
Error read(CRStringView path, void *buffer, std::size_t buffSize) noexcept override; Error readFilePath(CRStringView path, void *buffer, std::size_t buffSize) noexcept override;
Result<const char*> directAccess(CRStringView) noexcept override; Result<const char*> directAccessPath(CRStringView) noexcept override;
Error read(uint64_t inode, void *buffer, std::size_t size) noexcept override; Error readFileInode(uint64_t inode, void *buffer, std::size_t size) noexcept override;
Error read(uint64_t inode, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept override; Error readFileInodeRange(uint64_t inode, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept override;
Result<const char*> directAccess(uint64_t) noexcept override; Result<const char*> directAccessInode(uint64_t) noexcept override;
Result<Vector<String>> ls(CRStringView dir) const noexcept override; Result<Vector<String>> ls(CRStringView dir) const noexcept override;
@ -163,14 +199,15 @@ class FileSystemTemplate: public FileSystem {
Error resize(uint64_t size, void *buffer) noexcept override; Error resize(uint64_t size, void *buffer) noexcept override;
Error write(CRStringView path, const void *buffer, uint64_t size, FileType fileType) noexcept override; Error writeFilePath(CRStringView path, const void *buffer, uint64_t size, FileType fileType) noexcept override;
Error write(uint64_t inode, const void *buffer, uint64_t size, FileType fileType) noexcept override; Error writeFileInode(uint64_t inode, const void *buffer, uint64_t size, FileType fileType) noexcept override;
Result<FileStat> stat(uint64_t inode) const noexcept override; Result<FileStat> statInode(uint64_t inode) const noexcept override;
Result<FileStat> stat(CRStringView path) const noexcept override; Result<FileStat> statPath(CRStringView path) const noexcept override;
[[nodiscard]]
uint64_t spaceNeeded(uint64_t size) const noexcept override; uint64_t spaceNeeded(uint64_t size) const noexcept override;
Result<uint64_t> available() const noexcept override; Result<uint64_t> available() const noexcept override;
@ -254,33 +291,40 @@ Error FileSystemTemplate<FileStore, Directory>::move(CRStringView src, CRStringV
} }
template<typename FileStore, typename Directory> template<typename FileStore, typename Directory>
Error FileSystemTemplate<FileStore, Directory>::read(CRStringView path, void *buffer, std::size_t buffSize) noexcept { Error FileSystemTemplate<FileStore, Directory>::readFilePath(CRStringView path, void *buffer, std::size_t buffSize) noexcept {
oxRequire(fd, fileSystemData());
Directory rootDir(m_fs, fd.rootDirInode);
oxRequire(s, stat(path));
if (s.size > buffSize) {
return OxError(1, "Buffer to small to load file");
}
return readFileInodeRange(s.inode, 0, s.size, buffer, &buffSize);
}
template<typename FileStore, typename Directory>
Result<const char*> FileSystemTemplate<FileStore, Directory>::directAccessPath(CRStringView path) noexcept {
oxRequire(fd, fileSystemData()); oxRequire(fd, fileSystemData());
Directory rootDir(m_fs, fd.rootDirInode); Directory rootDir(m_fs, fd.rootDirInode);
oxRequire(inode, rootDir.find(path)); oxRequire(inode, rootDir.find(path));
return read(inode, buffer, buffSize); return directAccessInode(inode);
} }
template<typename FileStore, typename Directory> template<typename FileStore, typename Directory>
Result<const char*> FileSystemTemplate<FileStore, Directory>::directAccess(CRStringView path) noexcept { Error FileSystemTemplate<FileStore, Directory>::readFileInode(uint64_t inode, void *buffer, std::size_t buffSize) noexcept {
oxRequire(fd, fileSystemData()); oxRequire(s, stat(inode));
Directory rootDir(m_fs, fd.rootDirInode); if (s.size > buffSize) {
oxRequire(inode, rootDir.find(path)); return OxError(1, "Buffer to small to load file");
return directAccess(inode); }
return readFileInodeRange(inode, 0, s.size, buffer, &buffSize);
} }
template<typename FileStore, typename Directory> template<typename FileStore, typename Directory>
Error FileSystemTemplate<FileStore, Directory>::read(uint64_t inode, void *buffer, std::size_t buffSize) noexcept { Error FileSystemTemplate<FileStore, Directory>::readFileInodeRange(uint64_t inode, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept {
return m_fs.read(inode, buffer, buffSize);
}
template<typename FileStore, typename Directory>
Error FileSystemTemplate<FileStore, Directory>::read(uint64_t inode, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept {
return m_fs.read(inode, readStart, readSize, reinterpret_cast<uint8_t*>(buffer), size); return m_fs.read(inode, readStart, readSize, reinterpret_cast<uint8_t*>(buffer), size);
} }
template<typename FileStore, typename Directory> template<typename FileStore, typename Directory>
Result<const char*> FileSystemTemplate<FileStore, Directory>::directAccess(uint64_t inode) noexcept { Result<const char*> FileSystemTemplate<FileStore, Directory>::directAccessInode(uint64_t inode) noexcept {
auto data = m_fs.read(inode); auto data = m_fs.read(inode);
if (!data.valid()) { if (!data.valid()) {
return OxError(1, "Data not valid"); return OxError(1, "Data not valid");
@ -312,7 +356,7 @@ Error FileSystemTemplate<FileStore, Directory>::remove(CRStringView path, bool r
oxRequire(fd, fileSystemData()); oxRequire(fd, fileSystemData());
Directory rootDir(m_fs, fd.rootDirInode); Directory rootDir(m_fs, fd.rootDirInode);
oxRequire(inode, rootDir.find(path)); oxRequire(inode, rootDir.find(path));
oxRequire(st, stat(inode)); oxRequire(st, statInode(inode));
if (st.fileType == FileType::NormalFile || recursive) { if (st.fileType == FileType::NormalFile || recursive) {
if (auto err = rootDir.remove(path)) { if (auto err = rootDir.remove(path)) {
// removal failed, try putting the index back // removal failed, try putting the index back
@ -338,7 +382,7 @@ Error FileSystemTemplate<FileStore, Directory>::resize(uint64_t size, void *buff
} }
template<typename FileStore, typename Directory> template<typename FileStore, typename Directory>
Error FileSystemTemplate<FileStore, Directory>::write(CRStringView path, const void *buffer, uint64_t size, FileType fileType) noexcept { Error FileSystemTemplate<FileStore, Directory>::writeFilePath(CRStringView path, const void *buffer, uint64_t size, FileType fileType) noexcept {
auto [inode, err] = find(path); auto [inode, err] = find(path);
if (err) { if (err) {
oxRequire(generatedId, m_fs.generateInodeId()); oxRequire(generatedId, m_fs.generateInodeId());
@ -346,17 +390,17 @@ Error FileSystemTemplate<FileStore, Directory>::write(CRStringView path, const v
oxRequireM(rootDir, this->rootDir()); oxRequireM(rootDir, this->rootDir());
oxReturnError(rootDir.write(path, inode)); oxReturnError(rootDir.write(path, inode));
} }
oxReturnError(write(inode, buffer, size, fileType)); oxReturnError(writeFileInode(inode, buffer, size, fileType));
return OxError(0); return OxError(0);
} }
template<typename FileStore, typename Directory> template<typename FileStore, typename Directory>
Error FileSystemTemplate<FileStore, Directory>::write(uint64_t inode, const void *buffer, uint64_t size, FileType fileType) noexcept { Error FileSystemTemplate<FileStore, Directory>::writeFileInode(uint64_t inode, const void *buffer, uint64_t size, FileType fileType) noexcept {
return m_fs.write(inode, buffer, size, static_cast<uint8_t>(fileType)); return m_fs.write(inode, buffer, size, static_cast<uint8_t>(fileType));
} }
template<typename FileStore, typename Directory> template<typename FileStore, typename Directory>
Result<FileStat> FileSystemTemplate<FileStore, Directory>::stat(uint64_t inode) const noexcept { Result<FileStat> FileSystemTemplate<FileStore, Directory>::statInode(uint64_t inode) const noexcept {
oxRequire(s, m_fs.stat(inode)); oxRequire(s, m_fs.stat(inode));
FileStat out; FileStat out;
out.inode = s.inode; out.inode = s.inode;
@ -367,7 +411,7 @@ Result<FileStat> FileSystemTemplate<FileStore, Directory>::stat(uint64_t inode)
} }
template<typename FileStore, typename Directory> template<typename FileStore, typename Directory>
Result<FileStat> FileSystemTemplate<FileStore, Directory>::stat(CRStringView path) const noexcept { Result<FileStat> FileSystemTemplate<FileStore, Directory>::statPath(CRStringView path) const noexcept {
oxRequire(inode, find(path)); oxRequire(inode, find(path));
return stat(inode); return stat(inode);
} }

View File

@ -63,41 +63,6 @@ Error PassThroughFS::move(CRStringView src, CRStringView dest) noexcept {
return OxError(0); return OxError(0);
} }
Error PassThroughFS::read(CRStringView path, void *buffer, std::size_t buffSize) noexcept {
try {
std::ifstream file((m_path / stripSlash(path)), std::ios::binary | std::ios::ate);
const std::size_t size = file.tellg();
file.seekg(0, std::ios::beg);
if (size > buffSize) {
oxTracef("ox::fs::PassThroughFS::read::error", "Read failed: Buffer too small: {}", path);
return OxError(1);
}
file.read(static_cast<char*>(buffer), static_cast<std::streamsize>(buffSize));
} catch (const std::fstream::failure &f) {
oxTracef("ox::fs::PassThroughFS::read::error", "Read of {} failed: {}", path, f.what());
return OxError(2);
}
return OxError(0);
}
Result<const char*> PassThroughFS::directAccess(CRStringView) noexcept {
return OxError(1, "PassThroughFS::directAccess not supported");
}
Error PassThroughFS::read(uint64_t, void*, std::size_t) noexcept {
// unsupported
return OxError(1, "read(uint64_t, void*, std::size_t) is not supported by PassThroughFS");
}
Error PassThroughFS::read(uint64_t, std::size_t, std::size_t, void*, std::size_t*) noexcept {
// unsupported
return OxError(1, "read(uint64_t, std::size_t, std::size_t, void*, std::size_t*) is not supported by PassThroughFS");
}
Result<const char*> PassThroughFS::directAccess(uint64_t) noexcept {
return OxError(1, "PassThroughFS::directAccess not supported");
}
Result<Vector<String>> PassThroughFS::ls(CRStringView dir) const noexcept { Result<Vector<String>> PassThroughFS::ls(CRStringView dir) const noexcept {
Vector<String> out; Vector<String> out;
std::error_code ec; std::error_code ec;
@ -123,37 +88,20 @@ Error PassThroughFS::resize(uint64_t, void*) noexcept {
return OxError(1, "resize is not supported by PassThroughFS"); return OxError(1, "resize is not supported by PassThroughFS");
} }
Error PassThroughFS::write(CRStringView path, const void *buffer, uint64_t size, FileType) noexcept { Result<FileStat> PassThroughFS::statInode(uint64_t) const noexcept {
const auto p = (m_path / stripSlash(path));
try {
std::ofstream f(p, std::ios::binary);
f.write(static_cast<const char*>(buffer), size);
} catch (const std::fstream::failure &f) {
oxTracef("ox::fs::PassThroughFS::read::error", "Write of {} failed: {}", path, f.what());
return OxError(1);
}
return OxError(0);
}
Error PassThroughFS::write(uint64_t, const void*, uint64_t, FileType) noexcept {
// unsupported // unsupported
return OxError(1, "write(uint64_t, void*, uint64_t, uint8_t) is not supported by PassThroughFS"); return OxError(1, "statInode(uint64_t) is not supported by PassThroughFS");
} }
Result<FileStat> PassThroughFS::stat(uint64_t) const noexcept { Result<FileStat> PassThroughFS::statPath(CRStringView path) const noexcept {
// unsupported
return OxError(1, "stat(uint64_t) is not supported by PassThroughFS");
}
Result<FileStat> PassThroughFS::stat(CRStringView path) const noexcept {
std::error_code ec; std::error_code ec;
const auto p = m_path / stripSlash(path); const auto p = m_path / stripSlash(path);
const FileType type = std::filesystem::is_directory(p, ec) ? const FileType type = std::filesystem::is_directory(p, ec) ?
FileType::Directory : FileType::NormalFile; FileType::Directory : FileType::NormalFile;
oxTracef("ox::fs::PassThroughFS::stat", "{} {}", ec.message(), path); oxTracef("ox::fs::PassThroughFS::statInode", "{} {}", ec.message(), path);
const uint64_t size = type == FileType::Directory ? 0 : std::filesystem::file_size(p, ec); const uint64_t size = type == FileType::Directory ? 0 : std::filesystem::file_size(p, ec);
oxTracef("ox::fs::PassThroughFS::stat", "{} {}", ec.message(), path); oxTracef("ox::fs::PassThroughFS::statInode", "{} {}", ec.message(), path);
oxTracef("ox::fs::PassThroughFS::stat::size", "{} {}", path, size); oxTracef("ox::fs::PassThroughFS::statInode::size", "{} {}", path, size);
oxReturnError(OxError(ec.value())); oxReturnError(OxError(ec.value()));
return FileStat{0, 0, size, type}; return FileStat{0, 0, size, type};
} }
@ -193,12 +141,56 @@ bool PassThroughFS::valid() const noexcept {
return false; return false;
} }
Error PassThroughFS::readFilePath(CRStringView path, void *buffer, std::size_t buffSize) noexcept {
try {
std::ifstream file((m_path / stripSlash(path)), std::ios::binary | std::ios::ate);
const std::size_t size = file.tellg();
file.seekg(0, std::ios::beg);
if (size > buffSize) {
oxTracef("ox::fs::PassThroughFS::read::error", "Read failed: Buffer too small: {}", path);
return OxError(1);
}
file.read(static_cast<char*>(buffer), static_cast<std::streamsize>(buffSize));
} catch (const std::fstream::failure &f) {
oxTracef("ox::fs::PassThroughFS::read::error", "Read of {} failed: {}", path, f.what());
return OxError(2);
}
return OxError(0);
}
Error PassThroughFS::readFileInode(uint64_t, void*, std::size_t) noexcept {
// unsupported
return OxError(1, "readFileInode(uint64_t, void*, std::size_t) is not supported by PassThroughFS");
}
Error PassThroughFS::readFileInodeRange(uint64_t, std::size_t, std::size_t, void*, std::size_t*) noexcept {
// unsupported
return OxError(1, "read(uint64_t, std::size_t, std::size_t, void*, std::size_t*) is not supported by PassThroughFS");
}
Error PassThroughFS::writeFilePath(CRStringView path, const void *buffer, uint64_t size, FileType) noexcept {
const auto p = (m_path / stripSlash(path));
try {
std::ofstream f(p, std::ios::binary);
f.write(static_cast<const char*>(buffer), static_cast<std::streamsize>(size));
} catch (const std::fstream::failure &f) {
oxTracef("ox::fs::PassThroughFS::read::error", "Write of {} failed: {}", path, f.what());
return OxError(1);
}
return OxError(0);
}
Error PassThroughFS::writeFileInode(uint64_t, const void*, uint64_t, FileType) noexcept {
// unsupported
return OxError(1, "writeFileInode(uint64_t, void*, uint64_t, uint8_t) is not supported by PassThroughFS");
}
std::string_view PassThroughFS::stripSlash(StringView path) noexcept { std::string_view PassThroughFS::stripSlash(StringView path) noexcept {
const auto pathLen = ox_strlen(path); const auto pathLen = ox_strlen(path);
for (auto i = 0u; i < pathLen && path[0] == '/'; i++) { for (auto i = 0u; i < pathLen && path[0] == '/'; i++) {
path = path.substr(1); path = path.substr(1);
} }
return std::string_view(path.data(), path.bytes()); return {path.data(), path.bytes()};
} }
} }

View File

@ -11,7 +11,6 @@
#if __has_include(<filesystem>) && defined(OX_USE_STDLIB) #if __has_include(<filesystem>) && defined(OX_USE_STDLIB)
#include <filesystem> #include <filesystem>
#include <string>
#include <ox/std/bit.hpp> #include <ox/std/bit.hpp>
#include "filesystem.hpp" #include "filesystem.hpp"
@ -37,36 +36,22 @@ class PassThroughFS: public FileSystem {
[[nodiscard]] [[nodiscard]]
String basePath() const noexcept; String basePath() const noexcept;
Error mkdir(CRStringView path, bool recursive = false) noexcept override; Error mkdir(CRStringView path, bool recursive) noexcept override;
Error move(CRStringView src, CRStringView dest) noexcept override; Error move(CRStringView src, CRStringView dest) noexcept override;
Error read(CRStringView path, void *buffer, std::size_t buffSize) noexcept override;
Result<const char*> directAccess(CRStringView) noexcept override;
Error read(uint64_t inode, void *buffer, std::size_t size) noexcept override;
Error read(uint64_t inode, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept override;
Result<const char*> directAccess(uint64_t) noexcept override;
Result<Vector<String>> ls(CRStringView dir) const noexcept override; Result<Vector<String>> ls(CRStringView dir) const noexcept override;
template<typename F> template<typename F>
Error ls(CRStringView dir, F cb) const noexcept; Error ls(CRStringView dir, F cb) const noexcept;
Error remove(CRStringView path, bool recursive = false) noexcept override; Error remove(CRStringView path, bool recursive) noexcept override;
Error resize(uint64_t size, void *buffer = nullptr) noexcept override; Error resize(uint64_t size, void *buffer) noexcept override;
Error write(CRStringView path, const void *buffer, uint64_t size, FileType fileType = FileType::NormalFile) noexcept override; Result<FileStat> statInode(uint64_t inode) const noexcept override;
Error write(uint64_t inode, const void *buffer, uint64_t size, FileType fileType = FileType::NormalFile) noexcept override; Result<FileStat> statPath(CRStringView path) const noexcept override;
Result<FileStat> stat(uint64_t inode) const noexcept override;
Result<FileStat> stat(CRStringView path) const noexcept override;
[[nodiscard]] [[nodiscard]]
uint64_t spaceNeeded(uint64_t size) const noexcept override; uint64_t spaceNeeded(uint64_t size) const noexcept override;
@ -83,6 +68,17 @@ class PassThroughFS: public FileSystem {
[[nodiscard]] [[nodiscard]]
bool valid() const noexcept override; bool valid() const noexcept override;
protected:
Error readFilePath(CRStringView path, void *buffer, std::size_t buffSize) noexcept override;
Error readFileInode(uint64_t inode, void *buffer, std::size_t size) noexcept override;
Error readFileInodeRange(uint64_t inode, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept override;
Error writeFilePath(CRStringView path, const void *buffer, uint64_t size, FileType fileType) noexcept override;
Error writeFileInode(uint64_t inode, const void *buffer, uint64_t size, FileType fileType) noexcept override;
private: private:
/** /**
* Strips the leading slashes from a string. * Strips the leading slashes from a string.

View File

@ -223,7 +223,6 @@ template<typename SubT>
constexpr Ptr<SubT, size_t, sizeof(T)> Ptr<T, size_t, minOffset>::subPtr(size_t offset) noexcept { constexpr Ptr<SubT, size_t, sizeof(T)> Ptr<T, size_t, minOffset>::subPtr(size_t offset) noexcept {
oxTracef("ox::fs::Ptr::subPtr", "{} {} {} {} {}", m_itemOffset, this->size(), offset, m_itemSize, (m_itemSize - offset)); oxTracef("ox::fs::Ptr::subPtr", "{} {} {} {} {}", m_itemOffset, this->size(), offset, m_itemSize, (m_itemSize - offset));
return subPtr<SubT>(offset, m_itemSize - offset); return subPtr<SubT>(offset, m_itemSize - offset);
return subPtr<SubT>(offset, m_itemSize - offset);
} }
template<typename T, typename size_t, size_t minOffset> template<typename T, typename size_t, size_t minOffset>