mirror of
https://github.com/RPCSX/rpcsx.git
synced 2025-12-06 07:12:14 +01:00
FIle: add write_at
This commit is contained in:
parent
f78e4e5061
commit
d7c39cc719
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue