Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Pavlov <ipavlov@users.sourceforge.net>2016-05-10 03:00:00 +0300
committerKornel LesiƄski <kornel@geekhood.net>2016-05-28 02:16:59 +0300
commit66ac98bb02ac0fadd2a0e3266ea39279984580a3 (patch)
treec14c790212474e8b51df443d686b202cfe6b2315 /CPP/7zip/Archive/Rar
parentc20d013055085bf49b4c93b2c617030b10c1fb4d (diff)
16.0016.00
Diffstat (limited to 'CPP/7zip/Archive/Rar')
-rw-r--r--CPP/7zip/Archive/Rar/Rar5Handler.cpp58
-rw-r--r--CPP/7zip/Archive/Rar/RarHandler.cpp66
-rw-r--r--CPP/7zip/Archive/Rar/RarItem.h2
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; }