This commit is contained in:
Igor Pavlov
2005-05-30 00:00:00 +00:00
committed by Kornel Lesiński
parent 8c1b5c7b7e
commit 3c510ba80b
926 changed files with 40559 additions and 23519 deletions

View File

@@ -41,41 +41,57 @@ static CMethodID k_Copy = { { 0x0 }, 1 };
#endif
#ifdef COMPRESS_DEFLATE
#ifndef COMPRESS_DEFLATE_ENCODER
#define COMPRESS_DEFLATE_ENCODER
#endif
#endif
#ifdef COMPRESS_DEFLATE_ENCODER
static CMethodID k_Deflate = { { 0x4, 0x1, 0x8 }, 3 };
#endif
#ifdef COMPRESS_BZIP2
#ifndef COMPRESS_BZIP2_ENCODER
#define COMPRESS_BZIP2_ENCODER
#endif
#endif
#ifdef COMPRESS_BZIP2_ENCODER
static CMethodID k_BZip2 = { { 0x4, 0x2, 0x2 }, 3 };
#endif
const wchar_t *kCopyMethod = L"Copy";
const wchar_t *kLZMAMethodName = L"LZMA";
const wchar_t *kBZip2MethodName = L"BZip2";
const UINT32 kAlgorithmForX7 = 2;
const UINT32 kDicSizeForX7 = 1 << 23;
const UINT32 kFastBytesForX7 = 64;
const UInt32 kAlgorithmForX7 = 2;
const UInt32 kDicSizeForX7 = 1 << 23;
const UInt32 kFastBytesForX7 = 64;
const UINT32 kAlgorithmForX9 = 2;
const UINT32 kDicSizeForX9 = 1 << 25;
const UINT32 kFastBytesForX9 = 64;
const UInt32 kAlgorithmForX9 = 2;
const UInt32 kDicSizeForX9 = 1 << 25;
const UInt32 kFastBytesForX9 = 64;
static const wchar_t *kMatchFinderForX9 = L"BT4b";
const UINT32 kAlgorithmForFast = 0;
const UINT32 kDicSizeForFast = 1 << 15;
const UInt32 kAlgorithmForFast = 0;
const UInt32 kDicSizeForFast = 1 << 15;
static const wchar_t *kMatchFinderForFast = L"HC3";
const wchar_t *kDefaultMethodName = kLZMAMethodName;
static const wchar_t *kMatchFinderForHeaders = L"BT2";
static const UINT32 kDictionaryForHeaders = 1 << 20;
static const UINT32 kNumFastBytesForHeaders = 254;
static const UInt32 kDictionaryForHeaders = 1 << 20;
static const UInt32 kNumFastBytesForHeaders = 254;
static bool IsLZMAMethod(const UString &methodName)
{ return (methodName.CompareNoCase(kLZMAMethodName) == 0); }
static bool IsLZMethod(const UString &methodName)
{ return IsLZMAMethod(methodName); }
STDMETHODIMP CHandler::GetFileTimeType(UINT32 *type)
static bool IsBZip2Method(const UString &methodName)
{ return (methodName.CompareNoCase(kBZip2MethodName) == 0); }
STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
{
*type = NFileTimeType::kWindows;
return S_OK;
@@ -94,7 +110,7 @@ HRESULT CHandler::SetPassword(CCompressionMethodMode &methodMode,
if (getTextPassword)
{
CMyComBSTR password;
INT32 passwordIsDefined;
Int32 passwordIsDefined;
RINOK(getTextPassword->CryptoGetTextPassword2(
&passwordIsDefined, &password));
if (methodMode.PasswordIsDefined = IntToBool(passwordIsDefined))
@@ -105,52 +121,6 @@ HRESULT CHandler::SetPassword(CCompressionMethodMode &methodMode,
return S_OK;
}
// it's work only for non-solid archives
/*
STDMETHODIMP CHandler::DeleteItems(IOutStream *outStream,
const UINT32* indices, UINT32 numItems, IUpdateCallback *updateCallback)
{
COM_TRY_BEGIN
CRecordVector<bool> compressStatuses;
CRecordVector<UINT32> copyIndices;
int index = 0;
int i;
for(i = 0; i < _database.NumUnPackStreamsVector.Size(); i++)
{
if (_database.NumUnPackStreamsVector[i] != 1)
return E_NOTIMPL;
}
for(i = 0; i < _database.Files.Size(); i++)
{
// bool copyMode = true;
if(index < numItems && i == indices[index])
index++;
else
{
compressStatuses.Add(false);
copyIndices.Add(i);
}
}
CCompressionMethodMode methodMode, headerMethod;
RINOK(SetCompressionMethod(methodMode, headerMethod));
methodMode.MultiThread = _multiThread;
methodMode.MultiThreadMult = _multiThreadMult;
headerMethod.MultiThread = false;
bool useAdditionalHeaderStreams = true;
bool compressMainHeader = false;
// headerMethod.MultiThreadMult = _multiThreadMult;
return UpdateMain(_database, compressStatuses,
CObjectVector<CUpdateItem>(), copyIndices,
outStream, _inStream, &_database.ArchiveInfo,
NULL, (_compressHeaders ? &headerMethod: 0),
useAdditionalHeaderStreams, compressMainHeader,
updateCallback, false, _removeSfxBlock);
COM_TRY_END
}
*/
struct CNameToPropID
{
PROPID PropID;
@@ -184,10 +154,10 @@ bool ConvertProperty(PROPVARIANT srcProp, VARTYPE varType,
{
if(srcProp.vt == VT_UI4)
{
UINT32 value = srcProp.ulVal;
UInt32 value = srcProp.ulVal;
if (value > 0xFF)
return false;
destProp = BYTE(value);
destProp = Byte(value);
return true;
}
}
@@ -235,13 +205,13 @@ HRESULT CHandler::SetCompressionMethod(
{
CProperty property;
property.PropID = NCoderPropID::kNumFastBytes;
property.Value = UINT32(kNumFastBytesForHeaders);
property.Value = UInt32(kNumFastBytesForHeaders);
oneMethodInfo.CoderProperties.Add(property);
}
{
CProperty property;
property.PropID = NCoderPropID::kDictionarySize;
property.Value = UINT32(kDictionaryForHeaders);
property.Value = UInt32(kDictionaryForHeaders);
oneMethodInfo.CoderProperties.Add(property);
}
headerMethodInfoVector.Add(oneMethodInfo);
@@ -309,6 +279,13 @@ HRESULT CHandler::SetCompressionMethod(
NCoderPropID::kMultiThread, true);
}
}
else if (IsBZip2Method(oneMethodInfo.MethodName))
{
SetOneMethodProp(oneMethodInfo,
NCoderPropID::kNumPasses, _defaultBZip2Passes);
}
CMethodFull methodFull;
methodFull.NumInStreams = 1;
methodFull.NumOutStreams = 1;
@@ -349,7 +326,7 @@ HRESULT CHandler::SetCompressionMethod(
}
#endif
#ifdef COMPRESS_DEFLATE
#ifdef COMPRESS_DEFLATE_ENCODER
if (oneMethodInfo.MethodName.CompareNoCase(L"Deflate") == 0)
{
defined = true;
@@ -357,7 +334,7 @@ HRESULT CHandler::SetCompressionMethod(
}
#endif
#ifdef COMPRESS_BZIP2
#ifdef COMPRESS_BZIP2_ENCODER
if (oneMethodInfo.MethodName.CompareNoCase(L"BZip2") == 0)
{
defined = true;
@@ -410,24 +387,39 @@ HRESULT CHandler::SetCompressionMethod(
return S_OK;
}
STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems,
STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
IArchiveUpdateCallback *updateCallback)
{
COM_TRY_BEGIN
const CArchiveDatabaseEx *database = 0;
#ifdef _7Z_VOL
if(_volumes.Size() > 1)
return E_FAIL;
const CVolume *volume = 0;
if (_volumes.Size() == 1)
{
volume = &_volumes.Front();
database = &volume->Database;
}
#else
if (_inStream != 0)
database = &_database;
#endif
// CRecordVector<bool> compressStatuses;
CObjectVector<CUpdateItem> updateItems;
// CRecordVector<UINT32> copyIndices;
// CRecordVector<UInt32> copyIndices;
// CMyComPtr<IUpdateCallback2> updateCallback2;
// updateCallback->QueryInterface(&updateCallback2);
int index = 0;
for(int i = 0; i < numItems; i++)
for(UInt32 i = 0; i < numItems; i++)
{
INT32 newData;
INT32 newProperties;
UINT32 indexInArchive;
Int32 newData;
Int32 newProperties;
UInt32 indexInArchive;
if (!updateCallback)
return E_FAIL;
RINOK(updateCallback->GetUpdateItemInfo(i,
@@ -442,7 +434,7 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems,
if (updateItem.IndexInArchive != -1)
{
const CFileItem &fileItem = _database.Files[updateItem.IndexInArchive];
const CFileItem &fileItem = database->Files[updateItem.IndexInArchive];
updateItem.Name = fileItem.Name;
updateItem.IsDirectory = fileItem.IsDirectory;
updateItem.Size = fileItem.UnPackSize;
@@ -550,7 +542,7 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems,
RINOK(updateCallback->GetProperty(i, kpidSize, &propVariant));
if (propVariant.vt != VT_UI8)
return E_INVALIDARG;
updateItem.Size = *(const UINT64 *)(&propVariant.uhVal);
updateItem.Size = (UInt64)propVariant.uhVal.QuadPart;
if (updateItem.Size != 0 && updateItem.IsAnti)
return E_INVALIDARG;
}
@@ -605,40 +597,43 @@ STDMETHODIMP CHandler::UpdateItems(IOutStream *outStream, UINT32 numItems,
if (numItems < 2)
compressMainHeader = false;
CInArchiveInfo *inArchiveInfo;
if (!_inStream)
inArchiveInfo = 0;
else
inArchiveInfo = &_database.ArchiveInfo;
return Update(_database,
// compressStatuses,
updateItems,
// copyIndices,
outStream, _inStream, inArchiveInfo,
methodMode,
(_compressHeaders ||
(methodMode.PasswordIsDefined && _encryptHeaders)) ?
&headerMethod : 0,
_level != 0 && _autoFilter, // useFilters
_level >= 8, // maxFilter
useAdditionalHeaderStreams, compressMainHeader,
updateCallback, _numSolidFiles, _numSolidBytes, _solidExtension,
_removeSfxBlock);
CUpdateOptions options;
options.Method = &methodMode;
options.HeaderMethod = (_compressHeaders ||
(methodMode.PasswordIsDefined && _encryptHeaders)) ?
&headerMethod : 0;
options.UseFilters = _level != 0 && _autoFilter;
options.MaxFilter = _level >= 8;
options.UseAdditionalHeaderStreams = useAdditionalHeaderStreams;
options.CompressMainHeader = compressMainHeader;
options.NumSolidFiles = _numSolidFiles;
options.NumSolidBytes = _numSolidBytes;
options.SolidExtension = _solidExtension;
options.RemoveSfxBlock = _removeSfxBlock;
options.VolumeMode = _volumeMode;
return Update(
#ifdef _7Z_VOL
volume ? volume->Stream: 0,
volume ? database: 0,
#else
_inStream,
database,
#endif
updateItems, outStream, updateCallback, options);
COM_TRY_END
}
static int ParseStringToUINT32(const UString &srcString, UINT32 &number)
static int ParseStringToUInt32(const UString &srcString, UInt32 &number)
{
const wchar_t *start = srcString;
const wchar_t *end;
UINT64 number64 = ConvertStringToUINT64(start, &end);
if (number64 >= (UINT64(1) << 32))
UInt64 number64 = ConvertStringToUInt64(start, &end);
if (number64 > 0xFFFFFFFF)
{
number = 0;
return 0;
}
number = number64;
number = (UInt32)number64;
return end - start;
}
@@ -647,14 +642,14 @@ static const char kByteSymbol = 'B';
static const char kKiloByteSymbol = 'K';
static const char kMegaByteSymbol = 'M';
HRESULT ParseDictionaryValues(const UString &srcStringSpec, UINT32 &dicSize)
HRESULT ParseDictionaryValues(const UString &srcStringSpec, UInt32 &dicSize)
{
UString srcString = srcStringSpec;
srcString.MakeUpper();
const wchar_t *start = srcString;
const wchar_t *end;
UINT64 number = ConvertStringToUINT64(start, &end);
UInt64 number = ConvertStringToUInt64(start, &end);
int numDigits = end - start;
if (numDigits == 0 || srcString.Length() > numDigits + 1)
return E_INVALIDARG;
@@ -662,25 +657,25 @@ HRESULT ParseDictionaryValues(const UString &srcStringSpec, UINT32 &dicSize)
{
if (number >= kLogarithmicSizeLimit)
return E_INVALIDARG;
dicSize = (UINT32)1 << number;
dicSize = (UInt32)1 << (int)number;
return S_OK;
}
switch (srcString[numDigits])
{
case kByteSymbol:
if (number >= ((UINT64)1 << kLogarithmicSizeLimit))
if (number >= ((UInt64)1 << kLogarithmicSizeLimit))
return E_INVALIDARG;
dicSize = (UINT32)number;
dicSize = (UInt32)number;
break;
case kKiloByteSymbol:
if (number >= ((UINT64)1 << (kLogarithmicSizeLimit - 10)))
if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 10)))
return E_INVALIDARG;
dicSize = UINT32(number << 10);
dicSize = UInt32(number << 10);
break;
case kMegaByteSymbol:
if (number >= ((UINT64)1 << (kLogarithmicSizeLimit - 20)))
if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 20)))
return E_INVALIDARG;
dicSize = UINT32(number << 20);
dicSize = UInt32(number << 20);
break;
default:
return E_INVALIDARG;
@@ -724,7 +719,7 @@ static HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value)
}
/*
static HRESULT SetComplexProperty(bool &boolStatus, UINT32 &number,
static HRESULT SetComplexProperty(bool &boolStatus, UInt32 &number,
const PROPVARIANT &value)
{
switch(value.vt)
@@ -746,17 +741,17 @@ static HRESULT SetComplexProperty(bool &boolStatus, UINT32 &number,
}
*/
static HRESULT GetBindInfoPart(UString &srcString, UINT32 &coder, UINT32 &stream)
static HRESULT GetBindInfoPart(UString &srcString, UInt32 &coder, UInt32 &stream)
{
stream = 0;
int index = ParseStringToUINT32(srcString, coder);
int index = ParseStringToUInt32(srcString, coder);
if (index == 0)
return E_INVALIDARG;
srcString.Delete(0, index);
if (srcString[0] == 'S')
{
srcString.Delete(0);
int index = ParseStringToUINT32(srcString, stream);
int index = ParseStringToUInt32(srcString, stream);
if (index == 0)
return E_INVALIDARG;
srcString.Delete(0, index);
@@ -824,7 +819,7 @@ HRESULT CHandler::SetParam(COneMethodInfo &oneMethodInfo, const UString &name, c
CProperty property;
if (name.CompareNoCase(L"D") == 0 || name.CompareNoCase(L"MEM") == 0)
{
UINT32 dicSize;
UInt32 dicSize;
RINOK(ParseDictionaryValues(value, dicSize));
if (name.CompareNoCase(L"D") == 0)
property.PropID = NCoderPropID::kDictionarySize;
@@ -849,8 +844,8 @@ HRESULT CHandler::SetParam(COneMethodInfo &oneMethodInfo, const UString &name, c
propValue = value;
else
{
UINT32 number;
if (ParseStringToUINT32(value, number) == value.Length())
UInt32 number;
if (ParseStringToUInt32(value, number) == value.Length())
propValue = number;
else
propValue = value;
@@ -898,7 +893,7 @@ HRESULT CHandler::SetSolidSettings(const UString &s)
{
const wchar_t *start = ((const wchar_t *)s2) + i;
const wchar_t *end;
UINT64 v = ConvertStringToUINT64(start, &end);
UInt64 v = ConvertStringToUInt64(start, &end);
if (start == end)
{
if (s2[i++] != 'E')
@@ -954,14 +949,14 @@ HRESULT CHandler::SetSolidSettings(const PROPVARIANT &value)
}
}
STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *values, INT32 numProperties)
STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, Int32 numProperties)
{
UINT codePage = GetCurrentFileCodePage();
COM_TRY_BEGIN
_methods.Clear();
_binds.Clear();
Init();
int minNumber = 0;
UInt32 minNumber = 0;
for (int i = 0; i < numProperties; i++)
{
@@ -986,7 +981,7 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value
{
if(!name.IsEmpty())
{
int index = ParseStringToUINT32(name, _level);
int index = ParseStringToUInt32(name, _level);
if (index != name.Length())
return E_INVALIDARG;
}
@@ -996,15 +991,18 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value
if (_level == 0)
{
_copyMode = true;
_defaultBZip2Passes = 1;
}
else if (_level < 5)
{
_defaultAlgorithm = kAlgorithmForFast;
_defaultDicSize = kDicSizeForFast;
_defaultMatchFinder = kMatchFinderForFast;
_defaultBZip2Passes = 1;
}
else if (_level < 7)
{
_defaultBZip2Passes = 1;
// normal;
}
else if(_level < 9)
@@ -1012,6 +1010,7 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value
_defaultAlgorithm = kAlgorithmForX7;
_defaultDicSize = kDicSizeForX7;
_defaultFastBytes = kFastBytesForX7;
_defaultBZip2Passes = 2;
}
else
{
@@ -1019,6 +1018,7 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value
_defaultDicSize = kDicSizeForX9;
_defaultFastBytes = kFastBytesForX9;
_defaultMatchFinder = kMatchFinderForX9;
_defaultBZip2Passes = 7;
}
continue;
}
@@ -1047,8 +1047,8 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value
}
UINT32 number;
int index = ParseStringToUINT32(name, number);
UInt32 number;
int index = ParseStringToUInt32(name, number);
UString realName = name.Mid(index);
if (index == 0)
{
@@ -1057,7 +1057,7 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value
RINOK(SetBoolProperty(_removeSfxBlock, value));
continue;
}
if (name.CompareNoCase(L"F") == 0)
else if (name.CompareNoCase(L"F") == 0)
{
RINOK(SetBoolProperty(_autoFilter, value));
continue;
@@ -1084,16 +1084,19 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value
// RINOK(SetComplexProperty(MultiThread, _multiThreadMult, value));
continue;
}
else if (name.CompareNoCase(L"V") == 0)
{
RINOK(SetBoolProperty(_volumeMode, value));
continue;
}
number = 0;
}
if (number > 100)
if (number > 10000)
return E_FAIL;
if (number < minNumber)
{
return E_INVALIDARG;
}
number -= minNumber;
for(int j = _methods.Size(); j <= number; j++)
for(int j = _methods.Size(); j <= (int)number; j++)
{
COneMethodInfo oneMethodInfo;
_methods.Add(oneMethodInfo);
@@ -1114,13 +1117,13 @@ STDMETHODIMP CHandler::SetProperties(const BSTR *names, const PROPVARIANT *value
CProperty property;
if (realName.CompareNoCase(L"D") == 0 || realName.CompareNoCase(L"MEM") == 0)
{
UINT32 dicSize;
UInt32 dicSize;
if (value.vt == VT_UI4)
{
UINT32 logDicSize = value.ulVal;
UInt32 logDicSize = value.ulVal;
if (logDicSize >= 32)
return E_INVALIDARG;
dicSize = (UINT32)1 << logDicSize;
dicSize = (UInt32)1 << logDicSize;
}
else if (value.vt == VT_BSTR)
{