4.53 beta

This commit is contained in:
Igor Pavlov
2007-08-27 00:00:00 +00:00
committed by Kornel Lesiński
parent 33ccab7e72
commit 051769bbc5
360 changed files with 4658 additions and 5167 deletions

View File

@@ -13,7 +13,9 @@
#include "../../Common/CreateCoder.h"
#include "../../Common/FilterCoder.h"
static UInt64 k_AES = 0x06F10701;
static const UInt64 k_AES = 0x06F10701;
static const UInt64 k_BCJ = 0x03030103;
static const UInt64 k_BCJ2 = 0x0303011B;
namespace NArchive {
namespace N7z {
@@ -59,7 +61,8 @@ HRESULT CEncoder::CreateMixerCoder(
{
const CMethodFull &methodFull = _options.Methods[i];
_codersInfo.Add(CCoderInfo());
// CCoderInfo &encodingInfo = _codersInfo.Back();
CCoderInfo &encodingInfo = _codersInfo.Back();
encodingInfo.MethodID = methodFull.Id;
CMyComPtr<ICompressCoder> encoder;
CMyComPtr<ICompressCoder2> encoder2;
@@ -176,7 +179,7 @@ HRESULT CEncoder::Encode(
return E_FAIL;
UInt32 mainCoderIndex, mainStreamIndex;
_bindInfo.FindInStream(_bindInfo.InStreams[0], mainCoderIndex, mainStreamIndex);
_mixerCoderSpec->SetProgressCoderIndex(mainCoderIndex);
if (inStreamSize != NULL)
{
CRecordVector<const UInt64 *> sizePointers;
@@ -234,6 +237,17 @@ HRESULT CEncoder::Encode(
memmove(encodingInfo.Properties, outStreamSpec->GetBuffer(), size);
}
}
UInt32 progressIndex = mainCoderIndex;
for (i = 0; i < _codersInfo.Size(); i++)
{
const CCoderInfo &e = _codersInfo[i];
if ((e.MethodID == k_BCJ || e.MethodID == k_BCJ2) && i + 1 < _codersInfo.Size())
progressIndex = i + 1;
}
_mixerCoderSpec->SetProgressCoderIndex(progressIndex);
RINOK(_mixerCoder->Code(&inStreamPointers.Front(), NULL, 1,
&outStreamPointers.Front(), NULL, outStreamPointers.Size(), compressProgress));

View File

@@ -149,16 +149,27 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
);
// CDecoder1 decoder;
UInt64 currentImportantTotalUnPacked = 0;
UInt64 currentTotalPacked = 0;
UInt64 currentTotalUnPacked = 0;
UInt64 totalFolderUnPacked;
UInt64 totalFolderPacked;
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, false);
for(int i = 0; i < extractFolderInfoVector.Size(); i++,
currentImportantTotalUnPacked += totalFolderUnPacked)
currentTotalUnPacked += totalFolderUnPacked,
currentTotalPacked += totalFolderPacked)
{
lps->OutSize = currentTotalUnPacked;
lps->InSize = currentTotalPacked;
RINOK(lps->SetCur());
const CExtractFolderInfo &efi = extractFolderInfoVector[i];
totalFolderUnPacked = efi.UnPackSize;
RINOK(extractCallback->SetCompleted(&currentImportantTotalUnPacked));
totalFolderPacked = 0;
CFolderOutStream *folderOutStream = new CFolderOutStream;
CMyComPtr<ISequentialOutStream> outStream(folderOutStream);
@@ -194,14 +205,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
CNum folderIndex = efi.FolderIndex;
const CFolder &folderInfo = database.Folders[folderIndex];
CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = localProgressSpec;
localProgressSpec->Init(extractCallback, false);
CLocalCompressProgressInfo *localCompressProgressSpec =
new CLocalCompressProgressInfo;
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
localCompressProgressSpec->Init(progress, NULL, &currentImportantTotalUnPacked);
totalFolderPacked = _database.GetFolderFullPackSize(folderIndex);
CNum packStreamIndex = database.FolderStartPackStreamIndex[folderIndex];
UInt64 folderStartPackPos = database.GetFolderStreamPos(folderIndex, 0);
@@ -225,7 +229,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
&database.PackSizes[packStreamIndex],
folderInfo,
outStream,
compressProgress
progress
#ifndef _NO_CRYPTO
, getTextPassword
#endif

View File

@@ -53,14 +53,10 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
return S_OK;
}
STDMETHODIMP CHandler::GetArchiveProperty(PROPID /* propID */, PROPVARIANT *value)
{
value->vt = VT_EMPTY;
return S_OK;
}
#ifdef _SFX
IMP_IInArchive_ArcProps_NO
STDMETHODIMP CHandler::GetNumberOfProperties(UInt32 * /* numProperties */)
{
return E_NOTIMPL;
@@ -72,27 +68,64 @@ STDMETHODIMP CHandler::GetPropertyInfo(UInt32 /* index */,
return E_NOTIMPL;
}
#else
STATPROPSTG kArcProps[] =
{
{ NULL, kpidMethod, VT_BSTR},
{ NULL, kpidSolid, VT_BOOL},
{ NULL, kpidNumBlocks, VT_UI4}
};
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop;
switch(propID)
{
case kpidMethod:
{
UString resString;
CRecordVector<UInt64> ids;
int i;
for (i = 0; i < _database.Folders.Size(); i++)
{
const CFolder &f = _database.Folders[i];
for (int j = f.Coders.Size() - 1; j >= 0; j--)
ids.AddToUniqueSorted(f.Coders[j].MethodID);
}
for (i = 0; i < ids.Size(); i++)
{
UInt64 id = ids[i];
UString methodName;
/* bool methodIsKnown = */ FindMethod(EXTERNAL_CODECS_VARS id, methodName);
if (methodName.IsEmpty())
methodName = ConvertMethodIdToString(id);
if (!resString.IsEmpty())
resString += L' ';
resString += methodName;
}
prop = resString;
break;
}
case kpidSolid: prop = _database.IsSolid(); break;
case kpidNumBlocks: prop = (UInt32)_database.Folders.Size(); break;
}
prop.Detach(value);
return S_OK;
COM_TRY_END
}
IMP_IInArchive_ArcProps
#endif
STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties)
{
*numProperties = 0;
return S_OK;
}
STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */,
BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */)
{
return E_NOTIMPL;
}
static void MySetFileTime(bool timeDefined, FILETIME unixTime,
NWindows::NCOM::CPropVariant &propVariant)
static void MySetFileTime(bool timeDefined, FILETIME unixTime, NWindows::NCOM::CPropVariant &prop)
{
if (timeDefined)
propVariant = unixTime;
prop = unixTime;
}
#ifndef _SFX
@@ -171,7 +204,7 @@ bool CHandler::IsEncrypted(UInt32 index2) const
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NWindows::NCOM::CPropVariant propVariant;
NWindows::NCOM::CPropVariant prop;
/*
const CRef2 &ref2 = _refs[index];
@@ -196,68 +229,68 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
case kpidPath:
{
if (!item.Name.IsEmpty())
propVariant = NItemName::GetOSName(item.Name);
prop = NItemName::GetOSName(item.Name);
break;
}
case kpidIsFolder:
propVariant = item.IsDirectory;
prop = item.IsDirectory;
break;
case kpidSize:
{
propVariant = item.UnPackSize;
// propVariant = ref2.UnPackSize;
prop = item.UnPackSize;
// prop = ref2.UnPackSize;
break;
}
case kpidPosition:
{
/*
if (ref2.Refs.Size() > 1)
propVariant = ref2.StartPos;
prop = ref2.StartPos;
else
*/
if (item.IsStartPosDefined)
propVariant = item.StartPos;
prop = item.StartPos;
break;
}
case kpidPackedSize:
{
// propVariant = ref2.PackSize;
// prop = ref2.PackSize;
{
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
if (folderIndex != kNumNoIndex)
{
if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2)
propVariant = _database.GetFolderFullPackSize(folderIndex);
prop = _database.GetFolderFullPackSize(folderIndex);
/*
else
propVariant = UInt64(0);
prop = (UInt64)0;
*/
}
else
propVariant = UInt64(0);
prop = (UInt64)0;
}
break;
}
case kpidLastAccessTime:
MySetFileTime(item.IsLastAccessTimeDefined, item.LastAccessTime, propVariant);
MySetFileTime(item.IsLastAccessTimeDefined, item.LastAccessTime, prop);
break;
case kpidCreationTime:
MySetFileTime(item.IsCreationTimeDefined, item.CreationTime, propVariant);
MySetFileTime(item.IsCreationTimeDefined, item.CreationTime, prop);
break;
case kpidLastWriteTime:
MySetFileTime(item.IsLastWriteTimeDefined, item.LastWriteTime, propVariant);
MySetFileTime(item.IsLastWriteTimeDefined, item.LastWriteTime, prop);
break;
case kpidAttributes:
if (item.AreAttributesDefined)
propVariant = item.Attributes;
prop = item.Attributes;
break;
case kpidCRC:
if (item.IsFileCRCDefined)
propVariant = item.FileCRC;
prop = item.FileCRC;
break;
case kpidEncrypted:
{
propVariant = IsEncrypted(index2);
prop = IsEncrypted(index2);
break;
}
#ifndef _SFX
@@ -357,7 +390,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
}
}
}
propVariant = methodsString;
prop = methodsString;
}
}
break;
@@ -365,7 +398,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
{
CNum folderIndex = _database.FileIndexToFolderIndexMap[index2];
if (folderIndex != kNumNoIndex)
propVariant = (UInt32)folderIndex;
prop = (UInt32)folderIndex;
}
break;
case kpidPackedSize0:
@@ -381,21 +414,21 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *va
if (_database.FolderStartFileIndex[folderIndex] == (CNum)index2 &&
folderInfo.PackStreams.Size() > (int)(propID - kpidPackedSize0))
{
propVariant = _database.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0);
prop = _database.GetFolderPackStreamSize(folderIndex, propID - kpidPackedSize0);
}
else
propVariant = UInt64(0);
prop = (UInt64)0;
}
else
propVariant = UInt64(0);
prop = (UInt64)0;
}
break;
#endif
case kpidIsAnti:
propVariant = item.IsAnti;
prop = item.IsAnti;
break;
}
propVariant.Detach(value);
prop.Detach(value);
return S_OK;
COM_TRY_END
}
@@ -522,11 +555,11 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
{
UString baseName;
{
NCOM::CPropVariant propVariant;
RINOK(openVolumeCallback->GetProperty(kpidName, &propVariant));
if (propVariant.vt != VT_BSTR)
NCOM::CPropVariant prop;
RINOK(openVolumeCallback->GetProperty(kpidName, &prop));
if (prop.vt != VT_BSTR)
break;
baseName = propVariant.bstrVal;
baseName = prop.bstrVal;
}
seqName.InitName(baseName);
}

