Rar5Handler.cpp (p7zip_15.14.1_src_all) | : | Rar5Handler.cpp (p7zip_16.02_src_all) | ||
---|---|---|---|---|
skipping to change at line 187 | skipping to change at line 187 | |||
} | } | |||
bool CItem::FindExtra_Version(UInt64 &version) const | bool CItem::FindExtra_Version(UInt64 &version) const | |||
{ | { | |||
unsigned size; | unsigned size; | |||
int offset = FindExtra(NExtraRecordType::kVersion, size); | int offset = FindExtra(NExtraRecordType::kVersion, size); | |||
if (offset < 0) | if (offset < 0) | |||
return false; | return false; | |||
const Byte *p = Extra + (unsigned)offset; | const Byte *p = Extra + (unsigned)offset; | |||
UInt64 Flags; | UInt64 flags; | |||
unsigned num = ReadVarInt(p, size, &Flags); | unsigned num = ReadVarInt(p, size, &flags); | |||
if (num == 0) return false; p += num; size -= num; | if (num == 0) return false; p += num; size -= num; | |||
num = ReadVarInt(p, size, &version); | num = ReadVarInt(p, size, &version); | |||
if (num == 0) return false; p += num; size -= num; | if (num == 0) return false; p += num; size -= num; | |||
return size == 0; | return size == 0; | |||
} | } | |||
bool CItem::FindExtra_Link(CLinkInfo &link) const | bool CItem::FindExtra_Link(CLinkInfo &link) const | |||
{ | { | |||
skipping to change at line 1837 | skipping to change at line 1837 | |||
RINOK(inStream->Seek(0, STREAM_SEEK_END, &endPos)); | RINOK(inStream->Seek(0, STREAM_SEEK_END, &endPos)); | |||
RINOK(inStream->Seek(arch.StreamStartPosition, STREAM_SEEK_SET, NULL)); | RINOK(inStream->Seek(arch.StreamStartPosition, STREAM_SEEK_SET, NULL)); | |||
if (openCallback) | if (openCallback) | |||
{ | { | |||
totalBytes += endPos; | totalBytes += endPos; | |||
RINOK(openCallback->SetTotal(NULL, &totalBytes)); | RINOK(openCallback->SetTotal(NULL, &totalBytes)); | |||
} | } | |||
CInArcInfo arcInfoOpen; | CInArcInfo arcInfoOpen; | |||
{ | ||||
HRESULT res = arch.Open(inStream, maxCheckStartPosition, getTextPassword, ar cInfoOpen); | HRESULT res = arch.Open(inStream, maxCheckStartPosition, getTextPassword, ar cInfoOpen); | |||
if (arch.IsArc && arch.UnexpectedEnd) | if (arch.IsArc && arch.UnexpectedEnd) | |||
_errorFlags |= kpv_ErrorFlags_UnexpectedEnd; | _errorFlags |= kpv_ErrorFlags_UnexpectedEnd; | |||
if (_arcs.IsEmpty()) | if (_arcs.IsEmpty()) | |||
{ | { | |||
_isArc = arch.IsArc; | _isArc = arch.IsArc; | |||
} | } | |||
if (res != S_OK) | if (res != S_OK) | |||
{ | { | |||
if (res != S_FALSE) | if (res != S_FALSE) | |||
return res; | return res; | |||
if (_arcs.IsEmpty()) | if (_arcs.IsEmpty()) | |||
return res; | return res; | |||
break; | break; | |||
} | } | |||
} | ||||
CArc &arc = _arcs.AddNew(); | CArc &arc = _arcs.AddNew(); | |||
CInArcInfo &arcInfo = arc.Info; | CInArcInfo &arcInfo = arc.Info; | |||
arcInfo = arcInfoOpen; | arcInfo = arcInfoOpen; | |||
arc.Stream = inStream; | arc.Stream = inStream; | |||
CItem item; | CItem item; | |||
for (;;) | for (;;) | |||
{ | { | |||
skipping to change at line 2024 | skipping to change at line 2026 | |||
} | } | |||
} | } | |||
} | } | |||
if (needAdd) | if (needAdd) | |||
{ | { | |||
if (item.IsSplitBefore()) | if (item.IsSplitBefore()) | |||
{ | { | |||
if (prevSplitFile >= 0) | if (prevSplitFile >= 0) | |||
{ | { | |||
CRefItem &ref = _refs[prevSplitFile]; | CRefItem &ref2 = _refs[prevSplitFile]; | |||
CItem &prevItem = _items[ref.Last]; | CItem &prevItem = _items[ref2.Last]; | |||
if (item.IsNextForItem(prevItem)) | if (item.IsNextForItem(prevItem)) | |||
{ | { | |||
ref.Last = _items.Size(); | ref2.Last = _items.Size(); | |||
prevItem.NextItem = ref.Last; | prevItem.NextItem = ref2.Last; | |||
needAdd = false; | needAdd = false; | |||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
if (needAdd) | if (needAdd) | |||
{ | { | |||
if (item.IsSplitAfter()) | if (item.IsSplitAfter()) | |||
prevSplitFile = _refs.Size(); | prevSplitFile = _refs.Size(); | |||
skipping to change at line 2283 | skipping to change at line 2285 | |||
const size_t k_CopyLinkFile_MaxSize = (size_t)1 << (28 + sizeof(size_t) / 2); | const size_t k_CopyLinkFile_MaxSize = (size_t)1 << (28 + sizeof(size_t) / 2); | |||
const Byte kStatus_Extract = 1 << 0; | const Byte kStatus_Extract = 1 << 0; | |||
const Byte kStatus_Skip = 1 << 1; | const Byte kStatus_Skip = 1 << 1; | |||
const Byte kStatus_Link = 1 << 2; | const Byte kStatus_Link = 1 << 2; | |||
CObjectVector<CLinkFile> linkFiles; | CObjectVector<CLinkFile> linkFiles; | |||
{ | { | |||
UInt64 total = 0; | UInt64 total = 0; | |||
bool isThereUndefinedSize = false; | ||||
bool thereAreLinks = false; | bool thereAreLinks = false; | |||
{ | { | |||
unsigned solidLimit = 0; | unsigned solidLimit = 0; | |||
for (UInt32 t = 0; t < numItems; t++) | for (UInt32 t = 0; t < numItems; t++) | |||
{ | { | |||
unsigned index = allFilesMode ? t : indices[t]; | unsigned index = allFilesMode ? t : indices[t]; | |||
const CRefItem &ref = _refs[index]; | const CRefItem &ref = _refs[index]; | |||
const CItem &item = _items[ref.Item]; | const CItem &item = _items[ref.Item]; | |||
const CItem &lastItem = _items[ref.Last]; | ||||
extractStatuses[index] |= kStatus_Extract; | extractStatuses[index] |= kStatus_Extract; | |||
total += item.Size; | ||||
if (!lastItem.Is_UnknownSize()) | ||||
total += lastItem.Size; | ||||
else | ||||
isThereUndefinedSize = true; | ||||
if (ref.Link >= 0) | if (ref.Link >= 0) | |||
{ | { | |||
if (!testMode) | if (!testMode) | |||
{ | { | |||
if ((unsigned)ref.Link < index) | 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 (linkItem.IsSolid() && linkItem.Size <= k_CopyLinkFile_MaxSize) | |||
{ | { | |||
if (extractStatuses[(unsigned)ref.Link] == 0) | 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; | extractStatuses[(unsigned)ref.Link] |= kStatus_Link; | |||
thereAreLinks = true; | thereAreLinks = true; | |||
} | } | |||
} | } | |||
} | } | |||
continue; | continue; | |||
} | } | |||
if (item.IsService()) | if (item.IsService()) | |||
continue; | continue; | |||
if (item.IsSolid()) | if (item.IsSolid()) | |||
{ | { | |||
unsigned j = index; | unsigned j = index; | |||
while (j > solidLimit) | while (j > solidLimit) | |||
{ | { | |||
j--; | j--; | |||
const CItem &item2 = _items[_refs[j].Item]; | const CRefItem &ref2 = _refs[j]; | |||
const CItem &item2 = _items[ref2.Item]; | ||||
if (!item2.IsService()) | if (!item2.IsService()) | |||
{ | { | |||
if (extractStatuses[j] == 0) | 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; | extractStatuses[j] |= kStatus_Skip; | |||
if (!item2.IsSolid()) | if (!item2.IsSolid()) | |||
break; | break; | |||
} | } | |||
} | } | |||
} | } | |||
solidLimit = index + 1; | solidLimit = index + 1; | |||
} | } | |||
} | } | |||
skipping to change at line 2365 | skipping to change at line 2387 | |||
CLinkFile &linkFile = linkFiles.AddNew(); | CLinkFile &linkFile = linkFiles.AddNew(); | |||
linkFile.Index = i; | linkFile.Index = i; | |||
if (item.IsSolid()) | if (item.IsSolid()) | |||
{ | { | |||
unsigned j = i; | unsigned j = i; | |||
while (j > solidLimit) | while (j > solidLimit) | |||
{ | { | |||
j--; | j--; | |||
const CItem &item2 = _items[_refs[j].Item]; | const CRefItem &ref2 = _refs[j]; | |||
const CItem &item2 = _items[ref2.Item]; | ||||
if (!item2.IsService()) | if (!item2.IsService()) | |||
{ | { | |||
if (extractStatuses[j] != 0) | if (extractStatuses[j] != 0) | |||
break; | break; | |||
extractStatuses[j] = kStatus_Skip; | 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()) | if (!item2.IsSolid()) | |||
break; | break; | |||
} | } | |||
} | } | |||
} | } | |||
solidLimit = i + 1; | solidLimit = i + 1; | |||
} | } | |||
for (UInt32 t = 0; t < numItems; t++) | for (UInt32 t = 0; t < numItems; t++) | |||
skipping to change at line 2399 | skipping to change at line 2428 | |||
const CItem &linkItem = _items[_refs[(unsigned)linkIndex].Item]; | const CItem &linkItem = _items[_refs[(unsigned)linkIndex].Item]; | |||
if (!linkItem.IsSolid() || linkItem.Size > k_CopyLinkFile_MaxSize) | if (!linkItem.IsSolid() || linkItem.Size > k_CopyLinkFile_MaxSize) | |||
continue; | continue; | |||
int bufIndex = FindLinkBuf(linkFiles, linkIndex); | int bufIndex = FindLinkBuf(linkFiles, linkIndex); | |||
if (bufIndex < 0) | if (bufIndex < 0) | |||
return E_FAIL; | return E_FAIL; | |||
linkFiles[bufIndex].NumLinks++; | linkFiles[bufIndex].NumLinks++; | |||
} | } | |||
} | } | |||
RINOK(extractCallback->SetTotal(total)); | if (total != 0 || !isThereUndefinedSize) | |||
{ | ||||
RINOK(extractCallback->SetTotal(total)); | ||||
} | ||||
} | } | |||
UInt64 totalUnpacked = 0; | UInt64 totalUnpacked = 0; | |||
UInt64 totalPacked = 0; | UInt64 totalPacked = 0; | |||
UInt64 curUnpackSize = 0; | UInt64 curUnpackSize = 0; | |||
UInt64 curPackSize = 0; | UInt64 curPackSize = 0; | |||
CUnpacker unpacker; | CUnpacker unpacker; | |||
CVolsInStream *volsInStreamSpec = new CVolsInStream; | CVolsInStream *volsInStreamSpec = new CVolsInStream; | |||
skipping to change at line 2451 | skipping to change at line 2483 | |||
int bufIndex = FindLinkBuf(linkFiles, i); | int bufIndex = FindLinkBuf(linkFiles, i); | |||
if (bufIndex < 0) | if (bufIndex < 0) | |||
return E_FAIL; | return E_FAIL; | |||
unpacker.linkFile = &linkFiles[bufIndex]; | unpacker.linkFile = &linkFiles[bufIndex]; | |||
} | } | |||
UInt32 index = i; | UInt32 index = i; | |||
const CRefItem *ref = &_refs[index]; | const CRefItem *ref = &_refs[index]; | |||
const CItem *item = &_items[ref->Item]; | 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); | curPackSize = GetPackSize(index); | |||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); | RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); | |||
bool isSolid; | bool isSolid; | |||
{ | { | |||
bool &needClearSolid = unpacker.NeedClearSolid[item->IsService() ? 1 : 0]; | bool &needClearSolid = unpacker.NeedClearSolid[item->IsService() ? 1 : 0]; | |||
isSolid = (item->IsSolid() && !needClearSolid); | isSolid = (item->IsSolid() && !needClearSolid); | |||
if (item->IsService()) | if (item->IsService()) | |||
isSolid = false; | isSolid = false; | |||
skipping to change at line 2481 | skipping to change at line 2517 | |||
} | } | |||
int index2 = ref->Link; | int index2 = ref->Link; | |||
int bufIndex = -1; | int bufIndex = -1; | |||
if (index2 >= 0) | if (index2 >= 0) | |||
{ | { | |||
const CRefItem &ref2 = _refs[index2]; | const CRefItem &ref2 = _refs[index2]; | |||
const CItem &item2 = _items[ref2.Item]; | const CItem &item2 = _items[ref2.Item]; | |||
const CItem &lastItem2 = _items[ref2.Last]; | ||||
if (!item2.IsSolid()) | if (!item2.IsSolid()) | |||
{ | { | |||
item = &item2; | item = &item2; | |||
ref = &ref2; | ref = &ref2; | |||
curUnpackSize = item->Size; | if (!lastItem2.Is_UnknownSize()) | |||
curUnpackSize = lastItem2.Size; | ||||
else | ||||
curUnpackSize = 0; | ||||
curPackSize = GetPackSize(index2); | curPackSize = GetPackSize(index2); | |||
} | } | |||
else if ((unsigned)index2 < index) | else if ((unsigned)index2 < index) | |||
bufIndex = FindLinkBuf(linkFiles, index2); | bufIndex = FindLinkBuf(linkFiles, index2); | |||
} | } | |||
if (!realOutStream) | if (!realOutStream) | |||
{ | { | |||
if (testMode) | if (testMode) | |||
{ | { | |||
End of changes. 19 change blocks. | ||||
16 lines changed or deleted | 56 lines changed or added |