[ox/fs] Add new partial file read functions

This commit is contained in:
Gary Talent 2025-02-03 20:28:25 -06:00
parent 671dd86206
commit d45ff05bcd
4 changed files with 100 additions and 5 deletions

View File

@ -37,6 +37,30 @@ Error FileSystem::read(const FileAddress &addr, void *buffer, std::size_t size)
}
}
Result<Buffer> FileSystem::read(FileAddress const &addr, size_t const size) noexcept {
Result<Buffer> 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<Buffer> FileSystem::read(StringViewCR path, size_t const size) noexcept {
Result<Buffer> out;
out.value.resize(size);
OX_RETURN_ERROR(readFilePath(path, out.value.data(), size));
return out;
}
Result<Buffer> FileSystem::read(const FileAddress &addr) noexcept {
OX_REQUIRE(s, stat(addr));
Buffer buff(static_cast<std::size_t>(s.size));
@ -51,18 +75,33 @@ Result<Buffer> 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<size_t> FileSystem::read(
StringViewCR path,
std::size_t const readStart,
std::size_t const readSize,
Span<char> 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:

View File

@ -41,6 +41,10 @@ class FileSystem {
Error read(const FileAddress &addr, void *buffer, std::size_t size) noexcept;
Result<Buffer> read(FileAddress const &addr, size_t size) noexcept;
Result<Buffer> read(StringViewCR path, size_t size) noexcept;
Result<Buffer> read(const FileAddress &addr) noexcept;
Result<Buffer> 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<size_t> read(
StringViewCR path, size_t readStart, size_t readSize, ox::Span<char> buff) noexcept;
virtual Result<Vector<String>> 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<const char*> directAccessInode(uint64_t) const noexcept override;
@ -358,6 +385,13 @@ Error FileSystemTemplate<FileStore, Directory>::readFileInodeRange(uint64_t inod
return m_fs.read(inode, readStart, readSize, reinterpret_cast<uint8_t*>(buffer), size);
}
template<typename FileStore, typename Directory>
Error FileSystemTemplate<FileStore, Directory>::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<typename FileStore, typename Directory>
Error FileSystemTemplate<FileStore, Directory>::removePath(StringViewCR path, bool recursive) noexcept {
OX_REQUIRE(fd, fileSystemData());

View File

@ -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<size_t>(file.tellg());
readSize = ox::min(readSize, size);
file.seekg(static_cast<off_t>(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<char*>(buffer), static_cast<std::streamsize>(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");

View File

@ -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;