View File

@@ -170,6 +170,13 @@ struct CArchiveDatabase
NumUnPackStreamsVector.IsEmpty() &&
Files.IsEmpty());
}
bool IsSolid() const
{
for (int i = 0; i < NumUnPackStreamsVector.Size(); i++)
if (NumUnPackStreamsVector[i] > 1)
return true;
return false;
}
};
}}

View File

@@ -37,18 +37,14 @@ CPropMap kPropMap[] =
{ NID::kWinAttributes, NULL, kpidAttributes, VT_UI4},
{ NID::kStartPos, NULL, kpidPosition, VT_UI4},
{ NID::kCRC, NULL, kpidCRC, VT_UI4},
{ NID::kAnti, L"Anti", kpidIsAnti, VT_BOOL},
{ NID::kAnti, NULL, kpidIsAnti, VT_BOOL},
// { 97, NULL, kpidSolid, VT_BOOL},
#ifndef _SFX
{ 98, NULL, kpidMethod, VT_BSTR},
{ 99, L"Block", kpidBlock, VT_UI4}
{ 99, NULL, kpidBlock, VT_UI4}
#endif
// { L"ID", kpidID, VT_BSTR},
// { L"UnPack Version", kpidUnPackVersion, VT_UI1},
// { L"Host OS", kpidHostOS, VT_BSTR}
};
static const int kPropMapSize = sizeof(kPropMap) / sizeof(kPropMap[0]);

