FIle: add write_at

This commit is contained in:
DH 2025-03-14 14:54:18 +03:00
parent f78e4e5061
commit d7c39cc719
2 changed files with 80 additions and 0 deletions

View file

@ -539,6 +539,34 @@ namespace fs
return nwritten_sum;
}
u64 write_at(u64 offset, const void* buffer, u64 count) override
{
u64 nwritten_sum = 0;
for (const char* data = static_cast<const char*>(buffer); count;)
{
const DWORD size = static_cast<DWORD>(std::min<u64>(count, DWORD{umax} & -4096));
DWORD nwritten = 0;
OVERLAPPED ovl{};
ovl.Offset = DWORD(offset);
ovl.OffsetHigh = DWORD(offset >> 32);
ensure(WriteFile(m_handle, data, size, &nwritten, &ovl)); // "file::write"
ensure(nwritten == size);
nwritten_sum += nwritten;
if (nwritten < size)
{
break;
}
count -= size;
data += size;
}
return nwritten_sum;
}
u64 seek(s64 offset, seek_mode whence) override
{
if (whence > seek_end)
@ -710,6 +738,25 @@ namespace fs
return result;
}
u64 write_at(u64 offset, const void* buffer, u64 count) override
{
u64 result = 0;
// For safety; see read()
while (auto r = ::pwrite(m_fd, buffer, count, offset))
{
ensure(r > 0); // "file::write"
count -= r;
offset += r;
result += r;
buffer = static_cast<const u8*>(buffer) + r;
if (!count)
break;
}
return result;
}
u64 seek(s64 offset, seek_mode whence) override
{
if (whence > seek_end)

View file

@ -109,6 +109,10 @@ namespace fs
virtual u64 read(void* buffer, u64 size) = 0;
virtual u64 read_at(u64 offset, void* buffer, u64 size) = 0;
virtual u64 write(const void* buffer, u64 size) = 0;
virtual u64 write_at([[maybe_unused]] u64 offset, [[maybe_unused]] const void* buffer, [[maybe_unused]] u64 size)
{
return 0;
}
virtual u64 seek(s64 offset, seek_mode whence) = 0;
virtual u64 size() = 0;
virtual native_handle get_handle();
@ -343,6 +347,12 @@ namespace fs
return m_file->write(buffer, count);
}
u64 write_at(u64 offset, const void* buffer, u64 count, std::source_location src_loc = std::source_location::current()) const
{
if (!m_file) xnull(src_loc);
return m_file->write_at(offset, buffer, count);
}
// Change current position, returns resulting position
u64 seek(s64 offset, seek_mode whence = seek_set, std::source_location src_loc = std::source_location::current()) const
{
@ -611,6 +621,29 @@ namespace fs
}
};
class virtual_dir final : public fs::dir_base
{
std::vector<fs::dir_entry> m_entries;
std::size_t m_offset = 0;
public:
virtual_dir(std::vector<fs::dir_entry> entries)
: m_entries(std::move(entries)) {}
bool read(fs::dir_entry &entry) override
{
if (m_offset < m_entries.size())
{
entry = m_entries[m_offset++];
return true;
}
return false;
}
void rewind() override { m_offset = 0; }
};
// Get executable path
std::string get_executable_path();