diff options
Diffstat (limited to 'CPP/7zip/Archive/7z')
-rwxr-xr-x | CPP/7zip/Archive/7z/7zEncode.cpp | 20 | ||||
-rwxr-xr-x | CPP/7zip/Archive/7z/7zExtract.cpp | 28 | ||||
-rwxr-xr-x | CPP/7zip/Archive/7z/7zHandler.cpp | 123 | ||||
-rwxr-xr-x | CPP/7zip/Archive/7z/7zItem.h | 7 | ||||
-rwxr-xr-x | CPP/7zip/Archive/7z/7zProperties.cpp | 8 | ||||
-rwxr-xr-x | CPP/7zip/Archive/7z/7zUpdate.cpp | 98 |
6 files changed, 147 insertions, 137 deletions
diff --git a/CPP/7zip/Archive/7z/7zEncode.cpp b/CPP/7zip/Archive/7z/7zEncode.cpp index 8c229362..3a5cfcd5 100755 --- a/CPP/7zip/Archive/7z/7zEncode.cpp +++ b/CPP/7zip/Archive/7z/7zEncode.cpp @@ -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)); diff --git a/CPP/7zip/Archive/7z/7zExtract.cpp b/CPP/7zip/Archive/7z/7zExtract.cpp index 2f2423ee..65f9c9eb 100755 --- a/CPP/7zip/Archive/7z/7zExtract.cpp +++ b/CPP/7zip/Archive/7z/7zExtract.cpp @@ -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(¤tImportantTotalUnPacked)); + 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, ¤tImportantTotalUnPacked); + 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 diff --git a/CPP/7zip/Archive/7z/7zHandler.cpp b/CPP/7zip/Archive/7z/7zHandler.cpp index 9fc45848..d5dc8720 100755 --- a/CPP/7zip/Archive/7z/7zHandler.cpp +++ b/CPP/7zip/Archive/7z/7zHandler.cpp @@ -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; } -#endif +#else -STDMETHODIMP CHandler::GetNumberOfArchiveProperties(UInt32 *numProperties) +STATPROPSTG kArcProps[] = { - *numProperties = 0; - return S_OK; -} + { NULL, kpidMethod, VT_BSTR}, + { NULL, kpidSolid, VT_BOOL}, + { NULL, kpidNumBlocks, VT_UI4} +}; -STDMETHODIMP CHandler::GetArchivePropertyInfo(UInt32 /* index */, - BSTR * /* name */, PROPID * /* propID */, VARTYPE * /* varType */) +STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) { - return E_NOTIMPL; + 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 -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); } diff --git a/CPP/7zip/Archive/7z/7zItem.h b/CPP/7zip/Archive/7z/7zItem.h index 388f19d3..31c5ce2d 100755 --- a/CPP/7zip/Archive/7z/7zItem.h +++ b/CPP/7zip/Archive/7z/7zItem.h @@ -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; + } }; }} diff --git a/CPP/7zip/Archive/7z/7zProperties.cpp b/CPP/7zip/Archive/7z/7zProperties.cpp index 316f4f09..3452a030 100755 --- a/CPP/7zip/Archive/7z/7zProperties.cpp +++ b/CPP/7zip/Archive/7z/7zProperties.cpp @@ -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]); diff --git a/CPP/7zip/Archive/7z/7zUpdate.cpp b/CPP/7zip/Archive/7z/7zUpdate.cpp index 59e7c4fc..68f4604d 100755 --- a/CPP/7zip/Archive/7z/7zUpdate.cpp +++ b/CPP/7zip/Archive/7z/7zUpdate.cpp @@ -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 ¤tComplexity) -{ - 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, ¤tComplexity, ¤tComplexity); - - HRESULT result = CopyBlock(inStreamLimited, outStream, compressProgress); - currentComplexity += size; - return result; -} - - -static HRESULT WriteRange(IInStream *inStream, - ISequentialOutStream *outStream, - UInt64 position, - UInt64 size, - IProgress *progress, - UInt64 ¤tComplexity) -{ - 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; |