7zencode.cpp

来自「由7-zip提供的压缩、解压缩程序」· C++ 代码 · 共 613 行 · 第 1/2 页

CPP
613
字号
      }      RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, sizeInBytes));    }    if (methodFull.IsSimpleCoder())      _mixerCoderSpec->AddCoder(encoder);    else      _mixerCoderSpec->AddCoder2(encoder2);  }  return S_OK;}HRESULT CEncoder::Encode(ISequentialInStream *inStream,    const UInt64 *inStreamSize, const UInt64 *inSizeForReduce,    CFolder &folderItem,    ISequentialOutStream *outStream,    CRecordVector<UInt64> &packSizes,    ICompressProgressInfo *compressProgress){  if (_mixerCoderSpec == NULL)  {    RINOK(CreateMixerCoder(inSizeForReduce));  }  _mixerCoderSpec->ReInit();  // _mixerCoderSpec->SetCoderInfo(0, NULL, NULL, progress);  CObjectVector<CInOutTempBuffer> inOutTempBuffers;  CObjectVector<CSequentialOutTempBufferImp *> tempBufferSpecs;  CObjectVector<CMyComPtr<ISequentialOutStream> > tempBuffers;  int numMethods = _bindInfo.Coders.Size();  int i;  for (i = 1; i < _bindInfo.OutStreams.Size(); i++)  {    inOutTempBuffers.Add(CInOutTempBuffer());    inOutTempBuffers.Back().Create();    inOutTempBuffers.Back().InitWriting();  }  for (i = 1; i < _bindInfo.OutStreams.Size(); i++)  {    CSequentialOutTempBufferImp *tempBufferSpec =         new CSequentialOutTempBufferImp;    CMyComPtr<ISequentialOutStream> tempBuffer = tempBufferSpec;    tempBufferSpec->Init(&inOutTempBuffers[i - 1]);    tempBuffers.Add(tempBuffer);    tempBufferSpecs.Add(tempBufferSpec);  }  for (i = 0; i < numMethods; i++)    _mixerCoderSpec->SetCoderInfo(i, NULL, NULL);  if (_bindInfo.InStreams.IsEmpty())    return E_FAIL;  UInt32 mainCoderIndex, mainStreamIndex;  _bindInfo.FindInStream(_bindInfo.InStreams[0], mainCoderIndex, mainStreamIndex);  _mixerCoderSpec->SetProgressCoderIndex(mainCoderIndex);  if (inStreamSize != NULL)  {    CRecordVector<const UInt64 *> sizePointers;    for (UInt32 i = 0; i < _bindInfo.Coders[mainCoderIndex].NumInStreams; i++)      if (i == mainStreamIndex)        sizePointers.Add(inStreamSize);      else        sizePointers.Add(NULL);    _mixerCoderSpec->SetCoderInfo(mainCoderIndex, &sizePointers.Front(), NULL);  }    // UInt64 outStreamStartPos;  // RINOK(stream->Seek(0, STREAM_SEEK_CUR, &outStreamStartPos));    CSequentialInStreamSizeCount2 *inStreamSizeCountSpec =       new CSequentialInStreamSizeCount2;  CMyComPtr<ISequentialInStream> inStreamSizeCount = inStreamSizeCountSpec;  CSequentialOutStreamSizeCount *outStreamSizeCountSpec =       new CSequentialOutStreamSizeCount;  CMyComPtr<ISequentialOutStream> outStreamSizeCount = outStreamSizeCountSpec;  inStreamSizeCountSpec->Init(inStream);  outStreamSizeCountSpec->Init(outStream);  CRecordVector<ISequentialInStream *> inStreamPointers;  CRecordVector<ISequentialOutStream *> outStreamPointers;  inStreamPointers.Add(inStreamSizeCount);  outStreamPointers.Add(outStreamSizeCount);  for (i = 1; i < _bindInfo.OutStreams.Size(); i++)    outStreamPointers.Add(tempBuffers[i - 1]);    RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1,    &outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress));    ConvertBindInfoToFolderItemInfo(_decompressBindInfo, _decompressionMethods,      folderItem);    packSizes.Add(outStreamSizeCountSpec->GetSize());    for (i = 1; i < _bindInfo.OutStreams.Size(); i++)  {    CInOutTempBuffer &inOutTempBuffer = inOutTempBuffers[i - 1];    inOutTempBuffer.FlushWrite();    inOutTempBuffer.InitReading();    inOutTempBuffer.WriteToStream(outStream);    packSizes.Add(inOutTempBuffer.GetDataSize());  }    for (i = 0; i < (int)_bindReverseConverter->NumSrcInStreams; i++)  {    int binder = _bindInfo.FindBinderForInStream(        _bindReverseConverter->DestOutToSrcInMap[i]);    UInt64 streamSize;    if (binder < 0)      streamSize = inStreamSizeCountSpec->GetSize();    else      streamSize = _mixerCoderSpec->GetWriteProcessedSize(binder);    folderItem.UnPackSizes.Add(streamSize);  }  for (i = numMethods - 1; i >= 0; i--)  {    // folderItem.Coders[numMethods - 1 - i].Properties = _codersInfo[i].Properties;    for (int j = 0; j < _codersInfo[i].AltCoders.Size(); j++)      folderItem.Coders[numMethods - 1 - i].AltCoders[j].Properties           = _codersInfo[i].AltCoders[j].Properties;  }  return S_OK;}CEncoder::CEncoder(const CCompressionMethodMode &options):  _bindReverseConverter(0){  if (options.IsEmpty())    throw 1;  _options = options;  _mixerCoderSpec = NULL;  if (options.Methods.IsEmpty())  {    // it has only password method;    if (!options.PasswordIsDefined)      throw 1;    if (!options.Binds.IsEmpty())      throw 1;    NCoderMixer2::CCoderStreamsInfo coderStreamsInfo;    CMethodFull method;        method.NumInStreams = 1;    method.NumOutStreams = 1;    coderStreamsInfo.NumInStreams = method.NumOutStreams;    coderStreamsInfo.NumOutStreams = method.NumInStreams;    method.MethodID = k_AES;        #ifndef EXCLUDE_COM    CMethodInfo2 methodInfo;    if (!GetMethodInfo(kCryproMethod, methodInfo))       throw 2;    method.FilePath = methodInfo.FilePath;    method.EncoderClassID = methodInfo.Encoder;    // method.EncoderClassID = CLSID_CCrypto7zAESEncoder;    #endif        _options.Methods.Add(method);    _bindInfo.Coders.Add(coderStreamsInfo);      _bindInfo.InStreams.Add(0);    _bindInfo.OutStreams.Add(0);  }  else  {  UInt32 numInStreams = 0, numOutStreams = 0;  int i;  for (i = 0; i < options.Methods.Size(); i++)  {    const CMethodFull &methodFull = options.Methods[i];    NCoderMixer2::CCoderStreamsInfo coderStreamsInfo;    coderStreamsInfo.NumInStreams = methodFull.NumOutStreams;    coderStreamsInfo.NumOutStreams = methodFull.NumInStreams;    if (options.Binds.IsEmpty())    {      if (i < options.Methods.Size() - 1)      {        NCoderMixer2::CBindPair bindPair;        bindPair.InIndex = numInStreams + coderStreamsInfo.NumInStreams;        bindPair.OutIndex = numOutStreams;        _bindInfo.BindPairs.Add(bindPair);      }      else        _bindInfo.OutStreams.Insert(0, numOutStreams);      for (UInt32 j = 1; j < coderStreamsInfo.NumOutStreams; j++)        _bindInfo.OutStreams.Add(numOutStreams + j);    }        numInStreams += coderStreamsInfo.NumInStreams;    numOutStreams += coderStreamsInfo.NumOutStreams;    _bindInfo.Coders.Add(coderStreamsInfo);  }  if (!options.Binds.IsEmpty())  {    for (i = 0; i < options.Binds.Size(); i++)    {      NCoderMixer2::CBindPair bindPair;      const CBind &bind = options.Binds[i];      bindPair.InIndex = _bindInfo.GetCoderInStreamIndex(bind.InCoder) + bind.InStream;      bindPair.OutIndex = _bindInfo.GetCoderOutStreamIndex(bind.OutCoder) + bind.OutStream;      _bindInfo.BindPairs.Add(bindPair);    }    for (i = 0; i < (int)numOutStreams; i++)      if (_bindInfo.FindBinderForOutStream(i) == -1)        _bindInfo.OutStreams.Add(i);  }  for (i = 0; i < (int)numInStreams; i++)    if (_bindInfo.FindBinderForInStream(i) == -1)      _bindInfo.InStreams.Add(i);  if (_bindInfo.InStreams.IsEmpty())    throw 1; // this is error  // Make main stream first in list  int inIndex = _bindInfo.InStreams[0];  while (true)  {    UInt32 coderIndex, coderStreamIndex;    _bindInfo.FindInStream(inIndex, coderIndex, coderStreamIndex);    UInt32 outIndex = _bindInfo.GetCoderOutStreamIndex(coderIndex);    int binder = _bindInfo.FindBinderForOutStream(outIndex);    if (binder >= 0)    {      inIndex = _bindInfo.BindPairs[binder].InIndex;      continue;    }    for (i = 0; i < _bindInfo.OutStreams.Size(); i++)      if (_bindInfo.OutStreams[i] == outIndex)      {        _bindInfo.OutStreams.Delete(i);        _bindInfo.OutStreams.Insert(0, outIndex);        break;      }    break;  }  if (_options.PasswordIsDefined)  {    int numCryptoStreams = _bindInfo.OutStreams.Size();    for (i = 0; i < numCryptoStreams; i++)    {      NCoderMixer2::CBindPair bindPair;      bindPair.InIndex = numInStreams + i;      bindPair.OutIndex = _bindInfo.OutStreams[i];      _bindInfo.BindPairs.Add(bindPair);    }    _bindInfo.OutStreams.Clear();    /*    if (numCryptoStreams == 0)      numCryptoStreams = 1;    */    for (i = 0; i < numCryptoStreams; i++)    {      NCoderMixer2::CCoderStreamsInfo coderStreamsInfo;      CMethodFull method;      method.NumInStreams = 1;      method.NumOutStreams = 1;      coderStreamsInfo.NumInStreams = method.NumOutStreams;      coderStreamsInfo.NumOutStreams = method.NumInStreams;      method.MethodID = k_AES;      #ifndef EXCLUDE_COM      CMethodInfo2 methodInfo;      if (!GetMethodInfo(kCryproMethod, methodInfo))         throw 2;      method.FilePath = methodInfo.FilePath;      method.EncoderClassID = methodInfo.Encoder;      // method.EncoderClassID = CLSID_CCrypto7zAESEncoder;      #endif      _options.Methods.Add(method);      _bindInfo.Coders.Add(coderStreamsInfo);      _bindInfo.OutStreams.Add(numOutStreams + i);    }  }  }  for (int i = _options.Methods.Size() - 1; i >= 0; i--)  {    const CMethodFull &methodFull = _options.Methods[i];    _decompressionMethods.Add(methodFull.MethodID);  }  _bindReverseConverter = new NCoderMixer2::CBindReverseConverter(_bindInfo);  _bindReverseConverter->CreateReverseBindInfo(_decompressBindInfo);}CEncoder::~CEncoder(){  delete _bindReverseConverter;}}}

⌨️ 快捷键说明

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