CZipLoader.cpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #include "StdInc.h"
  2. #include "../../Global.h"
  3. #include "CZipLoader.h"
  4. /*
  5. * CZipLoader.cpp, part of VCMI engine
  6. *
  7. * Authors: listed in file AUTHORS in main folder
  8. *
  9. * License: GNU General Public License v2.0 or later
  10. * Full text of license available in license.txt file, in main folder
  11. *
  12. */
  13. CZipStream::CZipStream(const std::string & archive, unz_file_pos filepos)
  14. {
  15. file = unzOpen(archive.c_str());
  16. unzGoToFilePos(file, &filepos);
  17. unzOpenCurrentFile(file);
  18. }
  19. CZipStream::~CZipStream()
  20. {
  21. unzCloseCurrentFile(file);
  22. unzClose(file);
  23. }
  24. si64 CZipStream::readMore(ui8 * data, si64 size)
  25. {
  26. return unzReadCurrentFile(file, data, size);
  27. }
  28. si64 CZipStream::getSize()
  29. {
  30. unz_file_info info;
  31. unzGetCurrentFileInfo (file, &info, nullptr, 0, nullptr, 0, nullptr, 0);
  32. return info.uncompressed_size;
  33. }
  34. CZipLoader::CZipLoader(const std::string & mountPoint, const std::string & archive):
  35. archiveName(archive),
  36. mountPoint(mountPoint),
  37. files(listFiles(mountPoint, archive))
  38. {
  39. logGlobal->traceStream() << "Zip archive loaded, " << files.size() << " files found";
  40. }
  41. std::unordered_map<ResourceID, unz_file_pos> CZipLoader::listFiles(const std::string & mountPoint, const std::string & archive)
  42. {
  43. std::unordered_map<ResourceID, unz_file_pos> ret;
  44. unzFile file = unzOpen(archive.c_str());
  45. if (unzGoToFirstFile(file) == UNZ_OK)
  46. {
  47. do
  48. {
  49. unz_file_info info;
  50. std::vector<char> filename;
  51. // Fill unz_file_info structure with current file info
  52. unzGetCurrentFileInfo (file, &info, nullptr, 0, nullptr, 0, nullptr, 0);
  53. filename.resize(info.size_filename);
  54. // Get name of current file. Contrary to docs "info" parameter can't be null
  55. unzGetCurrentFileInfo (file, &info, filename.data(), filename.size(), nullptr, 0, nullptr, 0);
  56. std::string filenameString(filename.data(), filename.size());
  57. unzGetFilePos(file, &ret[ResourceID(mountPoint + filenameString)]);
  58. }
  59. while (unzGoToNextFile(file) == UNZ_OK);
  60. }
  61. unzClose(file);
  62. return ret;
  63. }
  64. std::unique_ptr<CInputStream> CZipLoader::load(const ResourceID & resourceName) const
  65. {
  66. return std::unique_ptr<CInputStream>(new CZipStream(archiveName, files.at(resourceName)));
  67. }
  68. bool CZipLoader::existsResource(const ResourceID & resourceName) const
  69. {
  70. return files.count(resourceName) != 0;
  71. }
  72. std::string CZipLoader::getMountPoint() const
  73. {
  74. return mountPoint;
  75. }
  76. std::unordered_set<ResourceID> CZipLoader::getFilteredFiles(std::function<bool(const ResourceID &)> filter) const
  77. {
  78. std::unordered_set<ResourceID> foundID;
  79. for (auto & file : files)
  80. {
  81. if (filter(file.first))
  82. foundID.insert(file.first);
  83. }
  84. return foundID;
  85. }