diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2016-05-10 03:00:00 +0300 |
---|---|---|
committer | Kornel LesiĆski <kornel@geekhood.net> | 2016-05-28 02:16:59 +0300 |
commit | 66ac98bb02ac0fadd2a0e3266ea39279984580a3 (patch) | |
tree | c14c790212474e8b51df443d686b202cfe6b2315 /CPP/7zip/Archive/Rar | |
parent | c20d013055085bf49b4c93b2c617030b10c1fb4d (diff) |
16.0016.00
Diffstat (limited to 'CPP/7zip/Archive/Rar')
-rw-r--r-- | CPP/7zip/Archive/Rar/Rar5Handler.cpp | 58 | ||||
-rw-r--r-- | CPP/7zip/Archive/Rar/RarHandler.cpp | 66 | ||||
-rw-r--r-- | CPP/7zip/Archive/Rar/RarItem.h | 2 |
3 files changed, 100 insertions, 26 deletions
diff --git a/CPP/7zip/Archive/Rar/Rar5Handler.cpp b/CPP/7zip/Archive/Rar/Rar5Handler.cpp index 131f2c9b..959c2e36 100644 --- a/CPP/7zip/Archive/Rar/Rar5Handler.cpp +++ b/CPP/7zip/Archive/Rar/Rar5Handler.cpp @@ -2333,6 +2333,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, { UInt64 total = 0; + bool isThereUndefinedSize = false; bool thereAreLinks = false; { @@ -2342,9 +2343,14 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, unsigned index = allFilesMode ? t : indices[t]; const CRefItem &ref = _refs[index]; const CItem &item = _items[ref.Item]; + const CItem &lastItem = _items[ref.Last]; extractStatuses[index] |= kStatus_Extract; - total += item.Size; + + if (!lastItem.Is_UnknownSize()) + total += lastItem.Size; + else + isThereUndefinedSize = true; if (ref.Link >= 0) { @@ -2352,11 +2358,18 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, { if ((unsigned)ref.Link < index) { - const CItem &linkItem = _items[_refs[(unsigned)ref.Link].Item]; + const CRefItem &linkRef = _refs[(unsigned)ref.Link]; + const CItem &linkItem = _items[linkRef.Item]; if (linkItem.IsSolid() && linkItem.Size <= k_CopyLinkFile_MaxSize) { if (extractStatuses[(unsigned)ref.Link] == 0) - total += linkItem.Size; + { + const CItem &lastLinkItem = _items[linkRef.Last]; + if (!lastLinkItem.Is_UnknownSize()) + total += lastLinkItem.Size; + else + isThereUndefinedSize = true; + } extractStatuses[(unsigned)ref.Link] |= kStatus_Link; thereAreLinks = true; } @@ -2375,11 +2388,18 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, while (j > solidLimit) { j--; - const CItem &item2 = _items[_refs[j].Item]; + const CRefItem &ref2 = _refs[j]; + const CItem &item2 = _items[ref2.Item]; if (!item2.IsService()) { if (extractStatuses[j] == 0) - total += item2.Size; + { + const CItem &lastItem2 = _items[ref2.Last]; + if (!lastItem2.Is_UnknownSize()) + total += lastItem2.Size; + else + isThereUndefinedSize = true; + } extractStatuses[j] |= kStatus_Skip; if (!item2.IsSolid()) break; @@ -2415,13 +2435,20 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, while (j > solidLimit) { j--; - const CItem &item2 = _items[_refs[j].Item]; + const CRefItem &ref2 = _refs[j]; + const CItem &item2 = _items[ref2.Item]; if (!item2.IsService()) { if (extractStatuses[j] != 0) break; extractStatuses[j] = kStatus_Skip; - total += item2.Size; + { + const CItem &lastItem2 = _items[ref2.Last]; + if (!lastItem2.Is_UnknownSize()) + total += lastItem2.Size; + else + isThereUndefinedSize = true; + } if (!item2.IsSolid()) break; } @@ -2449,7 +2476,10 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, } } - RINOK(extractCallback->SetTotal(total)); + if (total != 0 || !isThereUndefinedSize) + { + RINOK(extractCallback->SetTotal(total)); + } } @@ -2502,8 +2532,12 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, const CRefItem *ref = &_refs[index]; const CItem *item = &_items[ref->Item]; + const CItem &lastItem = _items[ref->Last]; + + curUnpackSize = 0; + if (!lastItem.Is_UnknownSize()) + curUnpackSize = lastItem.Size; - curUnpackSize = item->Size; curPackSize = GetPackSize(index); RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); @@ -2532,11 +2566,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, { const CRefItem &ref2 = _refs[index2]; const CItem &item2 = _items[ref2.Item]; + const CItem &lastItem2 = _items[ref2.Last]; if (!item2.IsSolid()) { item = &item2; ref = &ref2; - curUnpackSize = item->Size; + if (!lastItem2.Is_UnknownSize()) + curUnpackSize = lastItem2.Size; + else + curUnpackSize = 0; curPackSize = GetPackSize(index2); } else if ((unsigned)index2 < index) diff --git a/CPP/7zip/Archive/Rar/RarHandler.cpp b/CPP/7zip/Archive/Rar/RarHandler.cpp index 3b5924b4..6f3e0a0c 100644 --- a/CPP/7zip/Archive/Rar/RarHandler.cpp +++ b/CPP/7zip/Archive/Rar/RarHandler.cpp @@ -953,6 +953,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val NCOM::CPropVariant prop; const CRefItem &refItem = _refItems[index]; const CItem &item = _items[refItem.ItemIndex]; + const CItem &lastItem = _items[refItem.ItemIndex + refItem.NumItems - 1]; + /* const CItem *mainItem = &item; if (item.BaseFileIndex >= 0) @@ -972,7 +974,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val break; } case kpidIsDir: prop = item.IsDir(); break; - case kpidSize: prop = item.Size; break; + case kpidSize: if (lastItem.Is_Size_Defined()) prop = lastItem.Size; break; case kpidPackSize: prop = GetPackSize(index); break; case kpidMTime: RarTimeToProp(item.MTime, prop); break; case kpidCTime: if (item.CTimeDefined) RarTimeToProp(item.CTime, prop); break; @@ -985,7 +987,6 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val case kpidSplitAfter: prop = _items[refItem.ItemIndex + refItem.NumItems - 1].IsSplitAfter(); break; case kpidCRC: { - const CItem &lastItem = _items[refItem.ItemIndex + refItem.NumItems - 1]; prop = ((lastItem.IsSplitAfter()) ? item.FileCRC : lastItem.FileCRC); break; } @@ -1378,34 +1379,52 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, CRecordVector<unsigned> importantIndexes; CRecordVector<bool> extractStatuses; + bool isThereUndefinedSize = false; + for (UInt32 t = 0; t < numItems; t++) { unsigned index = allFilesMode ? t : indices[t]; - const CRefItem &refItem = _refItems[index]; - const CItem &item = _items[refItem.ItemIndex]; - censoredTotalUnPacked += item.Size; - // censoredTotalPacked += item.PackSize; + + { + const CRefItem &refItem = _refItems[index]; + const CItem &item = _items[refItem.ItemIndex + refItem.NumItems - 1]; + + if (item.Is_Size_Defined()) + censoredTotalUnPacked += item.Size; + else + isThereUndefinedSize = true; + + // censoredTotalPacked += item.PackSize; + } + unsigned j; for (j = lastIndex; j <= index; j++) // if (!_items[_refItems[j].ItemIndex].IsSolid()) if (!IsSolid(j)) lastIndex = j; + for (j = lastIndex; j <= index; j++) { const CRefItem &refItem = _refItems[j]; - const CItem &item = _items[refItem.ItemIndex]; + const CItem &item = _items[refItem.ItemIndex + refItem.NumItems - 1]; - // const CItem &item = _items[j]; - - importantTotalUnPacked += item.Size; + if (item.Is_Size_Defined()) + importantTotalUnPacked += item.Size; + else + isThereUndefinedSize = true; // importantTotalPacked += item.PackSize; importantIndexes.Add(j); extractStatuses.Add(j == index); } + lastIndex = index + 1; } - RINOK(extractCallback->SetTotal(importantTotalUnPacked)); + if (importantTotalUnPacked != 0 || !isThereUndefinedSize) + { + RINOK(extractCallback->SetTotal(importantTotalUnPacked)); + } + UInt64 currentImportantTotalUnPacked = 0; UInt64 currentImportantTotalPacked = 0; UInt64 currentUnPackSize, currentPackSize; @@ -1431,13 +1450,19 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, lps->Init(extractCallback, false); bool solidStart = true; - for (unsigned i = 0; i < importantIndexes.Size(); i++, + + for (unsigned i = 0;; + i++, currentImportantTotalUnPacked += currentUnPackSize, currentImportantTotalPacked += currentPackSize) { lps->InSize = currentImportantTotalPacked; lps->OutSize = currentImportantTotalUnPacked; RINOK(lps->SetCur()); + + if (i >= importantIndexes.Size()) + break; + CMyComPtr<ISequentialOutStream> realOutStream; Int32 askMode; @@ -1452,8 +1477,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, const CRefItem &refItem = _refItems[index]; const CItem &item = _items[refItem.ItemIndex]; - - currentUnPackSize = item.Size; + const CItem &lastItem = _items[refItem.ItemIndex + refItem.NumItems - 1]; + + UInt64 outSize = (UInt64)(Int64)-1; + currentUnPackSize = 0; + if (lastItem.Is_Size_Defined()) + { + outSize = lastItem.Size; + currentUnPackSize = outSize; + } currentPackSize = GetPackSize(index); @@ -1678,12 +1710,14 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, continue; } - HRESULT result = commonCoder->Code(inStream, outStream, &packSize, &item.Size, progress); + HRESULT result = commonCoder->Code(inStream, outStream, &packSize, &outSize, progress); if (item.IsEncrypted()) filterStreamSpec->ReleaseInStream(); - const CItem &lastItem = _items[refItem.ItemIndex + refItem.NumItems - 1]; + if (outSize == (UInt64)(Int64)-1) + currentUnPackSize = outStreamSpec->GetSize(); + int opRes = (volsInStreamSpec->CrcIsOK && outStreamSpec->GetCRC() == lastItem.FileCRC) ? NExtract::NOperationResult::kOK: NExtract::NOperationResult::kCRCError; diff --git a/CPP/7zip/Archive/Rar/RarItem.h b/CPP/7zip/Archive/Rar/RarItem.h index 13daa1cb..10e21c57 100644 --- a/CPP/7zip/Archive/Rar/RarItem.h +++ b/CPP/7zip/Archive/Rar/RarItem.h @@ -42,6 +42,8 @@ struct CItem Byte Salt[8]; + bool Is_Size_Defined() const { return Size != (UInt64)(Int64)-1; } + bool IsEncrypted() const { return (Flags & NHeader::NFile::kEncrypted) != 0; } bool IsSolid() const { return (Flags & NHeader::NFile::kSolid) != 0; } bool IsCommented() const { return (Flags & NHeader::NFile::kComment) != 0; } |