4.59 beta

This commit is contained in:
Igor Pavlov
2008-08-13 00:00:00 +00:00
committed by Kornel Lesiński
parent 3901bf0ab8
commit 173c07e166
781 changed files with 22124 additions and 13650 deletions
+100 -93
View File
@@ -30,13 +30,20 @@ using namespace NSynchronization;
namespace NArchive {
namespace NZip {
static const Byte kMadeByHostOS = NFileHeader::NHostOS::kFAT;
static const Byte kExtractHostOS = NFileHeader::NHostOS::kFAT;
static const Byte kHostOS =
#ifdef _WIN32
NFileHeader::NHostOS::kFAT;
#else
NFileHeader::NHostOS::kUnix;
#endif
static const Byte kMadeByHostOS = kHostOS;
static const Byte kExtractHostOS = kHostOS;
static const Byte kMethodForDirectory = NFileHeader::NCompressionMethod::kStored;
static const Byte kExtractVersionForDirectory = NFileHeader::NCompressionMethod::kStoreExtractVersion;
static HRESULT CopyBlockToArchive(ISequentialInStream *inStream,
static HRESULT CopyBlockToArchive(ISequentialInStream *inStream,
COutArchive &outArchive, ICompressProgressInfo *progress)
{
CMyComPtr<ISequentialOutStream> outStream;
@@ -45,7 +52,7 @@ static HRESULT CopyBlockToArchive(ISequentialInStream *inStream,
return copyCoder->Code(inStream, outStream, NULL, NULL, progress);
}
static HRESULT WriteRange(IInStream *inStream, COutArchive &outArchive,
static HRESULT WriteRange(IInStream *inStream, COutArchive &outArchive,
const CUpdateRange &range, ICompressProgressInfo *progress)
{
UInt64 position;
@@ -61,30 +68,30 @@ static HRESULT WriteRange(IInStream *inStream, COutArchive &outArchive,
}
static void SetFileHeader(
COutArchive &archive,
COutArchive &archive,
const CCompressionMethodMode &options,
const CUpdateItem &updateItem,
const CUpdateItem &ui,
CItem &item)
{
item.UnPackSize = updateItem.Size;
bool isDirectory;
item.UnPackSize = ui.Size;
bool isDir;
item.ClearFlags();
if (updateItem.NewProperties)
if (ui.NewProperties)
{
isDirectory = updateItem.IsDirectory;
item.Name = updateItem.Name;
item.SetUtf8(updateItem.IsUtf8);
item.ExternalAttributes = updateItem.Attributes;
item.Time = updateItem.Time;
item.NtfsMTime = updateItem.NtfsMTime;
item.NtfsATime = updateItem.NtfsATime;
item.NtfsCTime = updateItem.NtfsCTime;
item.NtfsTimeIsDefined = updateItem.NtfsTimeIsDefined;
isDir = ui.IsDir;
item.Name = ui.Name;
item.SetUtf8(ui.IsUtf8);
item.ExternalAttributes = ui.Attributes;
item.Time = ui.Time;
item.NtfsMTime = ui.NtfsMTime;
item.NtfsATime = ui.NtfsATime;
item.NtfsCTime = ui.NtfsCTime;
item.NtfsTimeIsDefined = ui.NtfsTimeIsDefined;
}
else
isDirectory = item.IsDirectory();
isDir = item.IsDir();
item.LocalHeaderPosition = archive.GetCurrentPosition();
item.MadeByVersion.HostOS = kMadeByHostOS;
@@ -93,8 +100,8 @@ static void SetFileHeader(
item.ExtractVersion.HostOS = kExtractHostOS;
item.InternalAttributes = 0; // test it
item.SetEncrypted(!isDirectory && options.PasswordIsDefined);
if (isDirectory)
item.SetEncrypted(!isDir && options.PasswordIsDefined);
if (isDir)
{
item.ExtractVersion.Version = kExtractVersionForDirectory;
item.CompressionMethod = kMethodForDirectory;
@@ -103,7 +110,7 @@ static void SetFileHeader(
}
}
static void SetItemInfoFromCompressingResult(const CCompressingResult &compressingResult,
static void SetItemInfoFromCompressingResult(const CCompressingResult &compressingResult,
bool isAesMode, Byte aesKeyMode, CItem &item)
{
item.ExtractVersion.Version = compressingResult.ExtractVersion;
@@ -196,7 +203,7 @@ void CThreadInfo::WaitAndCode()
return;
Result = Coder.Compress(
#ifdef EXTERNAL_CODECS
_codecsInfo, _externalCodecs,
_codecsInfo, _externalCodecs,
#endif
InStream, OutStream, Progress, CompressingResult);
if (Result == S_OK && Progress)
@@ -289,7 +296,7 @@ HRESULT CMtProgressMixer2::SetRatioInfo(int index, const UInt64 *inSize, const U
InSizes[index] = *inSize;
if (outSize != 0)
OutSizes[index] = *outSize;
UInt64 v = ProgressOffset + (_inSizeIsMain ?
UInt64 v = ProgressOffset + (_inSizeIsMain ?
(InSizes[0] + InSizes[1]) :
(OutSizes[0] + OutSizes[1]));
return Progress->SetCompleted(&v);
@@ -300,7 +307,7 @@ STDMETHODIMP CMtProgressMixer2::SetRatioInfo(const UInt64 *inSize, const UInt64
return SetRatioInfo(0, inSize, outSize);
}
class CMtProgressMixer:
class CMtProgressMixer:
public ICompressProgressInfo,
public CMyUnknownImp
{
@@ -328,14 +335,14 @@ STDMETHODIMP CMtProgressMixer::SetRatioInfo(const UInt64 *inSize, const UInt64 *
#endif
static HRESULT UpdateItemOldData(COutArchive &archive,
static HRESULT UpdateItemOldData(COutArchive &archive,
IInStream *inStream,
const CUpdateItem &updateItem, CItemEx &item,
const CUpdateItem &ui, CItemEx &item,
/* bool izZip64, */
ICompressProgressInfo *progress,
UInt64 &complexity)
{
if (updateItem.NewProperties)
if (ui.NewProperties)
{
if (item.HasDescriptor())
return E_NOTIMPL;
@@ -344,15 +351,15 @@ static HRESULT UpdateItemOldData(COutArchive &archive,
// CUpdateRange range(item.GetLocalExtraPosition(), item.LocalExtraSize + item.PackSize);
CUpdateRange range(item.GetDataPosition(), item.PackSize);
// item.ExternalAttributes = updateItem.Attributes;
// item.ExternalAttributes = ui.Attributes;
// Test it
item.Name = updateItem.Name;
item.SetUtf8(updateItem.IsUtf8);
item.Time = updateItem.Time;
item.NtfsMTime = updateItem.NtfsMTime;
item.NtfsATime = updateItem.NtfsATime;
item.NtfsCTime = updateItem.NtfsCTime;
item.NtfsTimeIsDefined = updateItem.NtfsTimeIsDefined;
item.Name = ui.Name;
item.SetUtf8(ui.IsUtf8);
item.Time = ui.Time;
item.NtfsMTime = ui.NtfsMTime;
item.NtfsATime = ui.NtfsATime;
item.NtfsCTime = ui.NtfsCTime;
item.NtfsTimeIsDefined = ui.NtfsTimeIsDefined;
item.CentralExtra.RemoveUnknownSubBlocks();
item.LocalExtra.RemoveUnknownSubBlocks();
@@ -369,7 +376,7 @@ static HRESULT UpdateItemOldData(COutArchive &archive,
CUpdateRange range(item.LocalHeaderPosition, item.GetLocalFullSize());
// set new header position
item.LocalHeaderPosition = archive.GetCurrentPosition();
item.LocalHeaderPosition = archive.GetCurrentPosition();
RINOK(WriteRange(inStream, archive, range, progress));
complexity += range.Size;
@@ -379,21 +386,21 @@ static HRESULT UpdateItemOldData(COutArchive &archive,
}
static void WriteDirHeader(COutArchive &archive, const CCompressionMethodMode *options,
const CUpdateItem &updateItem, CItemEx &item)
const CUpdateItem &ui, CItemEx &item)
{
SetFileHeader(archive, *options, updateItem, item);
archive.PrepareWriteCompressedData((UInt16)item.Name.Length(), updateItem.Size, options->IsAesMode);
SetFileHeader(archive, *options, ui, item);
archive.PrepareWriteCompressedData((UInt16)item.Name.Length(), ui.Size, options->IsAesMode);
archive.WriteLocalHeader(item);
}
static HRESULT Update2St(
DECL_EXTERNAL_CODECS_LOC_VARS
COutArchive &archive,
COutArchive &archive,
CInArchive *inArchive,
IInStream *inStream,
const CObjectVector<CItemEx> &inputItems,
const CObjectVector<CUpdateItem> &updateItems,
const CCompressionMethodMode *options,
const CCompressionMethodMode *options,
const CByteBuffer &comment,
IArchiveUpdateCallback *updateCallback)
{
@@ -411,37 +418,37 @@ static HRESULT Update2St(
lps->InSize = unpackSizeTotal;
lps->OutSize = packSizeTotal;
RINOK(lps->SetCur());
const CUpdateItem &updateItem = updateItems[itemIndex];
const CUpdateItem &ui = updateItems[itemIndex];
CItemEx item;
if (!updateItem.NewProperties || !updateItem.NewData)
if (!ui.NewProperties || !ui.NewData)
{
item = inputItems[updateItem.IndexInArchive];
item = inputItems[ui.IndexInArchive];
if (inArchive->ReadLocalItemAfterCdItemFull(item) != S_OK)
return E_NOTIMPL;
}
if (updateItem.NewData)
if (ui.NewData)
{
bool isDirectory = ((updateItem.NewProperties) ? updateItem.IsDirectory : item.IsDirectory());
if (isDirectory)
bool isDir = ((ui.NewProperties) ? ui.IsDir : item.IsDir());
if (isDir)
{
WriteDirHeader(archive, options, updateItem, item);
WriteDirHeader(archive, options, ui, item);
}
else
{
CMyComPtr<ISequentialInStream> fileInStream;
HRESULT res = updateCallback->GetStream(updateItem.IndexInClient, &fileInStream);
HRESULT res = updateCallback->GetStream(ui.IndexInClient, &fileInStream);
if (res == S_FALSE)
{
lps->ProgressOffset += updateItem.Size;
lps->ProgressOffset += ui.Size;
RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
continue;
}
RINOK(res);
// file Size can be 64-bit !!!
SetFileHeader(archive, *options, updateItem, item);
archive.PrepareWriteCompressedData((UInt16)item.Name.Length(), updateItem.Size, options->IsAesMode);
SetFileHeader(archive, *options, ui, item);
archive.PrepareWriteCompressedData((UInt16)item.Name.Length(), ui.Size, options->IsAesMode);
CCompressingResult compressingResult;
CMyComPtr<IOutStream> outStream;
archive.CreateStreamForCompressing(&outStream);
@@ -459,7 +466,7 @@ static HRESULT Update2St(
{
UInt64 complexity = 0;
lps->SendRatio = false;
RINOK(UpdateItemOldData(archive, inStream, updateItem, item, progress, complexity));
RINOK(UpdateItemOldData(archive, inStream, ui, item, progress, complexity));
lps->SendRatio = true;
lps->ProgressOffset += complexity;
}
@@ -472,12 +479,12 @@ static HRESULT Update2St(
static HRESULT Update2(
DECL_EXTERNAL_CODECS_LOC_VARS
COutArchive &archive,
COutArchive &archive,
CInArchive *inArchive,
IInStream *inStream,
const CObjectVector<CItemEx> &inputItems,
const CObjectVector<CUpdateItem> &updateItems,
const CCompressionMethodMode *options,
const CCompressionMethodMode *options,
const CByteBuffer &comment,
IArchiveUpdateCallback *updateCallback)
{
@@ -488,20 +495,20 @@ static HRESULT Update2(
int i;
for(i = 0; i < updateItems.Size(); i++)
{
const CUpdateItem &updateItem = updateItems[i];
if (updateItem.NewData)
const CUpdateItem &ui = updateItems[i];
if (ui.NewData)
{
complexity += updateItem.Size;
numBytesToCompress += updateItem.Size;
complexity += ui.Size;
numBytesToCompress += ui.Size;
numFilesToCompress++;
/*
if (updateItem.Commented)
complexity += updateItem.CommentRange.Size;
if (ui.Commented)
complexity += ui.CommentRange.Size;
*/
}
else
{
CItemEx inputItem = inputItems[updateItem.IndexInArchive];
CItemEx inputItem = inputItems[ui.IndexInArchive];
if (inArchive->ReadLocalItemAfterCdItemFull(inputItem) != S_OK)
return E_NOTIMPL;
complexity += inputItem.GetLocalFullSize();
@@ -580,7 +587,7 @@ static HRESULT Update2(
mtProgressMixerSpec->Create(updateCallback, true);
CMtCompressProgressMixer mtCompressProgressMixer;
mtCompressProgressMixer.Init(numThreads, mtProgressMixerSpec->RatioProgress);
mtCompressProgressMixer.Init(numThreads, mtProgressMixerSpec->RatioProgress);
CMemBlockManagerMt memManager(kBlockSize);
CMemRefs refs(&memManager);
@@ -625,30 +632,30 @@ static HRESULT Update2(
{
if ((UInt32)threadIndices.Size() < numThreads && mtItemIndex < updateItems.Size())
{
const CUpdateItem &updateItem = updateItems[mtItemIndex++];
if (!updateItem.NewData)
const CUpdateItem &ui = updateItems[mtItemIndex++];
if (!ui.NewData)
continue;
CItemEx item;
if (updateItem.NewProperties)
if (ui.NewProperties)
{
if (updateItem.IsDirectory)
if (ui.IsDir)
continue;
}
else
{
item = inputItems[updateItem.IndexInArchive];
item = inputItems[ui.IndexInArchive];
if (inArchive->ReadLocalItemAfterCdItemFull(item) != S_OK)
return E_NOTIMPL;
if (item.IsDirectory())
if (item.IsDir())
continue;
}
CMyComPtr<ISequentialInStream> fileInStream;
{
NWindows::NSynchronization::CCriticalSectionLock lock(mtProgressMixerSpec->Mixer2->CriticalSection);
HRESULT res = updateCallback->GetStream(updateItem.IndexInClient, &fileInStream);
HRESULT res = updateCallback->GetStream(ui.IndexInClient, &fileInStream);
if (res == S_FALSE)
{
complexity += updateItem.Size;
complexity += ui.Size;
complexity += NFileHeader::kLocalBlockSize;
mtProgressMixerSpec->Mixer2->SetProgressOffset(complexity);
RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
@@ -667,9 +674,9 @@ static HRESULT Update2(
threadInfo.IsFree = false;
threadInfo.InStream = fileInStream;
// !!!!! we must release ref before sending event
// !!!!! we must release ref before sending event
// BUG was here in v4.43 and v4.44. It could change ref counter in two threads in same time
fileInStream.Release();
fileInStream.Release();
threadInfo.OutStreamSpec->Init();
threadInfo.ProgressSpec->Reinit();
@@ -690,31 +697,31 @@ static HRESULT Update2(
continue;
}
const CUpdateItem &updateItem = updateItems[itemIndex];
const CUpdateItem &ui = updateItems[itemIndex];
CItemEx item;
if (!updateItem.NewProperties || !updateItem.NewData)
if (!ui.NewProperties || !ui.NewData)
{
item = inputItems[updateItem.IndexInArchive];
item = inputItems[ui.IndexInArchive];
if (inArchive->ReadLocalItemAfterCdItemFull(item) != S_OK)
return E_NOTIMPL;
}
if (updateItem.NewData)
if (ui.NewData)
{
bool isDirectory = ((updateItem.NewProperties) ? updateItem.IsDirectory : item.IsDirectory());
if (isDirectory)
bool isDir = ((ui.NewProperties) ? ui.IsDir : item.IsDir());
if (isDir)
{
WriteDirHeader(archive, options, updateItem, item);
WriteDirHeader(archive, options, ui, item);
}
else
{
if (lastRealStreamItemIndex < itemIndex)
{
lastRealStreamItemIndex = itemIndex;
SetFileHeader(archive, *options, updateItem, item);
SetFileHeader(archive, *options, ui, item);
// file Size can be 64-bit !!!
archive.PrepareWriteCompressedData((UInt16)item.Name.Length(), updateItem.Size, options->IsAesMode);
archive.PrepareWriteCompressedData((UInt16)item.Name.Length(), ui.Size, options->IsAesMode);
}
CMemBlocks2 &memRef = refs.Refs[itemIndex];
@@ -725,7 +732,7 @@ static HRESULT Update2(
memRef.WriteToStream(memManager.GetBlockSize(), outStream);
SetItemInfoFromCompressingResult(memRef.CompressingResult,
options->IsAesMode, options->AesKeyMode, item);
SetFileHeader(archive, *options, updateItem, item);
SetFileHeader(archive, *options, ui, item);
archive.WriteLocalHeader(item);
// RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
memRef.FreeOpt(&memManager);
@@ -743,7 +750,7 @@ static HRESULT Update2(
}
}
DWORD result = ::WaitForMultipleObjects(compressingCompletedEvents.Size(),
DWORD result = ::WaitForMultipleObjects(compressingCompletedEvents.Size(),
&compressingCompletedEvents.Front(), FALSE, INFINITE);
int t = (int)(result - WAIT_OBJECT_0);
CThreadInfo &threadInfo = threads.Threads[threadIndices[t]];
@@ -756,9 +763,9 @@ static HRESULT Update2(
{
RINOK(threadInfo.OutStreamSpec->WriteToRealStream());
threadInfo.OutStreamSpec->ReleaseOutStream();
SetItemInfoFromCompressingResult(threadInfo.CompressingResult,
SetItemInfoFromCompressingResult(threadInfo.CompressingResult,
options->IsAesMode, options->AesKeyMode, item);
SetFileHeader(archive, *options, updateItem, item);
SetFileHeader(archive, *options, ui, item);
archive.WriteLocalHeader(item);
}
else
@@ -774,7 +781,7 @@ static HRESULT Update2(
}
else
{
RINOK(UpdateItemOldData(archive, inStream, updateItem, item, progress, complexity));
RINOK(UpdateItemOldData(archive, inStream, ui, item, progress, complexity));
}
items.Add(item);
complexity += NFileHeader::kLocalBlockSize;
@@ -783,10 +790,10 @@ static HRESULT Update2(
}
archive.WriteCentralDir(items, comment);
return S_OK;
#endif
#endif
}
HRESULT Update(
HRESULT Update(
DECL_EXTERNAL_CODECS_LOC_VARS
const CObjectVector<CItemEx> &inputItems,
const CObjectVector<CUpdateItem> &updateItems,
@@ -825,9 +832,9 @@ HRESULT Update(
return Update2(
EXTERNAL_CODECS_LOC_VARS
outArchive, inArchive, inStream,
inputItems, updateItems,
compressionMethodMode,
outArchive, inArchive, inStream,
inputItems, updateItems,
compressionMethodMode,
archiveInfo.Comment, updateCallback);
}