MinizipUtil.h 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. // Copyright 2019 Dolphin Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <algorithm>
  5. #include <unzip.h>
  6. #include "Common/CommonTypes.h"
  7. #include "Common/ScopeGuard.h"
  8. namespace Common
  9. {
  10. // Reads all of the current file. destination must be big enough to fit the whole file.
  11. inline bool ReadFileFromZip(unzFile file, u8* destination, u64 len)
  12. {
  13. const u64 MAX_BUFFER_SIZE = 65535;
  14. if (unzOpenCurrentFile(file) != UNZ_OK)
  15. return false;
  16. Common::ScopeGuard guard{[&] { unzCloseCurrentFile(file); }};
  17. u64 bytes_to_go = len;
  18. while (bytes_to_go > 0)
  19. {
  20. // NOTE: multiples of 4G can't cause read_len == 0 && bytes_to_go > 0, as MAX_BUFFER_SIZE is
  21. // small.
  22. const u32 read_len = static_cast<u32>(std::min(bytes_to_go, MAX_BUFFER_SIZE));
  23. const int rv = unzReadCurrentFile(file, destination, read_len);
  24. if (rv < 0)
  25. return false;
  26. const u32 bytes_read = static_cast<u32>(rv);
  27. bytes_to_go -= bytes_read;
  28. destination += bytes_read;
  29. }
  30. return unzEndOfFile(file) == 1;
  31. }
  32. template <typename ContiguousContainer>
  33. bool ReadFileFromZip(unzFile file, ContiguousContainer* destination)
  34. {
  35. return ReadFileFromZip(file, reinterpret_cast<u8*>(destination->data()), destination->size());
  36. }
  37. } // namespace Common