aboutsummaryrefslogtreecommitdiff
path: root/CPP/7zip/Archive/LzhHandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/7zip/Archive/LzhHandler.cpp')
-rw-r--r--CPP/7zip/Archive/LzhHandler.cpp122
1 files changed, 55 insertions, 67 deletions
diff --git a/CPP/7zip/Archive/LzhHandler.cpp b/CPP/7zip/Archive/LzhHandler.cpp
index 6711da6..9239afd 100644
--- a/CPP/7zip/Archive/LzhHandler.cpp
+++ b/CPP/7zip/Archive/LzhHandler.cpp
@@ -51,9 +51,8 @@ UInt32 LzhCrc16Update(UInt32 crc, const void *data, size_t size)
51 return crc; 51 return crc;
52} 52}
53 53
54static class CLzhCrc16TableInit 54static struct CLzhCrc16TableInit
55{ 55{
56public:
57 CLzhCrc16TableInit() 56 CLzhCrc16TableInit()
58 { 57 {
59 for (UInt32 i = 0; i < 256; i++) 58 for (UInt32 i = 0; i < 256; i++)
@@ -176,7 +175,7 @@ struct CItem
176 { 175 {
177 FOR_VECTOR (i, Extensions) 176 FOR_VECTOR (i, Extensions)
178 if (Extensions[i].Type == type) 177 if (Extensions[i].Type == type)
179 return i; 178 return (int)i;
180 return -1; 179 return -1;
181 } 180 }
182 181
@@ -239,10 +238,10 @@ static const Byte *ReadString(const Byte *p, size_t size, AString &s)
239 s.Empty(); 238 s.Empty();
240 for (size_t i = 0; i < size; i++) 239 for (size_t i = 0; i < size; i++)
241 { 240 {
242 char c = p[i]; 241 const Byte c = p[i];
243 if (c == 0) 242 if (c == 0)
244 break; 243 break;
245 s += c; 244 s += (char)c;
246 } 245 }
247 return p + size; 246 return p + size;
248} 247}
@@ -271,7 +270,7 @@ static HRESULT GetNextItem(ISequentialInStream *stream, bool &filled, CItem &ite
271 270
272 Byte header[256]; 271 Byte header[256];
273 processedSize = kBasicPartSize; 272 processedSize = kBasicPartSize;
274 RINOK(ReadStream(stream, header, &processedSize)); 273 RINOK(ReadStream(stream, header, &processedSize))
275 if (processedSize != kBasicPartSize) 274 if (processedSize != kBasicPartSize)
276 return (startHeader[0] == 0) ? S_OK: S_FALSE; 275 return (startHeader[0] == 0) ? S_OK: S_FALSE;
277 276
@@ -294,11 +293,11 @@ static HRESULT GetNextItem(ISequentialInStream *stream, bool &filled, CItem &ite
294 headerSize = startHeader[0]; 293 headerSize = startHeader[0];
295 if (headerSize < kBasicPartSize) 294 if (headerSize < kBasicPartSize)
296 return S_FALSE; 295 return S_FALSE;
297 RINOK(ReadStream_FALSE(stream, header + kBasicPartSize, headerSize - kBasicPartSize)); 296 RINOK(ReadStream_FALSE(stream, header + kBasicPartSize, headerSize - kBasicPartSize))
298 if (startHeader[1] != CalcSum(header, headerSize)) 297 if (startHeader[1] != CalcSum(header, headerSize))
299 return S_FALSE; 298 return S_FALSE;
300 size_t nameLength = *p++; 299 const size_t nameLength = *p++;
301 if ((p - header) + nameLength + 2 > headerSize) 300 if ((size_t)(p - header) + nameLength + 2 > headerSize)
302 return S_FALSE; 301 return S_FALSE;
303 p = ReadString(p, nameLength, item.Name); 302 p = ReadString(p, nameLength, item.Name);
304 } 303 }
@@ -309,7 +308,7 @@ static HRESULT GetNextItem(ISequentialInStream *stream, bool &filled, CItem &ite
309 { 308 {
310 if (item.Level == 2) 309 if (item.Level == 2)
311 { 310 {
312 RINOK(ReadStream_FALSE(stream, header + kBasicPartSize, 2)); 311 RINOK(ReadStream_FALSE(stream, header + kBasicPartSize, 2))
313 } 312 }
314 if ((size_t)(p - header) + 3 > headerSize) 313 if ((size_t)(p - header) + 3 > headerSize)
315 return S_FALSE; 314 return S_FALSE;
@@ -335,7 +334,7 @@ static HRESULT GetNextItem(ISequentialInStream *stream, bool &filled, CItem &ite
335 RINOK(ReadStream_FALSE(stream, (Byte *)ext.Data, nextSize)) 334 RINOK(ReadStream_FALSE(stream, (Byte *)ext.Data, nextSize))
336 item.Extensions.Add(ext); 335 item.Extensions.Add(ext);
337 Byte hdr2[2]; 336 Byte hdr2[2];
338 RINOK(ReadStream_FALSE(stream, hdr2, 2)); 337 RINOK(ReadStream_FALSE(stream, hdr2, 2))
339 ReadUInt16(hdr2, nextSize); 338 ReadUInt16(hdr2, nextSize);
340 } 339 }
341 } 340 }
@@ -380,15 +379,10 @@ static const Byte kProps[] =
380}; 379};
381 380
382 381
383class COutStreamWithCRC: 382Z7_CLASS_IMP_NOQIB_1(
384 public ISequentialOutStream, 383 COutStreamWithCRC
385 public CMyUnknownImp 384 , ISequentialOutStream
386{ 385)
387public:
388 MY_UNKNOWN_IMP
389
390 STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
391private:
392 UInt32 _crc; 386 UInt32 _crc;
393 CMyComPtr<ISequentialOutStream> _stream; 387 CMyComPtr<ISequentialOutStream> _stream;
394public: 388public:
@@ -401,7 +395,7 @@ public:
401 UInt32 GetCRC() const { return _crc; } 395 UInt32 GetCRC() const { return _crc; }
402}; 396};
403 397
404STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize) 398Z7_COM7F_IMF(COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize))
405{ 399{
406 HRESULT res = S_OK; 400 HRESULT res = S_OK;
407 if (_stream) 401 if (_stream)
@@ -419,18 +413,14 @@ struct CItemEx: public CItem
419}; 413};
420 414
421 415
422class CHandler: 416Z7_CLASS_IMP_CHandler_IInArchive_0
423 public IInArchive, 417
424 public CMyUnknownImp
425{
426 CObjectVector<CItemEx> _items; 418 CObjectVector<CItemEx> _items;
427 CMyComPtr<IInStream> _stream; 419 CMyComPtr<IInStream> _stream;
428 UInt64 _phySize; 420 UInt64 _phySize;
429 UInt32 _errorFlags; 421 UInt32 _errorFlags;
430 bool _isArc; 422 bool _isArc;
431public: 423public:
432 MY_UNKNOWN_IMP1(IInArchive)
433 INTERFACE_IInArchive(;)
434 CHandler(); 424 CHandler();
435}; 425};
436 426
@@ -439,13 +429,13 @@ IMP_IInArchive_ArcProps_NO_Table
439 429
440CHandler::CHandler() {} 430CHandler::CHandler() {}
441 431
442STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) 432Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems))
443{ 433{
444 *numItems = _items.Size(); 434 *numItems = _items.Size();
445 return S_OK; 435 return S_OK;
446} 436}
447 437
448STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) 438Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
449{ 439{
450 NCOM::CPropVariant prop; 440 NCOM::CPropVariant prop;
451 switch (propID) 441 switch (propID)
@@ -462,7 +452,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
462 return S_OK; 452 return S_OK;
463} 453}
464 454
465STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) 455Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value))
466{ 456{
467 COM_TRY_BEGIN 457 COM_TRY_BEGIN
468 NCOM::CPropVariant prop; 458 NCOM::CPropVariant prop;
@@ -509,8 +499,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
509 COM_TRY_END 499 COM_TRY_END
510} 500}
511 501
512STDMETHODIMP CHandler::Open(IInStream *stream, 502Z7_COM7F_IMF(CHandler::Open(IInStream *stream,
513 const UInt64 * /* maxCheckStartPosition */, IArchiveOpenCallback *callback) 503 const UInt64 * /* maxCheckStartPosition */, IArchiveOpenCallback *callback))
514{ 504{
515 COM_TRY_BEGIN 505 COM_TRY_BEGIN
516 Close(); 506 Close();
@@ -518,18 +508,17 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
518 { 508 {
519 _items.Clear(); 509 _items.Clear();
520 510
521 UInt64 endPos = 0; 511 UInt64 endPos;
522 bool needSetTotal = true; 512 bool needSetTotal = true;
523 513
524 RINOK(stream->Seek(0, STREAM_SEEK_END, &endPos)); 514 RINOK(InStream_AtBegin_GetSize(stream, endPos))
525 RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
526 515
527 for (;;) 516 for (;;)
528 { 517 {
529 CItemEx item; 518 CItemEx item;
530 bool filled; 519 bool filled;
531 HRESULT res = GetNextItem(stream, filled, item); 520 const HRESULT res = GetNextItem(stream, filled, item);
532 RINOK(stream->Seek(0, STREAM_SEEK_CUR, &item.DataPosition)); 521 RINOK(InStream_GetPos(stream, item.DataPosition))
533 if (res == S_FALSE) 522 if (res == S_FALSE)
534 { 523 {
535 _errorFlags = kpv_ErrorFlags_HeadersError; 524 _errorFlags = kpv_ErrorFlags_HeadersError;
@@ -546,7 +535,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
546 _isArc = true; 535 _isArc = true;
547 536
548 UInt64 newPostion; 537 UInt64 newPostion;
549 RINOK(stream->Seek(item.PackSize, STREAM_SEEK_CUR, &newPostion)); 538 RINOK(stream->Seek(item.PackSize, STREAM_SEEK_CUR, &newPostion))
550 if (newPostion > endPos) 539 if (newPostion > endPos)
551 { 540 {
552 _phySize = endPos; 541 _phySize = endPos;
@@ -558,14 +547,14 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
558 { 547 {
559 if (needSetTotal) 548 if (needSetTotal)
560 { 549 {
561 RINOK(callback->SetTotal(NULL, &endPos)); 550 RINOK(callback->SetTotal(NULL, &endPos))
562 needSetTotal = false; 551 needSetTotal = false;
563 } 552 }
564 if (_items.Size() % 100 == 0) 553 if (_items.Size() % 100 == 0)
565 { 554 {
566 UInt64 numFiles = _items.Size(); 555 UInt64 numFiles = _items.Size();
567 UInt64 numBytes = item.DataPosition; 556 UInt64 numBytes = item.DataPosition;
568 RINOK(callback->SetCompleted(&numFiles, &numBytes)); 557 RINOK(callback->SetCompleted(&numFiles, &numBytes))
569 } 558 }
570 } 559 }
571 } 560 }
@@ -582,7 +571,7 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
582 return S_OK; 571 return S_OK;
583} 572}
584 573
585STDMETHODIMP CHandler::Close() 574Z7_COM7F_IMF(CHandler::Close())
586{ 575{
587 _isArc = false; 576 _isArc = false;
588 _phySize = 0; 577 _phySize = 0;
@@ -592,30 +581,28 @@ STDMETHODIMP CHandler::Close()
592 return S_OK; 581 return S_OK;
593} 582}
594 583
595STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, 584Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
596 Int32 testModeSpec, IArchiveExtractCallback *extractCallback) 585 Int32 testMode, IArchiveExtractCallback *extractCallback))
597{ 586{
598 COM_TRY_BEGIN 587 COM_TRY_BEGIN
599 bool testMode = (testModeSpec != 0); 588 const bool allFilesMode = (numItems == (UInt32)(Int32)-1);
600 UInt64 totalUnPacked = 0, totalPacked = 0;
601 bool allFilesMode = (numItems == (UInt32)(Int32)-1);
602 if (allFilesMode) 589 if (allFilesMode)
603 numItems = _items.Size(); 590 numItems = _items.Size();
604 if (numItems == 0) 591 if (numItems == 0)
605 return S_OK; 592 return S_OK;
593 UInt64 totalUnPacked = 0 /* , totalPacked = 0 */;
606 UInt32 i; 594 UInt32 i;
607 for (i = 0; i < numItems; i++) 595 for (i = 0; i < numItems; i++)
608 { 596 {
609 const CItemEx &item = _items[allFilesMode ? i : indices[i]]; 597 const CItemEx &item = _items[allFilesMode ? i : indices[i]];
610 totalUnPacked += item.Size; 598 totalUnPacked += item.Size;
611 totalPacked += item.PackSize; 599 // totalPacked += item.PackSize;
612 } 600 }
613 RINOK(extractCallback->SetTotal(totalUnPacked)); 601 RINOK(extractCallback->SetTotal(totalUnPacked))
614 602
615 UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0;
616 UInt64 currentItemUnPacked, currentItemPacked; 603 UInt64 currentItemUnPacked, currentItemPacked;
617 604
618 NCompress::NLzh::NDecoder::CCoder *lzhDecoderSpec = 0; 605 NCompress::NLzh::NDecoder::CCoder *lzhDecoderSpec = NULL;
619 CMyComPtr<ICompressCoder> lzhDecoder; 606 CMyComPtr<ICompressCoder> lzhDecoder;
620 // CMyComPtr<ICompressCoder> lzh1Decoder; 607 // CMyComPtr<ICompressCoder> lzh1Decoder;
621 // CMyComPtr<ICompressCoder> arj2Decoder; 608 // CMyComPtr<ICompressCoder> arj2Decoder;
@@ -631,30 +618,32 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
631 CMyComPtr<ISequentialInStream> inStream(streamSpec); 618 CMyComPtr<ISequentialInStream> inStream(streamSpec);
632 streamSpec->SetStream(_stream); 619 streamSpec->SetStream(_stream);
633 620
634 for (i = 0; i < numItems; i++, currentTotalUnPacked += currentItemUnPacked, 621 for (i = 0;; i++,
635 currentTotalPacked += currentItemPacked) 622 lps->OutSize += currentItemUnPacked,
623 lps->InSize += currentItemPacked)
636 { 624 {
637 currentItemUnPacked = 0; 625 currentItemUnPacked = 0;
638 currentItemPacked = 0; 626 currentItemPacked = 0;
639 627
640 lps->InSize = currentTotalPacked; 628 RINOK(lps->SetCur())
641 lps->OutSize = currentTotalUnPacked; 629
642 RINOK(lps->SetCur()); 630 if (i >= numItems)
631 break;
643 632
644 CMyComPtr<ISequentialOutStream> realOutStream; 633 CMyComPtr<ISequentialOutStream> realOutStream;
645 Int32 askMode; 634 const Int32 askMode = testMode ?
646 askMode = testMode ? NExtract::NAskMode::kTest : 635 NExtract::NAskMode::kTest :
647 NExtract::NAskMode::kExtract; 636 NExtract::NAskMode::kExtract;
648 Int32 index = allFilesMode ? i : indices[i]; 637 const UInt32 index = allFilesMode ? i : indices[i];
649 const CItemEx &item = _items[index]; 638 const CItemEx &item = _items[index];
650 RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); 639 RINOK(extractCallback->GetStream(index, &realOutStream, askMode))
651 640
652 if (item.IsDir()) 641 if (item.IsDir())
653 { 642 {
654 // if (!testMode) 643 // if (!testMode)
655 { 644 {
656 RINOK(extractCallback->PrepareOperation(askMode)); 645 RINOK(extractCallback->PrepareOperation(askMode))
657 RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)); 646 RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK))
658 } 647 }
659 continue; 648 continue;
660 } 649 }
@@ -662,7 +651,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
662 if (!testMode && !realOutStream) 651 if (!testMode && !realOutStream)
663 continue; 652 continue;
664 653
665 RINOK(extractCallback->PrepareOperation(askMode)); 654 RINOK(extractCallback->PrepareOperation(askMode))
666 currentItemUnPacked = item.Size; 655 currentItemUnPacked = item.Size;
667 currentItemPacked = item.PackSize; 656 currentItemPacked = item.PackSize;
668 657
@@ -672,8 +661,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
672 outStreamSpec->Init(realOutStream); 661 outStreamSpec->Init(realOutStream);
673 realOutStream.Release(); 662 realOutStream.Release();
674 663
675 UInt64 pos; 664 RINOK(InStream_SeekSet(_stream, item.DataPosition))
676 _stream->Seek(item.DataPosition, STREAM_SEEK_SET, &pos);
677 665
678 streamSpec->Init(item.PackSize); 666 streamSpec->Init(item.PackSize);
679 667
@@ -720,13 +708,13 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
720 opRes = NExtract::NOperationResult::kDataError; 708 opRes = NExtract::NOperationResult::kDataError;
721 else 709 else
722 { 710 {
723 RINOK(res); 711 RINOK(res)
724 if (outStreamSpec->GetCRC() != item.CRC) 712 if (outStreamSpec->GetCRC() != item.CRC)
725 opRes = NExtract::NOperationResult::kCRCError; 713 opRes = NExtract::NOperationResult::kCRCError;
726 } 714 }
727 } 715 }
728 outStream.Release(); 716 outStream.Release();
729 RINOK(extractCallback->SetOperationResult(opRes)); 717 RINOK(extractCallback->SetOperationResult(opRes))
730 } 718 }
731 } 719 }
732 return S_OK; 720 return S_OK;
@@ -736,7 +724,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
736static const Byte k_Signature[] = { '-', 'l', 'h' }; 724static const Byte k_Signature[] = { '-', 'l', 'h' };
737 725
738REGISTER_ARC_I( 726REGISTER_ARC_I(
739 "Lzh", "lzh lha", 0, 6, 727 "Lzh", "lzh lha", NULL, 6,
740 k_Signature, 728 k_Signature,
741 2, 729 2,
742 0, 730 0,