This commit is contained in:
Igor Pavlov
2014-11-23 00:00:00 +00:00
committed by Kornel Lesiński
parent 83f8ddcc5b
commit f08f4dcc3c
1158 changed files with 76451 additions and 35082 deletions

123
CPP/7zip/Archive/7z/7zDecode.cpp Executable file → Normal file
View File

@@ -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,45 +94,49 @@ 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);
@@ -139,7 +147,7 @@ HRESULT CDecoder::Decode(
createNewCoders = !AreBindInfoExEqual(bindInfo, _bindInfoExPrev);
if (createNewCoders)
{
int i;
unsigned i;
_decoders.Clear();
// _decoders2.Clear();
@@ -204,17 +212,19 @@ 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;
@@ -229,7 +239,7 @@ HRESULT CDecoder::Decode(
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,22 +267,23 @@ 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
@@ -281,32 +292,30 @@ HRESULT CDecoder::Decode(
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);
@@ -320,13 +329,15 @@ HRESULT CDecoder::Decode(
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);
}
}}