diff options
-rw-r--r-- | src/core/file_sys/vfs.cpp | 36 | ||||
-rw-r--r-- | src/core/file_sys/vfs.h | 6 |
2 files changed, 36 insertions, 6 deletions
diff --git a/src/core/file_sys/vfs.cpp b/src/core/file_sys/vfs.cpp index 1ddfb7600..218cfde66 100644 --- a/src/core/file_sys/vfs.cpp +++ b/src/core/file_sys/vfs.cpp @@ -463,13 +463,41 @@ bool DeepEquals(const VirtualFile& file1, const VirtualFile& file2, std::size_t return true; } -bool VfsRawCopy(VirtualFile src, VirtualFile dest) { - if (src == nullptr || dest == nullptr) +bool VfsRawCopy(const VirtualFile& src, const VirtualFile& dest, size_t block_size) { + if (src == nullptr || dest == nullptr || !src->IsReadable() || !dest->IsWritable()) return false; if (!dest->Resize(src->GetSize())) return false; - std::vector<u8> data = src->ReadAllBytes(); - return dest->WriteBytes(data, 0) == data.size(); + + std::vector<u8> temp(std::min(block_size, src->GetSize())); + for (size_t i = 0; i < src->GetSize(); i += block_size) { + const auto read = std::min(block_size, src->GetSize() - i); + const auto block = src->Read(temp.data(), read, i); + + if (dest->Write(temp.data(), read, i) != read) + return false; + } + + return true; +} + +bool VfsRawCopyD(const VirtualDir& src, const VirtualDir& dest, size_t block_size) { + if (src == nullptr || dest == nullptr || !src->IsReadable() || !dest->IsWritable()) + return false; + + for (const auto& file : src->GetFiles()) { + const auto out = dest->CreateFile(file->GetName()); + if (!VfsRawCopy(file, out, block_size)) + return false; + } + + for (const auto& dir : src->GetSubdirectories()) { + const auto out = dest->CreateSubdirectory(dir->GetName()); + if (!VfsRawCopyD(dir, out, block_size)) + return false; + } + + return true; } VirtualDir GetOrCreateDirectoryRelative(const VirtualDir& rel, std::string_view path) { diff --git a/src/core/file_sys/vfs.h b/src/core/file_sys/vfs.h index 828e87f38..6aec4c164 100644 --- a/src/core/file_sys/vfs.h +++ b/src/core/file_sys/vfs.h @@ -316,12 +316,14 @@ public: }; // Compare the two files, byte-for-byte, in increments specificed by block_size -bool DeepEquals(const VirtualFile& file1, const VirtualFile& file2, std::size_t block_size = 0x200); +bool DeepEquals(const VirtualFile& file1, const VirtualFile& file2, size_t block_size = 0x1000); // A method that copies the raw data between two different implementations of VirtualFile. If you // are using the same implementation, it is probably better to use the Copy method in the parent // directory of src/dest. -bool VfsRawCopy(VirtualFile src, VirtualFile dest); +bool VfsRawCopy(const VirtualFile& src, const VirtualFile& dest, size_t block_size = 0x1000); + +bool VfsRawCopyD(const VirtualDir& src, const VirtualDir& dest, size_t block_size = 0x1000); // Checks if the directory at path relative to rel exists. If it does, returns that. If it does not // it attempts to create it and returns the new dir or nullptr on failure. |