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 + -
显示快捷键?