CZipSaver.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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. ///CZipOutputStream
  13. CZipOutputStream::CZipOutputStream(CZipSaver * owner_, zipFile archive, const std::string & archiveFilename):
  14. handle(archive),
  15. owner(owner_)
  16. {
  17. zip_fileinfo fileInfo;
  18. std::time_t t = time(nullptr);
  19. fileInfo.dosDate = 0;
  20. struct tm * localTime = std::localtime(&t);
  21. fileInfo.tmz_date.tm_hour = localTime->tm_hour;
  22. fileInfo.tmz_date.tm_mday = localTime->tm_mday;
  23. fileInfo.tmz_date.tm_min = localTime->tm_min;
  24. fileInfo.tmz_date.tm_mon = localTime->tm_mon;
  25. fileInfo.tmz_date.tm_sec = localTime->tm_sec;
  26. fileInfo.tmz_date.tm_year = localTime->tm_year;
  27. fileInfo.external_fa = 0; //???
  28. fileInfo.internal_fa = 0;
  29. int status = zipOpenNewFileInZip4_64(
  30. handle,
  31. archiveFilename.c_str(),
  32. &fileInfo,
  33. nullptr,//extrafield_local
  34. 0,
  35. nullptr,//extrafield_global
  36. 0,
  37. nullptr,//comment
  38. Z_DEFLATED,
  39. Z_DEFAULT_COMPRESSION,
  40. 0,//raw
  41. -15,//windowBits
  42. 9,//memLevel
  43. Z_DEFAULT_STRATEGY,//strategy
  44. nullptr,//password
  45. 0,//crcForCrypting
  46. 20,//versionMadeBy
  47. 0,//flagBase
  48. 0//zip64
  49. );
  50. if(status != ZIP_OK)
  51. throw new std::runtime_error("CZipOutputStream: zipOpenNewFileInZip failed");
  52. owner->activeStream = this;
  53. }
  54. CZipOutputStream::~CZipOutputStream()
  55. {
  56. int status = zipCloseFileInZip(handle);
  57. if (status != ZIP_OK)
  58. logGlobal->error("CZipOutputStream: stream finalize failed: %d", static_cast<int>(status));
  59. owner->activeStream = nullptr;
  60. }
  61. si64 CZipOutputStream::write(const ui8 * data, si64 size)
  62. {
  63. int ret = zipWriteInFileInZip(handle, (const void*)data, (unsigned)size);
  64. if (ret == ZIP_OK)
  65. return size;
  66. else
  67. return 0;
  68. }
  69. ///CZipSaver
  70. CZipSaver::CZipSaver(std::shared_ptr<CIOApi> api, const boost::filesystem::path & path):
  71. ioApi(api),
  72. zipApi(ioApi->getApiStructure()),
  73. handle(nullptr),
  74. activeStream(nullptr)
  75. {
  76. handle = zipOpen2_64((const void *) & path, APPEND_STATUS_CREATE, nullptr, &zipApi);
  77. if (handle == nullptr)
  78. throw new 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 new std::runtime_error("CZipSaver::addFile: stream already opened");
  98. std::unique_ptr<COutputStream> stream(new CZipOutputStream(this, handle, archiveFilename));
  99. return std::move(stream);
  100. }