diff options
Diffstat (limited to '')
-rw-r--r-- | CPP/7zip/Archive/LzhHandler.cpp | 118 |
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 | ||
38 | static const UInt16 kCrc16Poly = 0xA001; | 39 | static const UInt16 kCrc16Poly = 0xA001; |
39 | 40 | ||
41 | MY_ALIGN(64) | ||
40 | static UInt16 g_LzhCrc16Table[256]; | 42 | static 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, ¤tItemUnPacked, 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, ¤tItemUnPacked, 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 |