aboutsummaryrefslogtreecommitdiff
path: root/CPP/7zip/Archive/LzhHandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--CPP/7zip/Archive/LzhHandler.cpp118
1 files changed, 52 insertions, 66 deletions
diff --git a/CPP/7zip/Archive/LzhHandler.cpp b/CPP/7zip/Archive/LzhHandler.cpp
index 9239afd..adfe59d 100644
--- a/CPP/7zip/Archive/LzhHandler.cpp
+++ b/CPP/7zip/Archive/LzhHandler.cpp
@@ -4,6 +4,7 @@
4 4
5#include "../../../C/CpuArch.h" 5#include "../../../C/CpuArch.h"
6 6
7#include "../../Common/AutoPtr.h"
7#include "../../Common/ComTry.h" 8#include "../../Common/ComTry.h"
8#include "../../Common/MyBuffer.h" 9#include "../../Common/MyBuffer.h"
9#include "../../Common/StringConvert.h" 10#include "../../Common/StringConvert.h"
@@ -37,6 +38,7 @@ using namespace NTime;
37 38
38static const UInt16 kCrc16Poly = 0xA001; 39static const UInt16 kCrc16Poly = 0xA001;
39 40
41MY_ALIGN(64)
40static UInt16 g_LzhCrc16Table[256]; 42static UInt16 g_LzhCrc16Table[256];
41 43
42#define CRC16_UPDATE_BYTE(crc, b) (g_LzhCrc16Table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) 44#define CRC16_UPDATE_BYTE(crc, b) (g_LzhCrc16Table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
@@ -219,7 +221,7 @@ struct CItem
219 AString s (GetDirName()); 221 AString s (GetDirName());
220 const char kDirSeparator = '\\'; 222 const char kDirSeparator = '\\';
221 // check kDirSeparator in Linux 223 // check kDirSeparator in Linux
222 s.Replace((char)(unsigned char)0xFF, kDirSeparator); 224 s.Replace((char)(Byte)0xFF, kDirSeparator);
223 if (!s.IsEmpty() && s.Back() != kDirSeparator) 225 if (!s.IsEmpty() && s.Back() != kDirSeparator)
224 s += kDirSeparator; 226 s += kDirSeparator;
225 s += GetFileName(); 227 s += GetFileName();
@@ -552,8 +554,8 @@ Z7_COM7F_IMF(CHandler::Open(IInStream *stream,
552 } 554 }
553 if (_items.Size() % 100 == 0) 555 if (_items.Size() % 100 == 0)
554 { 556 {
555 UInt64 numFiles = _items.Size(); 557 const UInt64 numFiles = _items.Size();
556 UInt64 numBytes = item.DataPosition; 558 const UInt64 numBytes = item.DataPosition;
557 RINOK(callback->SetCompleted(&numFiles, &numBytes)) 559 RINOK(callback->SetCompleted(&numFiles, &numBytes))
558 } 560 }
559 } 561 }
@@ -600,91 +602,76 @@ Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
600 } 602 }
601 RINOK(extractCallback->SetTotal(totalUnPacked)) 603 RINOK(extractCallback->SetTotal(totalUnPacked))
602 604
603 UInt64 currentItemUnPacked, currentItemPacked; 605 UInt32 cur_Unpacked, cur_Packed;
604
605 NCompress::NLzh::NDecoder::CCoder *lzhDecoderSpec = NULL;
606 CMyComPtr<ICompressCoder> lzhDecoder;
607 // CMyComPtr<ICompressCoder> lzh1Decoder;
608 // CMyComPtr<ICompressCoder> arj2Decoder;
609
610 NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
611 CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
612 606
613 CLocalProgress *lps = new CLocalProgress; 607 CMyComPtr2_Create<ICompressProgressInfo, CLocalProgress> lps;
614 CMyComPtr<ICompressProgressInfo> progress = lps;
615 lps->Init(extractCallback, false); 608 lps->Init(extractCallback, false);
616 609 CMyUniquePtr<NCompress::NLzh::NDecoder::CCoder> lzhDecoder;
617 CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream; 610 CMyComPtr2_Create<ICompressCoder, NCompress::CCopyCoder> copyCoder;
618 CMyComPtr<ISequentialInStream> inStream(streamSpec); 611 CMyComPtr2_Create<ISequentialInStream, CLimitedSequentialInStream> inStream;
619 streamSpec->SetStream(_stream); 612 inStream->SetStream(_stream);
620 613
621 for (i = 0;; i++, 614 for (i = 0;; i++,
622 lps->OutSize += currentItemUnPacked, 615 lps->OutSize += cur_Unpacked,
623 lps->InSize += currentItemPacked) 616 lps->InSize += cur_Packed)
624 { 617 {
625 currentItemUnPacked = 0; 618 cur_Unpacked = 0;
626 currentItemPacked = 0; 619 cur_Packed = 0;
627
628 RINOK(lps->SetCur()) 620 RINOK(lps->SetCur())
629
630 if (i >= numItems) 621 if (i >= numItems)
631 break; 622 break;
632 623
633 CMyComPtr<ISequentialOutStream> realOutStream; 624 Int32 opRes;
634 const Int32 askMode = testMode ?
635 NExtract::NAskMode::kTest :
636 NExtract::NAskMode::kExtract;
637 const UInt32 index = allFilesMode ? i : indices[i];
638 const CItemEx &item = _items[index];
639 RINOK(extractCallback->GetStream(index, &realOutStream, askMode))
640
641 if (item.IsDir())
642 { 625 {
643 // if (!testMode) 626 CMyComPtr<ISequentialOutStream> realOutStream;
627 const Int32 askMode = testMode ?
628 NExtract::NAskMode::kTest :
629 NExtract::NAskMode::kExtract;
630 const UInt32 index = allFilesMode ? i : indices[i];
631 const CItemEx &item = _items[index];
632 RINOK(extractCallback->GetStream(index, &realOutStream, askMode))
633
634 if (item.IsDir())
644 { 635 {
645 RINOK(extractCallback->PrepareOperation(askMode)) 636 // if (!testMode)
646 RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK)) 637 {
638 RINOK(extractCallback->PrepareOperation(askMode))
639 RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK))
640 }
641 continue;
647 } 642 }
648 continue; 643
649 } 644 if (!testMode && !realOutStream)
650 645 continue;
651 if (!testMode && !realOutStream) 646
652 continue; 647 RINOK(extractCallback->PrepareOperation(askMode))
653 648 cur_Unpacked = item.Size;
654 RINOK(extractCallback->PrepareOperation(askMode)) 649 cur_Packed = item.PackSize;
655 currentItemUnPacked = item.Size;
656 currentItemPacked = item.PackSize;
657 650
658 { 651 CMyComPtr2_Create<ISequentialOutStream, COutStreamWithCRC> outStream;
659 COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC; 652 outStream->Init(realOutStream);
660 CMyComPtr<ISequentialOutStream> outStream(outStreamSpec);
661 outStreamSpec->Init(realOutStream);
662 realOutStream.Release(); 653 realOutStream.Release();
663 654
664 RINOK(InStream_SeekSet(_stream, item.DataPosition)) 655 RINOK(InStream_SeekSet(_stream, item.DataPosition))
665 656
666 streamSpec->Init(item.PackSize); 657 inStream->Init(item.PackSize);
667 658
668 HRESULT res = S_OK; 659 HRESULT res = S_OK;
669 Int32 opRes = NExtract::NOperationResult::kOK; 660 opRes = NExtract::NOperationResult::kOK;
670 661
671 if (item.IsCopyMethod()) 662 if (item.IsCopyMethod())
672 { 663 {
673 res = copyCoder->Code(inStream, outStream, NULL, NULL, progress); 664 res = copyCoder.Interface()->Code(inStream, outStream, NULL, NULL, lps);
674 if (res == S_OK && copyCoderSpec->TotalSize != item.PackSize) 665 if (res == S_OK && copyCoder->TotalSize != item.PackSize)
675 res = S_FALSE; 666 res = S_FALSE;
676 } 667 }
677 else if (item.IsLh4GroupMethod()) 668 else if (item.IsLh4GroupMethod())
678 { 669 {
679 if (!lzhDecoder) 670 lzhDecoder.Create_if_Empty();
680 { 671 // lzhDecoder->FinishMode = true;
681 lzhDecoderSpec = new NCompress::NLzh::NDecoder::CCoder; 672 lzhDecoder->SetDictSize((UInt32)1 << item.GetNumDictBits());
682 lzhDecoder = lzhDecoderSpec; 673 res = lzhDecoder->Code(inStream, outStream, cur_Unpacked, lps);
683 } 674 if (res == S_OK && lzhDecoder->GetInputProcessedSize() != item.PackSize)
684 lzhDecoderSpec->FinishMode = true;
685 lzhDecoderSpec->SetDictSize(1 << item.GetNumDictBits());
686 res = lzhDecoder->Code(inStream, outStream, NULL, &currentItemUnPacked, progress);
687 if (res == S_OK && lzhDecoderSpec->GetInputProcessedSize() != item.PackSize)
688 res = S_FALSE; 675 res = S_FALSE;
689 } 676 }
690 /* 677 /*
@@ -696,7 +683,7 @@ Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
696 lzh1Decoder = lzh1DecoderSpec; 683 lzh1Decoder = lzh1DecoderSpec;
697 } 684 }
698 lzh1DecoderSpec->SetDictionary(item.GetNumDictBits()); 685 lzh1DecoderSpec->SetDictionary(item.GetNumDictBits());
699 res = lzh1Decoder->Code(inStream, outStream, NULL, &currentItemUnPacked, progress); 686 res = lzh1Decoder->Code(inStream, outStream, NULL, &cur_Unpacked, progress);
700 } 687 }
701 */ 688 */
702 else 689 else
@@ -709,13 +696,12 @@ Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
709 else 696 else
710 { 697 {
711 RINOK(res) 698 RINOK(res)
712 if (outStreamSpec->GetCRC() != item.CRC) 699 if (outStream->GetCRC() != item.CRC)
713 opRes = NExtract::NOperationResult::kCRCError; 700 opRes = NExtract::NOperationResult::kCRCError;
714 } 701 }
715 } 702 }
716 outStream.Release();
717 RINOK(extractCallback->SetOperationResult(opRes))
718 } 703 }
704 RINOK(extractCallback->SetOperationResult(opRes))
719 } 705 }
720 return S_OK; 706 return S_OK;
721 COM_TRY_END 707 COM_TRY_END