diff options
Diffstat (limited to 'src/libs/7zip/unix/CPP/7zip/Archive/7z/7zDecode.cpp')
-rw-r--r-- | src/libs/7zip/unix/CPP/7zip/Archive/7z/7zDecode.cpp | 153 |
1 files changed, 82 insertions, 71 deletions
diff --git a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zDecode.cpp b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zDecode.cpp index 425a34157..973966bd3 100644 --- a/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zDecode.cpp +++ b/src/libs/7zip/unix/CPP/7zip/Archive/7z/7zDecode.cpp @@ -16,29 +16,33 @@ static void ConvertFolderItemInfoToBindInfo(const CFolder &folder, CBindInfoEx &bindInfo) { bindInfo.Clear(); - int i; + bindInfo.BindPairs.ClearAndSetSize(folder.BindPairs.Size()); + unsigned i; for (i = 0; i < folder.BindPairs.Size(); i++) { - NCoderMixer::CBindPair bindPair; + NCoderMixer::CBindPair &bindPair = bindInfo.BindPairs[i]; bindPair.InIndex = (UInt32)folder.BindPairs[i].InIndex; bindPair.OutIndex = (UInt32)folder.BindPairs[i].OutIndex; - bindInfo.BindPairs.Add(bindPair); } + + bindInfo.Coders.ClearAndSetSize(folder.Coders.Size()); + bindInfo.CoderMethodIDs.ClearAndSetSize(folder.Coders.Size()); + UInt32 outStreamIndex = 0; for (i = 0; i < folder.Coders.Size(); i++) { - NCoderMixer::CCoderStreamsInfo coderStreamsInfo; + NCoderMixer::CCoderStreamsInfo &coderStreamsInfo = bindInfo.Coders[i]; const CCoderInfo &coderInfo = folder.Coders[i]; coderStreamsInfo.NumInStreams = (UInt32)coderInfo.NumInStreams; coderStreamsInfo.NumOutStreams = (UInt32)coderInfo.NumOutStreams; - bindInfo.Coders.Add(coderStreamsInfo); - bindInfo.CoderMethodIDs.Add(coderInfo.MethodID); + bindInfo.CoderMethodIDs[i] = coderInfo.MethodID; for (UInt32 j = 0; j < coderStreamsInfo.NumOutStreams; j++, outStreamIndex++) if (folder.FindBindPairForOutStream(outStreamIndex) < 0) bindInfo.OutStreams.Add(outStreamIndex); } + bindInfo.InStreams.ClearAndSetSize(folder.PackStreams.Size()); for (i = 0; i < folder.PackStreams.Size(); i++) - bindInfo.InStreams.Add((UInt32)folder.PackStreams[i]); + bindInfo.InStreams[i] = (UInt32)folder.PackStreams[i]; } static bool AreCodersEqual(const NCoderMixer::CCoderStreamsInfo &a1, @@ -58,7 +62,7 @@ static bool AreBindInfoExEqual(const CBindInfoEx &a1, const CBindInfoEx &a2) { if (a1.Coders.Size() != a2.Coders.Size()) return false; - int i; + unsigned i; for (i = 0; i < a1.Coders.Size(); i++) if (!AreCodersEqual(a1.Coders[i], a2.Coders[i])) return false; @@ -90,46 +94,50 @@ HRESULT CDecoder::Decode( DECL_EXTERNAL_CODECS_LOC_VARS IInStream *inStream, UInt64 startPos, - const UInt64 *packSizes, - const CFolder &folderInfo, + const CFolders &folders, int folderIndex, ISequentialOutStream *outStream, ICompressProgressInfo *compressProgress - #ifndef _NO_CRYPTO - , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined - #endif + _7Z_DECODER_CRYPRO_VARS_DECL #if !defined(_7ZIP_ST) && !defined(_SFX) , bool mtMode, UInt32 numThreads #endif ) { - if (!folderInfo.CheckStructure()) + const UInt64 *packPositions = &folders.PackPositions[folders.FoStartPackStreamIndex[folderIndex]]; + CFolder folderInfo; + folders.ParseFolderInfo(folderIndex, folderInfo); + + if (!folderInfo.CheckStructure(folders.GetNumFolderUnpackSizes(folderIndex))) return E_NOTIMPL; + + /* + We don't need to init isEncrypted and passwordIsDefined + We must upgrade them only #ifndef _NO_CRYPTO + isEncrypted = false; passwordIsDefined = false; #endif + */ + CObjectVector< CMyComPtr<ISequentialInStream> > inStreams; - + CLockedInStream lockedInStream; lockedInStream.Init(inStream); - - for (int j = 0; j < folderInfo.PackStreams.Size(); j++) + + for (unsigned j = 0; j < folderInfo.PackStreams.Size(); j++) { - CLockedSequentialInStreamImp *lockedStreamImpSpec = new - CLockedSequentialInStreamImp; + CLockedSequentialInStreamImp *lockedStreamImpSpec = new CLockedSequentialInStreamImp; CMyComPtr<ISequentialInStream> lockedStreamImp = lockedStreamImpSpec; - lockedStreamImpSpec->Init(&lockedInStream, startPos); - startPos += packSizes[j]; - - CLimitedSequentialInStream *streamSpec = new - CLimitedSequentialInStream; + lockedStreamImpSpec->Init(&lockedInStream, startPos + packPositions[j]); + CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; CMyComPtr<ISequentialInStream> inStream = streamSpec; streamSpec->SetStream(lockedStreamImp); - streamSpec->Init(packSizes[j]); + streamSpec->Init(packPositions[j + 1] - packPositions[j]); inStreams.Add(inStream); } - - int numCoders = folderInfo.Coders.Size(); - + + unsigned numCoders = folderInfo.Coders.Size(); + CBindInfoEx bindInfo; ConvertFolderItemInfoToBindInfo(folderInfo, bindInfo); bool createNewCoders; @@ -139,10 +147,10 @@ HRESULT CDecoder::Decode( createNewCoders = !AreBindInfoExEqual(bindInfo, _bindInfoExPrev); if (createNewCoders) { - int i; + unsigned i; _decoders.Clear(); // _decoders2.Clear(); - + _mixerCoder.Release(); if (_multiThread) @@ -160,12 +168,12 @@ HRESULT CDecoder::Decode( #endif } RINOK(_mixerCoderCommon->SetBindInfo(bindInfo)); - + for (i = 0; i < numCoders; i++) { const CCoderInfo &coderInfo = folderInfo.Coders[i]; - + CMyComPtr<ICompressCoder> decoder; CMyComPtr<ICompressCoder2> decoder2; RINOK(CreateCoder( @@ -178,7 +186,7 @@ HRESULT CDecoder::Decode( return E_NOTIMPL; decoderUnknown = (IUnknown *)decoder; - + if (_multiThread) _mixerCoderMTSpec->AddCoder(decoder); #ifdef _ST_MODE @@ -204,32 +212,34 @@ HRESULT CDecoder::Decode( decoderUnknown.QueryInterface(IID_ISetCompressCodecsInfo, (void **)&setCompressCodecsInfo); if (setCompressCodecsInfo) { - RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(codecsInfo)); + RINOK(setCompressCodecsInfo->SetCompressCodecsInfo(__externalCodecs->GetCodecs)); } #endif } _bindInfoExPrev = bindInfo; _bindInfoExPrevIsDefined = true; } - int i; + unsigned i; _mixerCoderCommon->ReInit(); - - UInt32 packStreamIndex = 0, unpackStreamIndex = 0; + + UInt32 packStreamIndex = 0; + UInt32 unpackStreamIndexStart = folders.FoToCoderUnpackSizes[folderIndex]; + UInt32 unpackStreamIndex = unpackStreamIndexStart; UInt32 coderIndex = 0; // UInt32 coder2Index = 0; - + for (i = 0; i < numCoders; i++) { const CCoderInfo &coderInfo = folderInfo.Coders[i]; CMyComPtr<IUnknown> &decoder = _decoders[coderIndex]; - + { CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties; decoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties); if (setDecoderProperties) { const CByteBuffer &props = coderInfo.Props; - size_t size = props.GetCapacity(); + size_t size = props.Size(); if (size > 0xFFFFFFFF) return E_NOTIMPL; // if (size > 0) @@ -257,56 +267,55 @@ HRESULT CDecoder::Decode( decoder.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword); if (cryptoSetPassword) { - if (getTextPassword == 0) - return E_FAIL; + isEncrypted = true; + if (!getTextPassword) + return E_NOTIMPL; CMyComBSTR passwordBSTR; RINOK(getTextPassword->CryptoGetTextPassword(&passwordBSTR)); - CByteBuffer buffer; passwordIsDefined = true; - const UString password(passwordBSTR); - const UInt32 sizeInBytes = password.Length() * 2; - buffer.SetCapacity(sizeInBytes); - for (int i = 0; i < password.Length(); i++) + size_t len = 0; + if (passwordBSTR) + len = MyStringLen((BSTR)passwordBSTR); + CByteBuffer buffer(len * 2); + for (size_t i = 0; i < len; i++) { - wchar_t c = password[i]; + wchar_t c = passwordBSTR[i]; ((Byte *)buffer)[i * 2] = (Byte)c; ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8); } - RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, sizeInBytes)); + RINOK(cryptoSetPassword->CryptoSetPassword((const Byte *)buffer, (UInt32)buffer.Size())); } } #endif coderIndex++; - + UInt32 numInStreams = (UInt32)coderInfo.NumInStreams; UInt32 numOutStreams = (UInt32)coderInfo.NumOutStreams; - CRecordVector<const UInt64 *> packSizesPointers; - CRecordVector<const UInt64 *> unpackSizesPointers; - packSizesPointers.Reserve(numInStreams); - unpackSizesPointers.Reserve(numOutStreams); + CObjArray<UInt64> packSizes(numInStreams); + CObjArray<const UInt64 *> packSizesPointers(numInStreams); + CObjArray<const UInt64 *> unpackSizesPointers(numOutStreams); UInt32 j; + for (j = 0; j < numOutStreams; j++, unpackStreamIndex++) - unpackSizesPointers.Add(&folderInfo.UnpackSizes[unpackStreamIndex]); - + unpackSizesPointers[j] = &folders.CoderUnpackSizes[unpackStreamIndex]; + for (j = 0; j < numInStreams; j++, packStreamIndex++) { int bindPairIndex = folderInfo.FindBindPairForInStream(packStreamIndex); if (bindPairIndex >= 0) - packSizesPointers.Add( - &folderInfo.UnpackSizes[(UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex]); + packSizesPointers[j] = &folders.CoderUnpackSizes[unpackStreamIndexStart + (UInt32)folderInfo.BindPairs[bindPairIndex].OutIndex]; else { int index = folderInfo.FindPackStreamArrayIndex(packStreamIndex); if (index < 0) - return E_FAIL; - packSizesPointers.Add(&packSizes[index]); + return S_FALSE; // check it + packSizes[j] = packPositions[index + 1] - packPositions[index]; + packSizesPointers[j] = &packSizes[j]; } } - - _mixerCoderCommon->SetCoderInfo(i, - &packSizesPointers.Front(), - &unpackSizesPointers.Front()); + + _mixerCoderCommon->SetCoderInfo(i, packSizesPointers, unpackSizesPointers); } UInt32 mainCoder, temp; bindInfo.FindOutStream(bindInfo.OutStreams[0], mainCoder, temp); @@ -317,16 +326,18 @@ HRESULT CDecoder::Decode( else _mixerCoderSTSpec->SetProgressCoderIndex(mainCoder);; */ - + if (numCoders == 0) return 0; - CRecordVector<ISequentialInStream *> inStreamPointers; - inStreamPointers.Reserve(inStreams.Size()); - for (i = 0; i < inStreams.Size(); i++) - inStreamPointers.Add(inStreams[i]); + unsigned num = inStreams.Size(); + CObjArray<ISequentialInStream *> inStreamPointers(num); + for (i = 0; i < num; i++) + inStreamPointers[i] = inStreams[i]; ISequentialOutStream *outStreamPointer = outStream; - return _mixerCoder->Code(&inStreamPointers.Front(), NULL, - inStreams.Size(), &outStreamPointer, NULL, 1, compressProgress); + return _mixerCoder->Code( + inStreamPointers, NULL, num, + &outStreamPointer, NULL, 1, + compressProgress); } }} |