View File

@@ -22,52 +22,19 @@ static const UInt32 kDictionaryForBCJ2_LZMA = 1 << 20;
static const UInt32 kAlgorithmForBCJ2_LZMA = 1;
static const UInt32 kNumFastBytesForBCJ2_LZMA = 64;
static HRESULT CopyBlock(ISequentialInStream *inStream,
ISequentialOutStream *outStream, ICompressProgressInfo *progress)
static HRESULT WriteRange(IInStream *inStream, ISequentialOutStream *outStream,
UInt64 position, UInt64 size, ICompressProgressInfo *progress)
{
CMyComPtr<ICompressCoder> copyCoder = new NCompress::CCopyCoder;
return copyCoder->Code(inStream, outStream, NULL, NULL, progress);
}
static HRESULT WriteRange(
ISequentialInStream *inStream,
ISequentialOutStream *outStream,
UInt64 size,
IProgress *progress,
UInt64 &currentComplexity)
{
CLimitedSequentialInStream *streamSpec = new
CLimitedSequentialInStream;
RINOK(inStream->Seek(position, STREAM_SEEK_SET, 0));
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<CLimitedSequentialInStream> inStreamLimited(streamSpec);
streamSpec->SetStream(inStream);
streamSpec->Init(size);
CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
localProgressSpec->Init(progress, true);
CLocalCompressProgressInfo *localCompressProgressSpec =
new CLocalCompressProgressInfo;
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
localCompressProgressSpec->Init(localProgress, &currentComplexity, &currentComplexity);
HRESULT result = CopyBlock(inStreamLimited, outStream, compressProgress);
currentComplexity += size;
return result;
}
static HRESULT WriteRange(IInStream *inStream,
ISequentialOutStream *outStream,
UInt64 position,
UInt64 size,
IProgress *progress,
UInt64 &currentComplexity)
{
inStream->Seek(position, STREAM_SEEK_SET, 0);
return WriteRange(inStream, outStream,
size, progress, currentComplexity);
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
RINOK(copyCoder->Code(inStreamLimited, outStream, NULL, NULL, progress));
return (copyCoderSpec->TotalSize == size ? S_OK : E_FAIL);
}
static int GetReverseSlashPos(const UString &name)
@@ -94,14 +61,6 @@ UString CUpdateItem::GetExtension() const
return Name.Mid(GetExtensionPos());
}
/*
struct CFolderRef
{
const CArchiveDatabaseEx *Database;
int FolderIndex;
};
*/
#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
static int CompareBuffers(const CByteBuffer &a1, const CByteBuffer &a2)
@@ -522,16 +481,10 @@ static HRESULT Update2(
return E_NOTIMPL;
*/
UInt64 startBlockSize = database != 0 ?
database->ArchiveInfo.StartPosition: 0;
UInt64 startBlockSize = database != 0 ? database->ArchiveInfo.StartPosition: 0;
if (startBlockSize > 0 && !options.RemoveSfxBlock)
{
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> limitedStream(streamSpec);
RINOK(inStream->Seek(0, STREAM_SEEK_SET, NULL));
streamSpec->SetStream(inStream);
streamSpec->Init(startBlockSize);
RINOK(CopyBlock(limitedStream, seqOutStream, NULL));
RINOK(WriteRange(inStream, seqOutStream, 0, startBlockSize, NULL));
}
CRecordVector<int> fileIndexToUpdateIndexMap;
@@ -607,6 +560,11 @@ static HRESULT Update2(
complexity = 0;
RINOK(updateCallback->SetCompleted(&complexity));
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(updateCallback, true);
/////////////////////////////////////////
// Write Copy Items
@@ -614,10 +572,11 @@ static HRESULT Update2(
{
int folderIndex = folderRefs[i];
lps->ProgressOffset = complexity;
UInt64 packSize = database->GetFolderFullPackSize(folderIndex);
RINOK(WriteRange(inStream, archive.SeqStream,
database->GetFolderStreamPos(folderIndex, 0),
database->GetFolderFullPackSize(folderIndex),
updateCallback, complexity));
database->GetFolderStreamPos(folderIndex, 0), packSize, progress));
complexity += packSize;
const CFolder &folder = database->Folders[folderIndex];
CNum startIndex = database->FolderStartPackStreamIndex[folderIndex];
@@ -736,18 +695,17 @@ static HRESULT Update2(
inStreamSpec->Init(updateCallback, &indices[i], numSubFiles);
CFolder folderItem;
CLocalProgress *localProgressSpec = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> localProgress = localProgressSpec;
localProgressSpec->Init(updateCallback, true);
CLocalCompressProgressInfo *localCompressProgressSpec = new CLocalCompressProgressInfo;
CMyComPtr<ICompressProgressInfo> compressProgress = localCompressProgressSpec;
localCompressProgressSpec->Init(localProgress, &complexity, NULL);
int startPackIndex = newDatabase.PackSizes.Size();
RINOK(encoder.Encode(
EXTERNAL_CODECS_LOC_VARS
solidInStream, NULL, &inSizeForReduce, folderItem,
archive.SeqStream, newDatabase.PackSizes, compressProgress));
archive.SeqStream, newDatabase.PackSizes, progress));
for (; startPackIndex < newDatabase.PackSizes.Size(); startPackIndex++)
lps->OutSize += newDatabase.PackSizes[startPackIndex];
lps->InSize += folderItem.GetUnPackSize();
// for()
// newDatabase.PackCRCsDefined.Add(false);
// newDatabase.PackCRCs.Add(0);
@@ -783,7 +741,6 @@ static HRESULT Update2(
file.IsFileCRCDefined = true;
file.HasStream = true;
numUnPackStreams++;
complexity += file.UnPackSize;
}
else
{
@@ -935,8 +892,7 @@ HRESULT UpdateVolume(
CMyComPtr<ISequentialInStream> inCrcStream = inCrcStreamSpec;
inCrcStreamSpec->Init(fileStream);
RINOK(WriteRange(inCrcStream, volumeStream, pureSize,
updateCallback, complexity));
RINOK(WriteRange(inCrcStream, volumeStream, pureSize, updateCallback, complexity));
file.UnPackSize = inCrcStreamSpec->GetSize();
if (file.UnPackSize == 0)
break;