ResourcePack: dont scan for individual files

walking the zip prevents minizip from re-reading the same
data repeatedly from the actual backing filesystem.
also improves most usages of minizip to allow for >4GB,
files altho we probably don't need it
This commit is contained in:
Shawn Hoffman
2022-08-06 13:26:04 -07:00
parent 7b2b559743
commit 9bb8315441
2 changed files with 77 additions and 44 deletions

View File

@ -13,29 +13,36 @@
namespace Common
{
// Reads all of the current file. destination must be big enough to fit the whole file.
template <typename ContiguousContainer>
bool ReadFileFromZip(unzFile file, ContiguousContainer* destination)
inline bool ReadFileFromZip(unzFile file, u8* destination, u64 len)
{
const u32 MAX_BUFFER_SIZE = 65535;
const u64 MAX_BUFFER_SIZE = 65535;
if (unzOpenCurrentFile(file) != UNZ_OK)
return false;
Common::ScopeGuard guard{[&] { unzCloseCurrentFile(file); }};
u32 bytes_to_go = static_cast<u32>(destination->size());
u64 bytes_to_go = len;
while (bytes_to_go > 0)
{
const int bytes_read =
unzReadCurrentFile(file, &(*destination)[destination->size() - bytes_to_go],
std::min(bytes_to_go, MAX_BUFFER_SIZE));
if (bytes_read < 0)
// NOTE: multiples of 4G can't cause read_len == 0 && bytes_to_go > 0, as MAX_BUFFER_SIZE is
// small.
const u32 read_len = static_cast<u32>(std::min(bytes_to_go, MAX_BUFFER_SIZE));
const int rv = unzReadCurrentFile(file, destination, read_len);
if (rv < 0)
return false;
bytes_to_go -= static_cast<u32>(bytes_read);
const u32 bytes_read = static_cast<u32>(rv);
bytes_to_go -= bytes_read;
destination += bytes_read;
}
return true;
return unzEndOfFile(file) == 1;
}
template <typename ContiguousContainer>
bool ReadFileFromZip(unzFile file, ContiguousContainer* destination)
{
return ReadFileFromZip(file, reinterpret_cast<u8*>(destination->data()), destination->size());
}
} // namespace Common