diff options
Diffstat (limited to 'CPP/7zip/Archive/LzhHandler.cpp')
-rw-r--r-- | CPP/7zip/Archive/LzhHandler.cpp | 122 |
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 | ||
54 | static class CLzhCrc16TableInit | 54 | static struct CLzhCrc16TableInit |
55 | { | 55 | { |
56 | public: | ||
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 | ||
383 | class COutStreamWithCRC: | 382 | Z7_CLASS_IMP_NOQIB_1( |
384 | public ISequentialOutStream, | 383 | COutStreamWithCRC |
385 | public CMyUnknownImp | 384 | , ISequentialOutStream |
386 | { | 385 | ) |
387 | public: | ||
388 | MY_UNKNOWN_IMP | ||
389 | |||
390 | STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); | ||
391 | private: | ||
392 | UInt32 _crc; | 386 | UInt32 _crc; |
393 | CMyComPtr<ISequentialOutStream> _stream; | 387 | CMyComPtr<ISequentialOutStream> _stream; |
394 | public: | 388 | public: |
@@ -401,7 +395,7 @@ public: | |||
401 | UInt32 GetCRC() const { return _crc; } | 395 | UInt32 GetCRC() const { return _crc; } |
402 | }; | 396 | }; |
403 | 397 | ||
404 | STDMETHODIMP COutStreamWithCRC::Write(const void *data, UInt32 size, UInt32 *processedSize) | 398 | Z7_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 | ||
422 | class CHandler: | 416 | Z7_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; |
431 | public: | 423 | public: |
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 | ||
440 | CHandler::CHandler() {} | 430 | CHandler::CHandler() {} |
441 | 431 | ||
442 | STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems) | 432 | Z7_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 | ||
448 | STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value) | 438 | Z7_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 | ||
465 | STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value) | 455 | Z7_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 | ||
512 | STDMETHODIMP CHandler::Open(IInStream *stream, | 502 | Z7_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 | ||
585 | STDMETHODIMP CHandler::Close() | 574 | Z7_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 | ||
595 | STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, | 584 | Z7_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, | |||
736 | static const Byte k_Signature[] = { '-', 'l', 'h' }; | 724 | static const Byte k_Signature[] = { '-', 'l', 'h' }; |
737 | 725 | ||
738 | REGISTER_ARC_I( | 726 | REGISTER_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, |