2
0

CZipSaver.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*
  2. * CZipSaver.cpp, part of VCMI engine
  3. *
  4. * Authors: listed in file AUTHORS in main folder
  5. *
  6. * License: GNU General Public License v2.0 or later
  7. * Full text of license available in license.txt file, in main folder
  8. *
  9. */
  10. #include "StdInc.h"
  11. #include "CZipSaver.h"
  12. VCMI_LIB_NAMESPACE_BEGIN
  13. ///CZipOutputStream
  14. CZipOutputStream::CZipOutputStream(CZipSaver * owner_, zipFile archive, const std::string & archiveFilename):
  15. handle(archive),
  16. owner(owner_)
  17. {
  18. zip_fileinfo fileInfo;
  19. std::time_t t = time(nullptr);
  20. fileInfo.dosDate = 0;
  21. struct tm * localTime = std::localtime(&t);
  22. fileInfo.tmz_date.tm_hour = localTime->tm_hour;
  23. fileInfo.tmz_date.tm_mday = localTime->tm_mday;
  24. fileInfo.tmz_date.tm_min = localTime->tm_min;
  25. fileInfo.tmz_date.tm_mon = localTime->tm_mon;
  26. fileInfo.tmz_date.tm_sec = localTime->tm_sec;
  27. fileInfo.tmz_date.tm_year = localTime->tm_year;
  28. fileInfo.external_fa = 0; //???
  29. fileInfo.internal_fa = 0;
  30. int status = zipOpenNewFileInZip4_64(
  31. handle,
  32. archiveFilename.c_str(),
  33. &fileInfo,
  34. nullptr,//extrafield_local
  35. 0,
  36. nullptr,//extrafield_global
  37. 0,
  38. nullptr,//comment
  39. Z_DEFLATED,
  40. Z_DEFAULT_COMPRESSION,
  41. 0,//raw
  42. -15,//windowBits
  43. 9,//memLevel
  44. Z_DEFAULT_STRATEGY,//strategy
  45. nullptr,//password
  46. 0,//crcForCrypting
  47. 20,//versionMadeBy
  48. 0,//flagBase
  49. 0//zip64
  50. );
  51. if(status != ZIP_OK)
  52. throw std::runtime_error("CZipOutputStream: zipOpenNewFileInZip failed");
  53. owner->activeStream = this;
  54. }
  55. CZipOutputStream::~CZipOutputStream()
  56. {
  57. int status = zipCloseFileInZip(handle);
  58. if (status != ZIP_OK)
  59. logGlobal->error("CZipOutputStream: stream finalize failed: %d", static_cast<int>(status));
  60. owner->activeStream = nullptr;
  61. }
  62. si64 CZipOutputStream::write(const ui8 * data, si64 size)
  63. {
  64. int ret = zipWriteInFileInZip(handle, data, static_cast<unsigned>(size));
  65. if (ret == ZIP_OK)
  66. return size;
  67. else
  68. return 0;
  69. }
  70. ///CZipSaver
  71. CZipSaver::CZipSaver(std::shared_ptr<CIOApi> api, const boost::filesystem::path & path):
  72. ioApi(std::move(api)),
  73. zipApi(ioApi->getApiStructure()),
  74. handle(zipOpen2_64(path.c_str(), APPEND_STATUS_CREATE, nullptr, &zipApi)),
  75. activeStream(nullptr)
  76. {
  77. if (handle == nullptr)
  78. throw std::runtime_error("CZipSaver: Failed to create archive");
  79. }
  80. CZipSaver::~CZipSaver()
  81. {
  82. if(activeStream != nullptr)
  83. {
  84. logGlobal->error("CZipSaver::~CZipSaver: active stream found");
  85. zipCloseFileInZip(handle);
  86. }
  87. if(handle != nullptr)
  88. {
  89. int status = zipClose(handle, nullptr);
  90. if (status != ZIP_OK)
  91. logGlobal->error("CZipSaver: archive finalize failed: %d", static_cast<int>(status));
  92. }
  93. }
  94. std::unique_ptr<COutputStream> CZipSaver::addFile(const std::string & archiveFilename)
  95. {
  96. if(activeStream != nullptr)
  97. throw std::runtime_error("CZipSaver::addFile: stream already opened");
  98. std::unique_ptr<COutputStream> stream(new CZipOutputStream(this, handle, archiveFilename));
  99. return stream;
  100. }
  101. VCMI_LIB_NAMESPACE_END