diff options
Diffstat (limited to 'CPP/7zip/Archive/GZip/GZipUpdate.cpp')
-rwxr-xr-x | CPP/7zip/Archive/GZip/GZipUpdate.cpp | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/CPP/7zip/Archive/GZip/GZipUpdate.cpp b/CPP/7zip/Archive/GZip/GZipUpdate.cpp new file mode 100755 index 00000000..45e6e985 --- /dev/null +++ b/CPP/7zip/Archive/GZip/GZipUpdate.cpp @@ -0,0 +1,120 @@ +// GZipUpdate.cpp + +#include "StdAfx.h" + +#include "GZipUpdate.h" + +#include "Common/Defs.h" +#include "Common/StringConvert.h" + +#include "Windows/Defs.h" +#include "Windows/PropVariant.h" + +#include "../../ICoder.h" +#include "../../Common/ProgressUtils.h" +#include "../../Compress/Copy/CopyCoder.h" + +#include "../Common/InStreamWithCRC.h" + +#ifdef COMPRESS_DEFLATE +#include "../../Compress/Deflate/DeflateEncoder.h" +#else +// {23170F69-40C1-278B-0401-080000000100} +DEFINE_GUID(CLSID_CCompressDeflateEncoder, +0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00); +#include "../Common/CoderLoader.h" +extern CSysString GetDeflateCodecPath(); +#endif + +namespace NArchive { +namespace NGZip { + +static const Byte kHostOS = NFileHeader::NHostOS::kFAT; + +HRESULT UpdateArchive(IInStream * /* inStream */, + UInt64 unpackSize, + ISequentialOutStream *outStream, + const CItem &newItem, + const CCompressionMethodMode &compressionMethod, + int indexInClient, + IArchiveUpdateCallback *updateCallback) +{ + UInt64 complexity = 0; + + complexity += unpackSize; + + RINOK(updateCallback->SetTotal(complexity)); + + #ifndef COMPRESS_DEFLATE + CCoderLibrary lib; + #endif + CMyComPtr<ICompressCoder> deflateEncoder; + + complexity = 0; + RINOK(updateCallback->SetCompleted(&complexity)); + + CMyComPtr<ISequentialInStream> fileInStream; + + RINOK(updateCallback->GetStream(indexInClient, &fileInStream)); + + CSequentialInStreamWithCRC *inStreamSpec = new CSequentialInStreamWithCRC; + CMyComPtr<ISequentialInStream> crcStream(inStreamSpec); + inStreamSpec->SetStream(fileInStream); + inStreamSpec->Init(); + + CLocalProgress *localProgressSpec = new CLocalProgress; + CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec; + localProgressSpec->Init(updateCallback, true); + + CLocalCompressProgressInfo *localCompressProgressSpec = + new CLocalCompressProgressInfo; + CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec; + + COutArchive outArchive; + outArchive.Create(outStream); + + CItem item = newItem; + item.CompressionMethod = NFileHeader::NCompressionMethod::kDeflate; + item.ExtraFlags = 0; + item.HostOS = kHostOS; + + RINOK(outArchive.WriteHeader(item)); + + localCompressProgressSpec->Init(localProgress, &complexity, NULL); + + { + #ifdef COMPRESS_DEFLATE + deflateEncoder = new NCompress::NDeflate::NEncoder::CCOMCoder; + #else + RINOK(lib.LoadAndCreateCoder(GetDeflateCodecPath(), + CLSID_CCompressDeflateEncoder, &deflateEncoder)); + #endif + + NWindows::NCOM::CPropVariant properties[] = + { + compressionMethod.NumPasses, + compressionMethod.NumFastBytes, + compressionMethod.NumMatchFinderCycles + }; + PROPID propIDs[] = + { + NCoderPropID::kNumPasses, + NCoderPropID::kNumFastBytes, + NCoderPropID::kMatchFinderCycles + }; + int numProps = sizeof(propIDs) / sizeof(propIDs[0]); + if (!compressionMethod.NumMatchFinderCyclesDefined) + numProps--; + CMyComPtr<ICompressSetCoderProperties> setCoderProperties; + RINOK(deflateEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties)); + RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, numProps)); + } + RINOK(deflateEncoder->Code(crcStream, outStream, NULL, NULL, compressProgress)); + + item.FileCRC = inStreamSpec->GetCRC(); + item.UnPackSize32 = (UInt32)inStreamSpec->GetSize(); + RINOK(outArchive.WritePostHeader(item)); + return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK); +} + +}} |