⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zipaddcommon.cpp

📁 由7-zip提供的压缩、解压缩程序
💻 CPP
字号:
// AddCommon.cpp#include "StdAfx.h"#include "Common/CRC.h"#include "Windows/PropVariant.h"#include "Windows/Defs.h"#include "../../ICoder.h"#include "../../IPassword.h"#include "../7z/7zMethods.h"#include "ZipAddCommon.h"#include "ZipHeader.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);#endif#ifdef COMPRESS_DEFLATE64#include "../../Compress/Deflate/DeflateEncoder.h"#else// {23170F69-40C1-278B-0401-090000000100}DEFINE_GUID(CLSID_CCompressDeflate64Encoder, 0x23170F69, 0x40C1, 0x278B, 0x04, 0x01, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00);#endif#ifdef COMPRESS_BZIP2#include "../../Compress/BZip2/BZip2Encoder.h"#else// {23170F69-40C1-278B-0402-020000000100}DEFINE_GUID(CLSID_CCompressBZip2Encoder, 0x23170F69, 0x40C1, 0x278B, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00);#endif#ifdef CRYPTO_ZIP#include "../../Crypto/Zip/ZipCipher.h"#else// {23170F69-40C1-278B-06F1-0101000000100}DEFINE_GUID(CLSID_CCryptoZipEncoder, 0x23170F69, 0x40C1, 0x278B, 0x06, 0xF1, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00);#endifnamespace NArchive {namespace NZip {static const Byte kMethodIDForEmptyStream = NFileHeader::NCompressionMethod::kStored;static const Byte kExtractVersionForEmptyStream = NFileHeader::NCompressionMethod::kStoreExtractVersion;CAddCommon::CAddCommon(const CCompressionMethodMode &options):  _options(options),  _copyCoderSpec(NULL),  _cryptoStreamSpec(0) {}static HRESULT GetStreamCRC(ISequentialInStream *inStream, UInt32 &resultCRC){  CCRC crc;  crc.Init();  const UInt32 kBufferSize = (1 << 14);  Byte buffer[kBufferSize];  while(true)  {    UInt32 realProcessedSize;    RINOK(inStream->Read(buffer, kBufferSize, &realProcessedSize));    if(realProcessedSize == 0)    {      resultCRC = crc.GetDigest();      return S_OK;    }    crc.Update(buffer, realProcessedSize);  }}HRESULT CAddCommon::Compress(ISequentialInStream *inStream, IOutStream *outStream,       UInt64 inSize, ICompressProgressInfo *progress, CCompressingResult &operationResult){  /*  if(inSize == 0)  {    operationResult.PackSize = 0;    operationResult.Method = kMethodIDForEmptyStream;    operationResult.ExtractVersion = kExtractVersionForEmptyStream;    return S_OK;  }  */  CMyComPtr<IInStream> inStream2;  int numTestMethods = _options.MethodSequence.Size();  if (numTestMethods > 1 || _options.PasswordIsDefined)  {    inStream->QueryInterface(IID_IInStream, (void **)&inStream2);    if (!inStream2)    {      if (_options.PasswordIsDefined)        return E_NOTIMPL;      numTestMethods = 1;    }  }  Byte method;  UInt64 resultSize = 0;  COutStreamReleaser outStreamReleaser;  for(int i = 0; i < numTestMethods; i++)  {    if (inStream2)      RINOK(inStream2->Seek(0, STREAM_SEEK_SET, NULL));    RINOK(outStream->Seek(0, STREAM_SEEK_SET, NULL));    if (_options.PasswordIsDefined)    {      if (!_cryptoStream)      {        _cryptoStreamSpec = new CFilterCoder;        _cryptoStream = _cryptoStreamSpec;        _filterSpec = new NCrypto::NZip::CEncoder;        _cryptoStreamSpec->Filter = _filterSpec;      }      RINOK(_filterSpec->CryptoSetPassword(          (const Byte *)(const char *)_options.Password, _options.Password.Length()));      UInt32 crc;      RINOK(GetStreamCRC(inStream, crc));      RINOK(inStream2->Seek(0, STREAM_SEEK_SET, NULL));      RINOK(_cryptoStreamSpec->SetOutStream(outStream));      outStreamReleaser.FilterCoder = _cryptoStreamSpec;      RINOK(_filterSpec->CryptoSetCRC(crc));      RINOK(_filterSpec->WriteHeader(outStream));    }    method = _options.MethodSequence[i];    switch(method)    {      case NFileHeader::NCompressionMethod::kStored:      {        if(_copyCoderSpec == NULL)        {          _copyCoderSpec = new NCompress::CCopyCoder;          _copyCoder = _copyCoderSpec;        }        CMyComPtr<ISequentialOutStream> outStreamNew;        if (_options.PasswordIsDefined)          outStreamNew = _cryptoStream;        else          outStreamNew = outStream;        RINOK(_copyCoder->Code(inStream, outStreamNew,               NULL, NULL, progress));        operationResult.ExtractVersion = NFileHeader::NCompressionMethod::kStoreExtractVersion;        break;      }      default:      {        if(!_compressEncoder)        {          // RINOK(m_MatchFinder.CoCreateInstance(CLSID_CMatchFinderBT3));          #ifndef COMPRESS_DEFLATE          UString methodName;          N7z::LoadMethodMap();          #endif          switch(method)          {            case NFileHeader::NCompressionMethod::kDeflated:            {              #ifdef COMPRESS_DEFLATE              _compressEncoder = new NCompress::NDeflate::NEncoder::CCOMCoder;              #else              methodName = L"Deflate";              #endif              break;            }            case NFileHeader::NCompressionMethod::kDeflated64:            {              #ifdef COMPRESS_DEFLATE64              _compressEncoder = new NCompress::NDeflate::NEncoder::CCOMCoder64;              #else              methodName = L"Deflate64";              #endif              break;            }            case NFileHeader::NCompressionMethod::kBZip2:            {              #ifdef COMPRESS_BZIP2              _compressEncoder = new NCompress::NBZip2::CEncoder;              #else              methodName = L"BZip2";              #endif              break;            }          }          #ifndef COMPRESS_DEFLATE          N7z::CMethodInfo2 methodInfo;          if (!N7z::GetMethodInfo(methodName, methodInfo))            return E_NOTIMPL;          RINOK(_compressLib.LoadAndCreateCoder(            methodInfo.FilePath, methodInfo.Encoder, &_compressEncoder));          #endif          if (method == NFileHeader::NCompressionMethod::kDeflated ||              method == NFileHeader::NCompressionMethod::kDeflated64)          {            NWindows::NCOM::CPropVariant properties[] =             {              _options.NumPasses,               _options.NumFastBytes,              _options.NumMatchFinderCycles            };            PROPID propIDs[] =             {              NCoderPropID::kNumPasses,              NCoderPropID::kNumFastBytes,              NCoderPropID::kMatchFinderCycles            };            int numProps = sizeof(propIDs) / sizeof(propIDs[0]);            if (!_options.NumMatchFinderCyclesDefined)              numProps--;            CMyComPtr<ICompressSetCoderProperties> setCoderProperties;            _compressEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties);            if (setCoderProperties)            {              RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, numProps));            }          }           else if (method == NFileHeader::NCompressionMethod::kBZip2)          {            NWindows::NCOM::CPropVariant properties[] =             {              _options.DicSize,               _options.NumPasses              #ifdef COMPRESS_MT              , _options.NumThreads              #endif            };            PROPID propIDs[] =             {              NCoderPropID::kDictionarySize,              NCoderPropID::kNumPasses              #ifdef COMPRESS_MT              , NCoderPropID::kNumThreads              #endif            };            CMyComPtr<ICompressSetCoderProperties> setCoderProperties;            _compressEncoder.QueryInterface(IID_ICompressSetCoderProperties, &setCoderProperties);            if (setCoderProperties)            {              RINOK(setCoderProperties->SetCoderProperties(propIDs, properties, sizeof(propIDs) / sizeof(propIDs[0])));            }          }        }        CMyComPtr<ISequentialOutStream> outStreamNew;        if (_options.PasswordIsDefined)          outStreamNew = _cryptoStream;        else          outStreamNew = outStream;        RINOK(_compressEncoder->Code(inStream, outStreamNew, NULL, NULL, progress));        operationResult.ExtractVersion = NFileHeader::NCompressionMethod::kDeflateExtractVersion;        break;      }    }    outStream->Seek(0, STREAM_SEEK_CUR, &resultSize);    if (_options.PasswordIsDefined)    {      if(resultSize < inSize  + 12)         break;    }    else if(resultSize < inSize)       break;  }  RINOK(outStream->SetSize(resultSize));  operationResult.PackSize = resultSize;  operationResult.Method = method;  return S_OK;}}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -