| 
									
										
										
										
											2015-08-11 21:20:13 +03:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * CZipSaver.cpp, part of VCMI engine | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Authors: listed in file AUTHORS in main folder | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * License: GNU General Public License v2.0 or later | 
					
						
							|  |  |  |  * Full text of license available in license.txt file, in main folder | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-06-14 11:56:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-11 21:20:13 +03:00
										 |  |  | #include "StdInc.h"
 | 
					
						
							|  |  |  | #include "CZipSaver.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-26 16:07:42 +03:00
										 |  |  | VCMI_LIB_NAMESPACE_BEGIN | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-11 21:20:13 +03:00
										 |  |  | ///CZipOutputStream
 | 
					
						
							| 
									
										
										
										
											2015-08-12 03:31:06 +03:00
										 |  |  | CZipOutputStream::CZipOutputStream(CZipSaver * owner_, zipFile archive, const std::string & archiveFilename): | 
					
						
							|  |  |  | 	handle(archive), | 
					
						
							|  |  |  | 	owner(owner_) | 
					
						
							| 
									
										
										
										
											2015-08-11 21:20:13 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-08-14 01:42:52 +03:00
										 |  |  | 	zip_fileinfo fileInfo; | 
					
						
							| 
									
										
										
										
											2017-06-14 11:56:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-14 01:42:52 +03:00
										 |  |  | 	std::time_t t = time(nullptr); | 
					
						
							| 
									
										
										
										
											2017-06-14 11:56:35 +03:00
										 |  |  | 	fileInfo.dosDate = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-14 01:42:52 +03:00
										 |  |  | 	struct tm * localTime = std::localtime(&t); | 
					
						
							|  |  |  | 	fileInfo.tmz_date.tm_hour = localTime->tm_hour; | 
					
						
							|  |  |  | 	fileInfo.tmz_date.tm_mday = localTime->tm_mday; | 
					
						
							|  |  |  | 	fileInfo.tmz_date.tm_min  = localTime->tm_min; | 
					
						
							|  |  |  | 	fileInfo.tmz_date.tm_mon  = localTime->tm_mon; | 
					
						
							|  |  |  | 	fileInfo.tmz_date.tm_sec  = localTime->tm_sec; | 
					
						
							|  |  |  | 	fileInfo.tmz_date.tm_year = localTime->tm_year; | 
					
						
							| 
									
										
										
										
											2017-06-14 11:56:35 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	fileInfo.external_fa = 0; //???
 | 
					
						
							|  |  |  | 	fileInfo.internal_fa = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-18 01:56:16 +03:00
										 |  |  | 	int status = zipOpenNewFileInZip4_64( | 
					
						
							|  |  |  | 						handle, | 
					
						
							|  |  |  | 						archiveFilename.c_str(), | 
					
						
							|  |  |  | 						&fileInfo, | 
					
						
							|  |  |  | 						nullptr,//extrafield_local
 | 
					
						
							|  |  |  | 						0, | 
					
						
							|  |  |  | 						nullptr,//extrafield_global
 | 
					
						
							|  |  |  | 						0, | 
					
						
							|  |  |  | 						nullptr,//comment
 | 
					
						
							|  |  |  | 						Z_DEFLATED, | 
					
						
							|  |  |  | 						Z_DEFAULT_COMPRESSION, | 
					
						
							|  |  |  | 						0,//raw
 | 
					
						
							|  |  |  | 						-15,//windowBits
 | 
					
						
							|  |  |  | 						9,//memLevel
 | 
					
						
							|  |  |  | 						Z_DEFAULT_STRATEGY,//strategy
 | 
					
						
							|  |  |  | 						nullptr,//password
 | 
					
						
							|  |  |  | 						0,//crcForCrypting
 | 
					
						
							|  |  |  | 						20,//versionMadeBy
 | 
					
						
							|  |  |  | 						0,//flagBase
 | 
					
						
							|  |  |  | 						0//zip64
 | 
					
						
							|  |  |  | 						); | 
					
						
							| 
									
										
										
										
											2017-06-14 11:56:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-13 03:29:13 +03:00
										 |  |  |     if(status != ZIP_OK) | 
					
						
							| 
									
										
										
										
											2018-10-31 07:27:54 +01:00
										 |  |  | 		throw std::runtime_error("CZipOutputStream: zipOpenNewFileInZip failed"); | 
					
						
							| 
									
										
										
										
											2017-06-14 11:56:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-12 03:31:06 +03:00
										 |  |  | 	owner->activeStream = this; | 
					
						
							| 
									
										
										
										
											2015-08-11 21:20:13 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CZipOutputStream::~CZipOutputStream() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2015-08-18 01:56:16 +03:00
										 |  |  | 	int status = zipCloseFileInZip(handle); | 
					
						
							|  |  |  | 	if (status != ZIP_OK) | 
					
						
							| 
									
										
										
										
											2017-08-12 15:43:41 +03:00
										 |  |  | 		logGlobal->error("CZipOutputStream: stream finalize failed: %d", static_cast<int>(status)); | 
					
						
							| 
									
										
										
										
											2015-08-12 03:31:06 +03:00
										 |  |  | 	owner->activeStream = nullptr; | 
					
						
							| 
									
										
										
										
											2015-08-11 21:20:13 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | si64 CZipOutputStream::write(const ui8 * data, si64 size) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-02-15 01:09:07 +03:00
										 |  |  | 	int ret = zipWriteInFileInZip(handle, data, static_cast<unsigned>(size)); | 
					
						
							| 
									
										
										
										
											2017-06-14 11:56:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-11 21:20:13 +03:00
										 |  |  | 	if (ret == ZIP_OK) | 
					
						
							|  |  |  | 		return size; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ///CZipSaver
 | 
					
						
							| 
									
										
										
										
											2017-06-14 11:56:35 +03:00
										 |  |  | CZipSaver::CZipSaver(std::shared_ptr<CIOApi> api, const boost::filesystem::path & path): | 
					
						
							| 
									
										
										
										
											2023-02-15 01:09:07 +03:00
										 |  |  | 	ioApi(std::move(api)), | 
					
						
							| 
									
										
										
										
											2015-08-11 21:20:13 +03:00
										 |  |  | 	zipApi(ioApi->getApiStructure()), | 
					
						
							| 
									
										
										
										
											2023-02-15 01:09:07 +03:00
										 |  |  | 	handle(zipOpen2_64(path.c_str(), APPEND_STATUS_CREATE, nullptr, &zipApi)), | 
					
						
							| 
									
										
										
										
											2015-08-12 03:31:06 +03:00
										 |  |  | 	activeStream(nullptr) | 
					
						
							| 
									
										
										
										
											2015-08-11 21:20:13 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-06-14 11:56:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-11 21:20:13 +03:00
										 |  |  | 	if (handle == nullptr) | 
					
						
							| 
									
										
										
										
											2018-10-31 07:27:54 +01:00
										 |  |  | 		throw std::runtime_error("CZipSaver: Failed to create archive"); | 
					
						
							| 
									
										
										
										
											2015-08-11 21:20:13 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CZipSaver::~CZipSaver() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2015-08-12 03:31:06 +03:00
										 |  |  | 	if(activeStream != nullptr) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2017-06-14 11:56:35 +03:00
										 |  |  | 		logGlobal->error("CZipSaver::~CZipSaver: active stream found"); | 
					
						
							| 
									
										
										
										
											2015-08-12 03:31:06 +03:00
										 |  |  | 		zipCloseFileInZip(handle); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-06-14 11:56:35 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-11 21:20:13 +03:00
										 |  |  | 	if(handle != nullptr) | 
					
						
							| 
									
										
										
										
											2015-08-18 01:56:16 +03:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		int status = zipClose(handle, nullptr); | 
					
						
							|  |  |  | 		if (status != ZIP_OK) | 
					
						
							| 
									
										
										
										
											2017-08-12 15:43:41 +03:00
										 |  |  | 			logGlobal->error("CZipSaver: archive finalize failed: %d", static_cast<int>(status)); | 
					
						
							| 
									
										
										
										
											2015-08-18 01:56:16 +03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2017-06-14 11:56:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-11 21:20:13 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | std::unique_ptr<COutputStream> CZipSaver::addFile(const std::string & archiveFilename) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if(activeStream != nullptr) | 
					
						
							| 
									
										
										
										
											2018-10-31 07:27:54 +01:00
										 |  |  | 		throw std::runtime_error("CZipSaver::addFile: stream already opened"); | 
					
						
							| 
									
										
										
										
											2017-06-14 11:56:35 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-08-12 03:31:06 +03:00
										 |  |  | 	std::unique_ptr<COutputStream> stream(new CZipOutputStream(this, handle, archiveFilename)); | 
					
						
							| 
									
										
										
										
											2019-01-19 13:52:02 +03:00
										 |  |  | 	return stream; | 
					
						
							| 
									
										
										
										
											2015-08-11 21:20:13 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-26 16:07:42 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | VCMI_LIB_NAMESPACE_END |