diff --git a/deps/ox/src/ox/fs/filesystem/filesystem.cpp b/deps/ox/src/ox/fs/filesystem/filesystem.cpp index 105e2b93..07e2c390 100644 --- a/deps/ox/src/ox/fs/filesystem/filesystem.cpp +++ b/deps/ox/src/ox/fs/filesystem/filesystem.cpp @@ -37,6 +37,30 @@ Error FileSystem::read(const FileAddress &addr, void *buffer, std::size_t size) } } +Result FileSystem::read(FileAddress const &addr, size_t const size) noexcept { + Result out; + out.value.resize(size); + switch (addr.type()) { + case FileAddressType::Inode: + OX_RETURN_ERROR(readFileInode(addr.getInode().value, out.value.data(), size)); + break; + case FileAddressType::ConstPath: + case FileAddressType::Path: + OX_RETURN_ERROR(readFilePath(StringView{addr.getPath().value}, out.value.data(), size)); + break; + default: + return ox::Error{1}; + } + return out; +} + +Result FileSystem::read(StringViewCR path, size_t const size) noexcept { + Result out; + out.value.resize(size); + OX_RETURN_ERROR(readFilePath(path, out.value.data(), size)); + return out; +} + Result FileSystem::read(const FileAddress &addr) noexcept { OX_REQUIRE(s, stat(addr)); Buffer buff(static_cast(s.size)); @@ -51,18 +75,33 @@ Result FileSystem::read(StringViewCR path) noexcept { return buff; } -Error FileSystem::read(const FileAddress &addr, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept { +Error FileSystem::read( + FileAddress const &addr, + std::size_t const readStart, + std::size_t const readSize, + void *buffer, + std::size_t *size) noexcept { switch (addr.type()) { case FileAddressType::Inode: - return read(addr.getInode().value, readStart, readSize, buffer, size); + return readFileInodeRange(addr.getInode().value, readStart, readSize, buffer, size); case FileAddressType::ConstPath: case FileAddressType::Path: - return ox::Error(2, "Unsupported for path lookups"); + return readFilePathRange(addr.getPath().value, readStart, readSize, buffer, size); default: return ox::Error(1); } } +Result FileSystem::read( + StringViewCR path, + std::size_t const readStart, + std::size_t const readSize, + Span buff) noexcept { + size_t szOut{buff.size()}; + OX_RETURN_ERROR(readFilePathRange(path, readStart, readSize, buff.data(), &szOut)); + return szOut; +} + Error FileSystem::write(const FileAddress &addr, const void *buffer, uint64_t size, FileType fileType) noexcept { switch (addr.type()) { case FileAddressType::Inode: diff --git a/deps/ox/src/ox/fs/filesystem/filesystem.hpp b/deps/ox/src/ox/fs/filesystem/filesystem.hpp index ebc83217..fc7459e9 100644 --- a/deps/ox/src/ox/fs/filesystem/filesystem.hpp +++ b/deps/ox/src/ox/fs/filesystem/filesystem.hpp @@ -41,6 +41,10 @@ class FileSystem { Error read(const FileAddress &addr, void *buffer, std::size_t size) noexcept; + Result read(FileAddress const &addr, size_t size) noexcept; + + Result read(StringViewCR path, size_t size) noexcept; + Result read(const FileAddress &addr) noexcept; Result read(StringViewCR path) noexcept; @@ -53,7 +57,24 @@ class FileSystem { 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; + Error read( + FileAddress const &addr, + size_t readStart, + size_t readSize, + void *buffer, + size_t *size) noexcept; + + /** + * + * @param path + * @param readStart + * @param readSize + * @param buffer + * @param size + * @return error or number of bytes read + */ + Result read( + StringViewCR path, size_t readStart, size_t readSize, ox::Span buff) noexcept; virtual Result> ls(StringViewCR dir) const noexcept = 0; @@ -140,7 +161,10 @@ class FileSystem { 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 readFilePathRange( + StringViewCR path, size_t readStart, size_t readSize, void *buffer, size_t *buffSize) noexcept = 0; + + virtual Error readFileInodeRange(uint64_t inode, size_t readStart, size_t readSize, void *buffer, size_t *size) noexcept = 0; virtual Error removePath(StringViewCR path, bool recursive) noexcept = 0; @@ -211,6 +235,9 @@ class FileSystemTemplate: public MemFS { Error readFileInodeRange(uint64_t inode, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept override; + Error readFilePathRange( + StringViewCR path, size_t readStart, size_t readSize, void *buffer, size_t *buffSize) noexcept override; + Error removePath(StringViewCR path, bool recursive) noexcept override; Result directAccessInode(uint64_t) const noexcept override; @@ -358,6 +385,13 @@ Error FileSystemTemplate::readFileInodeRange(uint64_t inod return m_fs.read(inode, readStart, readSize, reinterpret_cast(buffer), size); } +template +Error FileSystemTemplate::readFilePathRange( + StringViewCR path, size_t readStart, size_t readSize, void *buffer, size_t *buffSize) noexcept { + OX_REQUIRE(s, stat(path)); + return readFileInodeRange(s.inode, readStart, readSize, buffer, buffSize); +} + template Error FileSystemTemplate::removePath(StringViewCR path, bool recursive) noexcept { OX_REQUIRE(fd, fileSystemData()); diff --git a/deps/ox/src/ox/fs/filesystem/passthroughfs.cpp b/deps/ox/src/ox/fs/filesystem/passthroughfs.cpp index 365d5bb7..fbf960bd 100644 --- a/deps/ox/src/ox/fs/filesystem/passthroughfs.cpp +++ b/deps/ox/src/ox/fs/filesystem/passthroughfs.cpp @@ -154,6 +154,25 @@ Error PassThroughFS::readFileInode(uint64_t, void*, std::size_t) noexcept { return ox::Error(1, "readFileInode(uint64_t, void*, std::size_t) is not supported by PassThroughFS"); } +Error PassThroughFS::readFilePathRange( + StringViewCR path, size_t const readStart, size_t readSize, void *buffer, size_t *buffSize) noexcept { + try { + std::ifstream file(m_path / stripSlash(path), std::ios::binary | std::ios::ate); + auto const size = static_cast(file.tellg()); + readSize = ox::min(readSize, size); + file.seekg(static_cast(readStart), std::ios::beg); + if (readSize > *buffSize) { + oxTracef("ox.fs.PassThroughFS.read.error", "Read failed: Buffer too small: {}", path); + return ox::Error{1}; + } + file.read(static_cast(buffer), static_cast(readSize)); + return {}; + } catch (std::fstream::failure const &f) { + oxTracef("ox.fs.PassThroughFS.read.error", "Read of {} failed: {}", path, f.what()); + return ox::Error{2}; + } +} + Error PassThroughFS::readFileInodeRange(uint64_t, std::size_t, std::size_t, void*, std::size_t*) noexcept { // unsupported return ox::Error(1, "read(uint64_t, std::size_t, std::size_t, void*, std::size_t*) is not supported by PassThroughFS"); diff --git a/deps/ox/src/ox/fs/filesystem/passthroughfs.hpp b/deps/ox/src/ox/fs/filesystem/passthroughfs.hpp index a424cefe..4d9f255a 100644 --- a/deps/ox/src/ox/fs/filesystem/passthroughfs.hpp +++ b/deps/ox/src/ox/fs/filesystem/passthroughfs.hpp @@ -71,6 +71,9 @@ class PassThroughFS: public FileSystem { Error readFileInode(uint64_t inode, void *buffer, std::size_t size) noexcept override; + Error readFilePathRange( + StringViewCR path, size_t readStart, size_t readSize, void *buffer, size_t *buffSize) noexcept override; + Error readFileInodeRange(uint64_t inode, std::size_t readStart, std::size_t readSize, void *buffer, std::size_t *size) noexcept override; Error removePath(StringViewCR path, bool recursive) noexcept override;