2019-08-23 14:38:44 -06:00
|
|
|
// Copyright 2019 Dolphin Emulator Project
|
2021-07-04 19:22:19 -06:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2019-08-23 14:38:44 -06:00
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
|
2022-05-28 16:19:55 -06:00
|
|
|
#include <mz_compat.h>
|
2019-08-23 14:38:44 -06:00
|
|
|
|
|
|
|
#include "Common/CommonTypes.h"
|
|
|
|
#include "Common/ScopeGuard.h"
|
|
|
|
|
|
|
|
namespace Common
|
|
|
|
{
|
|
|
|
// Reads all of the current file. destination must be big enough to fit the whole file.
|
2022-08-06 14:26:04 -06:00
|
|
|
inline bool ReadFileFromZip(unzFile file, u8* destination, u64 len)
|
2019-08-23 14:38:44 -06:00
|
|
|
{
|
2022-08-06 14:26:04 -06:00
|
|
|
const u64 MAX_BUFFER_SIZE = 65535;
|
2019-08-23 14:38:44 -06:00
|
|
|
|
|
|
|
if (unzOpenCurrentFile(file) != UNZ_OK)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
Common::ScopeGuard guard{[&] { unzCloseCurrentFile(file); }};
|
|
|
|
|
2022-08-06 14:26:04 -06:00
|
|
|
u64 bytes_to_go = len;
|
2019-08-23 14:38:44 -06:00
|
|
|
while (bytes_to_go > 0)
|
|
|
|
{
|
2022-08-06 14:26:04 -06:00
|
|
|
// 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)
|
2019-08-23 14:38:44 -06:00
|
|
|
return false;
|
|
|
|
|
2022-08-06 14:26:04 -06:00
|
|
|
const u32 bytes_read = static_cast<u32>(rv);
|
|
|
|
bytes_to_go -= bytes_read;
|
|
|
|
destination += bytes_read;
|
2019-08-23 14:38:44 -06:00
|
|
|
}
|
|
|
|
|
2022-08-06 14:26:04 -06:00
|
|
|
return unzEndOfFile(file) == 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename ContiguousContainer>
|
|
|
|
bool ReadFileFromZip(unzFile file, ContiguousContainer* destination)
|
|
|
|
{
|
|
|
|
return ReadFileFromZip(file, reinterpret_cast<u8*>(destination->data()), destination->size());
|
2019-08-23 14:38:44 -06:00
|
|
|
}
|
|
|
|
} // namespace Common
|