diff options
Diffstat (limited to '')
-rw-r--r-- | CPP/7zip/Archive/7z/7zOut.cpp | 309 |
1 files changed, 190 insertions, 119 deletions
diff --git a/CPP/7zip/Archive/7z/7zOut.cpp b/CPP/7zip/Archive/7z/7zOut.cpp index 7f8fa5b..d0c8cf2 100644 --- a/CPP/7zip/Archive/7z/7zOut.cpp +++ b/CPP/7zip/Archive/7z/7zOut.cpp | |||
@@ -3,14 +3,34 @@ | |||
3 | #include "StdAfx.h" | 3 | #include "StdAfx.h" |
4 | 4 | ||
5 | #include "../../../../C/7zCrc.h" | 5 | #include "../../../../C/7zCrc.h" |
6 | #include "../../../../C/CpuArch.h" | ||
6 | 7 | ||
7 | #include "../../../Common/AutoPtr.h" | 8 | #include "../../../Common/AutoPtr.h" |
8 | // #include "../../../Common/UTFConvert.h" | 9 | // #include "../../../Common/UTFConvert.h" |
9 | 10 | ||
10 | #include "../../Common/StreamObjects.h" | 11 | #include "../../Common/StreamObjects.h" |
12 | #include "../Common/OutStreamWithCRC.h" | ||
11 | 13 | ||
12 | #include "7zOut.h" | 14 | #include "7zOut.h" |
13 | 15 | ||
16 | unsigned BoolVector_CountSum(const CBoolVector &v); | ||
17 | |||
18 | static UInt64 UInt64Vector_CountSum(const CRecordVector<UInt64> &v) | ||
19 | { | ||
20 | UInt64 sum = 0; | ||
21 | const unsigned size = v.Size(); | ||
22 | if (size) | ||
23 | { | ||
24 | const UInt64 *p = v.ConstData(); | ||
25 | const UInt64 * const lim = p + size; | ||
26 | do | ||
27 | sum += *p++; | ||
28 | while (p != lim); | ||
29 | } | ||
30 | return sum; | ||
31 | } | ||
32 | |||
33 | |||
14 | namespace NArchive { | 34 | namespace NArchive { |
15 | namespace N7z { | 35 | namespace N7z { |
16 | 36 | ||
@@ -133,7 +153,7 @@ void COutArchive::WriteBytes(const void *data, size_t size) | |||
133 | else if (_writeToStream) | 153 | else if (_writeToStream) |
134 | { | 154 | { |
135 | _outByte.WriteBytes(data, size); | 155 | _outByte.WriteBytes(data, size); |
136 | _crc = CrcUpdate(_crc, data, size); | 156 | // _crc = CrcUpdate(_crc, data, size); |
137 | } | 157 | } |
138 | else | 158 | else |
139 | _outByte2.WriteBytes(data, size); | 159 | _outByte2.WriteBytes(data, size); |
@@ -144,14 +164,12 @@ void COutArchive::WriteByte(Byte b) | |||
144 | if (_countMode) | 164 | if (_countMode) |
145 | _countSize++; | 165 | _countSize++; |
146 | else if (_writeToStream) | 166 | else if (_writeToStream) |
147 | { | 167 | WriteByte_ToStream(b); |
148 | _outByte.WriteByte(b); | ||
149 | _crc = CRC_UPDATE_BYTE(_crc, b); | ||
150 | } | ||
151 | else | 168 | else |
152 | _outByte2.WriteByte(b); | 169 | _outByte2.WriteByte(b); |
153 | } | 170 | } |
154 | 171 | ||
172 | /* | ||
155 | void COutArchive::WriteUInt32(UInt32 value) | 173 | void COutArchive::WriteUInt32(UInt32 value) |
156 | { | 174 | { |
157 | for (int i = 0; i < 4; i++) | 175 | for (int i = 0; i < 4; i++) |
@@ -169,6 +187,7 @@ void COutArchive::WriteUInt64(UInt64 value) | |||
169 | value >>= 8; | 187 | value >>= 8; |
170 | } | 188 | } |
171 | } | 189 | } |
190 | */ | ||
172 | 191 | ||
173 | void COutArchive::WriteNumber(UInt64 value) | 192 | void COutArchive::WriteNumber(UInt64 value) |
174 | { | 193 | { |
@@ -288,7 +307,7 @@ void COutArchive::WriteFolder(const CFolder &folder) | |||
288 | WriteNumber(folder.PackStreams[i]); | 307 | WriteNumber(folder.PackStreams[i]); |
289 | } | 308 | } |
290 | 309 | ||
291 | void COutArchive::WriteBoolVector(const CBoolVector &boolVector) | 310 | void COutArchive::Write_BoolVector(const CBoolVector &boolVector) |
292 | { | 311 | { |
293 | Byte b = 0; | 312 | Byte b = 0; |
294 | Byte mask = 0x80; | 313 | Byte mask = 0x80; |
@@ -314,31 +333,32 @@ void COutArchive::WritePropBoolVector(Byte id, const CBoolVector &boolVector) | |||
314 | { | 333 | { |
315 | WriteByte(id); | 334 | WriteByte(id); |
316 | WriteNumber(Bv_GetSizeInBytes(boolVector)); | 335 | WriteNumber(Bv_GetSizeInBytes(boolVector)); |
317 | WriteBoolVector(boolVector); | 336 | Write_BoolVector(boolVector); |
337 | } | ||
338 | |||
339 | void COutArchive::Write_BoolVector_numDefined(const CBoolVector &boolVector, unsigned numDefined) | ||
340 | { | ||
341 | if (numDefined == boolVector.Size()) | ||
342 | WriteByte(1); | ||
343 | else | ||
344 | { | ||
345 | WriteByte(0); | ||
346 | Write_BoolVector(boolVector); | ||
347 | } | ||
318 | } | 348 | } |
319 | 349 | ||
320 | unsigned BoolVector_CountSum(const CBoolVector &v); | ||
321 | 350 | ||
322 | void COutArchive::WriteHashDigests(const CUInt32DefVector &digests) | 351 | void COutArchive::WriteHashDigests(const CUInt32DefVector &digests) |
323 | { | 352 | { |
324 | const unsigned numDefined = BoolVector_CountSum(digests.Defs); | 353 | const unsigned numDefined = BoolVector_CountSum(digests.Defs); |
325 | if (numDefined == 0) | 354 | if (numDefined == 0) |
326 | return; | 355 | return; |
327 | |||
328 | WriteByte(NID::kCRC); | 356 | WriteByte(NID::kCRC); |
329 | if (numDefined == digests.Defs.Size()) | 357 | Write_BoolVector_numDefined(digests.Defs, numDefined); |
330 | WriteByte(1); | 358 | Write_UInt32DefVector_numDefined(digests, numDefined); |
331 | else | ||
332 | { | ||
333 | WriteByte(0); | ||
334 | WriteBoolVector(digests.Defs); | ||
335 | } | ||
336 | |||
337 | for (unsigned i = 0; i < digests.Defs.Size(); i++) | ||
338 | if (digests.Defs[i]) | ||
339 | WriteUInt32(digests.Vals[i]); | ||
340 | } | 359 | } |
341 | 360 | ||
361 | |||
342 | void COutArchive::WritePackInfo( | 362 | void COutArchive::WritePackInfo( |
343 | UInt64 dataOffset, | 363 | UInt64 dataOffset, |
344 | const CRecordVector<UInt64> &packSizes, | 364 | const CRecordVector<UInt64> &packSizes, |
@@ -467,17 +487,42 @@ void COutArchive::WriteAlignedBools(const CBoolVector &v, unsigned numDefined, B | |||
467 | 487 | ||
468 | WriteByte(type); | 488 | WriteByte(type); |
469 | WriteNumber(dataSize); | 489 | WriteNumber(dataSize); |
470 | if (numDefined == v.Size()) | 490 | Write_BoolVector_numDefined(v, numDefined); |
471 | WriteByte(1); | 491 | WriteByte(0); // 0 means no switching to external stream |
472 | else | 492 | } |
493 | |||
494 | |||
495 | void COutArchive::Write_UInt32DefVector_numDefined(const CUInt32DefVector &v, unsigned numDefined) | ||
496 | { | ||
497 | if (_countMode) | ||
473 | { | 498 | { |
474 | WriteByte(0); | 499 | _countSize += (size_t)numDefined * 4; |
475 | WriteBoolVector(v); | 500 | return; |
476 | } | 501 | } |
477 | WriteByte(0); // 0 means no switching to external stream | 502 | |
503 | const bool * const defs = v.Defs.ConstData(); | ||
504 | const UInt32 * const vals = v.Vals.ConstData(); | ||
505 | const size_t num = v.Defs.Size(); | ||
506 | |||
507 | for (size_t i = 0; i < num; i++) | ||
508 | if (defs[i]) | ||
509 | { | ||
510 | UInt32 value = vals[i]; | ||
511 | for (int k = 0; k < 4; k++) | ||
512 | { | ||
513 | if (_writeToStream) | ||
514 | WriteByte_ToStream((Byte)value); | ||
515 | else | ||
516 | _outByte2.WriteByte((Byte)value); | ||
517 | // WriteByte((Byte)value); | ||
518 | value >>= 8; | ||
519 | } | ||
520 | // WriteUInt32(v.Vals[i]); | ||
521 | } | ||
478 | } | 522 | } |
479 | 523 | ||
480 | void COutArchive::WriteUInt64DefVector(const CUInt64DefVector &v, Byte type) | 524 | |
525 | void COutArchive::Write_UInt64DefVector_type(const CUInt64DefVector &v, Byte type) | ||
481 | { | 526 | { |
482 | const unsigned numDefined = BoolVector_CountSum(v.Defs); | 527 | const unsigned numDefined = BoolVector_CountSum(v.Defs); |
483 | if (numDefined == 0) | 528 | if (numDefined == 0) |
@@ -485,18 +530,40 @@ void COutArchive::WriteUInt64DefVector(const CUInt64DefVector &v, Byte type) | |||
485 | 530 | ||
486 | WriteAlignedBools(v.Defs, numDefined, type, 3); | 531 | WriteAlignedBools(v.Defs, numDefined, type, 3); |
487 | 532 | ||
488 | for (unsigned i = 0; i < v.Defs.Size(); i++) | 533 | if (_countMode) |
489 | if (v.Defs[i]) | 534 | { |
490 | WriteUInt64(v.Vals[i]); | 535 | _countSize += (size_t)numDefined * 8; |
536 | return; | ||
537 | } | ||
538 | |||
539 | const bool * const defs = v.Defs.ConstData(); | ||
540 | const UInt64 * const vals = v.Vals.ConstData(); | ||
541 | const size_t num = v.Defs.Size(); | ||
542 | |||
543 | for (size_t i = 0; i < num; i++) | ||
544 | if (defs[i]) | ||
545 | { | ||
546 | UInt64 value = vals[i]; | ||
547 | for (int k = 0; k < 8; k++) | ||
548 | { | ||
549 | if (_writeToStream) | ||
550 | WriteByte_ToStream((Byte)value); | ||
551 | else | ||
552 | _outByte2.WriteByte((Byte)value); | ||
553 | // WriteByte((Byte)value); | ||
554 | value >>= 8; | ||
555 | } | ||
556 | // WriteUInt64(v.Vals[i]); | ||
557 | } | ||
491 | } | 558 | } |
492 | 559 | ||
560 | |||
493 | HRESULT COutArchive::EncodeStream( | 561 | HRESULT COutArchive::EncodeStream( |
494 | DECL_EXTERNAL_CODECS_LOC_VARS | 562 | DECL_EXTERNAL_CODECS_LOC_VARS |
495 | CEncoder &encoder, const CByteBuffer &data, | 563 | CEncoder &encoder, const CByteBuffer &data, |
496 | CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders, COutFolders &outFolders) | 564 | CRecordVector<UInt64> &packSizes, CObjectVector<CFolder> &folders, COutFolders &outFolders) |
497 | { | 565 | { |
498 | CBufInStream *streamSpec = new CBufInStream; | 566 | CMyComPtr2_Create<ISequentialInStream, CBufInStream> streamSpec; |
499 | CMyComPtr<ISequentialInStream> stream = streamSpec; | ||
500 | streamSpec->Init(data, data.Size()); | 567 | streamSpec->Init(data, data.Size()); |
501 | outFolders.FolderUnpackCRCs.Defs.Add(true); | 568 | outFolders.FolderUnpackCRCs.Defs.Add(true); |
502 | outFolders.FolderUnpackCRCs.Vals.Add(CrcCalc(data, data.Size())); | 569 | outFolders.FolderUnpackCRCs.Vals.Add(CrcCalc(data, data.Size())); |
@@ -505,7 +572,7 @@ HRESULT COutArchive::EncodeStream( | |||
505 | const UInt64 expectSize = data.Size(); | 572 | const UInt64 expectSize = data.Size(); |
506 | RINOK(encoder.Encode1( | 573 | RINOK(encoder.Encode1( |
507 | EXTERNAL_CODECS_LOC_VARS | 574 | EXTERNAL_CODECS_LOC_VARS |
508 | stream, | 575 | streamSpec, |
509 | // NULL, | 576 | // NULL, |
510 | &dataSize64, // inSizeForReduce | 577 | &dataSize64, // inSizeForReduce |
511 | expectSize, | 578 | expectSize, |
@@ -528,13 +595,7 @@ void COutArchive::WriteHeader( | |||
528 | */ | 595 | */ |
529 | _useAlign = true; | 596 | _useAlign = true; |
530 | 597 | ||
531 | { | 598 | headerOffset = UInt64Vector_CountSum(db.PackSizes); |
532 | UInt64 packSize = 0; | ||
533 | FOR_VECTOR (i, db.PackSizes) | ||
534 | packSize += db.PackSizes[i]; | ||
535 | headerOffset = packSize; | ||
536 | } | ||
537 | |||
538 | 599 | ||
539 | WriteByte(NID::kHeader); | 600 | WriteByte(NID::kHeader); |
540 | 601 | ||
@@ -655,81 +716,97 @@ void COutArchive::WriteHeader( | |||
655 | { | 716 | { |
656 | /* ---------- Names ---------- */ | 717 | /* ---------- Names ---------- */ |
657 | 718 | ||
658 | unsigned numDefined = 0; | ||
659 | size_t namesDataSize = 0; | 719 | size_t namesDataSize = 0; |
660 | FOR_VECTOR (i, db.Files) | ||
661 | { | 720 | { |
662 | const UString &name = db.Names[i]; | 721 | FOR_VECTOR (i, db.Files) |
663 | if (!name.IsEmpty()) | 722 | { |
664 | numDefined++; | 723 | const UString &name = db.Names[i]; |
665 | const size_t numUtfChars = | 724 | const size_t numUtfChars = |
666 | /* | 725 | /* |
667 | #if WCHAR_MAX > 0xffff | 726 | #if WCHAR_MAX > 0xffff |
668 | Get_Num_Utf16_chars_from_wchar_string(name.Ptr()); | 727 | Get_Num_Utf16_chars_from_wchar_string(name.Ptr()); |
669 | #else | 728 | #else |
670 | */ | 729 | */ |
671 | name.Len(); | 730 | name.Len(); |
672 | // #endif | 731 | // #endif |
673 | namesDataSize += (numUtfChars + 1) * 2; | 732 | namesDataSize += numUtfChars; |
733 | } | ||
674 | } | 734 | } |
675 | 735 | if (namesDataSize) | |
676 | if (numDefined > 0) | ||
677 | { | 736 | { |
678 | namesDataSize++; | 737 | namesDataSize += db.Files.Size(); // we will write tail zero wchar for each name |
738 | namesDataSize *= 2; // 2 bytes per wchar for UTF16 encoding | ||
739 | namesDataSize++; // for additional switch byte (zero value) | ||
679 | SkipToAligned(2 + GetBigNumberSize(namesDataSize), 4); | 740 | SkipToAligned(2 + GetBigNumberSize(namesDataSize), 4); |
680 | |||
681 | WriteByte(NID::kName); | 741 | WriteByte(NID::kName); |
682 | WriteNumber(namesDataSize); | 742 | WriteNumber(namesDataSize); |
683 | WriteByte(0); | 743 | |
684 | FOR_VECTOR (i, db.Files) | 744 | if (_countMode) |
745 | _countSize += namesDataSize; | ||
746 | else | ||
685 | { | 747 | { |
686 | const UString &name = db.Names[i]; | 748 | WriteByte(0); |
687 | for (unsigned t = 0; t <= name.Len(); t++) | 749 | FOR_VECTOR (i, db.Files) |
688 | { | 750 | { |
689 | wchar_t c = name[t]; | 751 | const UString &name = db.Names[i]; |
690 | 752 | const wchar_t *p = name.Ptr(); | |
691 | /* | 753 | const size_t len = (size_t)name.Len() + 1; |
692 | #if WCHAR_MAX > 0xffff | 754 | const wchar_t * const lim = p + len; |
693 | if (c >= 0x10000) | 755 | if (_writeToStream) |
694 | { | 756 | { |
695 | c -= 0x10000; | 757 | do |
696 | if (c < (1 << 20)) | ||
697 | { | 758 | { |
698 | unsigned c0 = 0xd800 + ((c >> 10) & 0x3FF); | 759 | const wchar_t c = *p++; |
699 | WriteByte((Byte)c0); | 760 | WriteByte_ToStream((Byte)c); |
700 | WriteByte((Byte)(c0 >> 8)); | 761 | WriteByte_ToStream((Byte)(c >> 8)); |
701 | c = 0xdc00 + (c & 0x3FF); | ||
702 | } | 762 | } |
703 | else | 763 | while (p != lim); |
704 | c = '_'; // we change character unsupported by UTF16 | 764 | } |
765 | else | ||
766 | { | ||
767 | Byte *dest = _outByte2.GetDest_and_Update(len * 2); | ||
768 | do | ||
769 | { | ||
770 | /* | ||
771 | #if WCHAR_MAX > 0xffff | ||
772 | if (c >= 0x10000) | ||
773 | { | ||
774 | c -= 0x10000; | ||
775 | if (c < (1 << 20)) | ||
776 | { | ||
777 | unsigned c0 = 0xd800 + ((c >> 10) & 0x3FF); | ||
778 | WriteByte((Byte)c0); | ||
779 | WriteByte((Byte)(c0 >> 8)); | ||
780 | c = 0xdc00 + (c & 0x3FF); | ||
781 | } | ||
782 | else | ||
783 | c = '_'; // we change character unsupported by UTF16 | ||
784 | } | ||
785 | #endif | ||
786 | */ | ||
787 | const wchar_t c = *p++; | ||
788 | SetUi16(dest, (UInt16)c) | ||
789 | dest += 2; | ||
790 | } | ||
791 | while (p != lim); | ||
705 | } | 792 | } |
706 | #endif | ||
707 | */ | ||
708 | |||
709 | WriteByte((Byte)c); | ||
710 | WriteByte((Byte)(c >> 8)); | ||
711 | } | 793 | } |
712 | } | 794 | } |
713 | } | 795 | } |
714 | } | 796 | } |
715 | 797 | ||
716 | /* if (headerOptions.WriteCTime) */ WriteUInt64DefVector(db.CTime, NID::kCTime); | 798 | /* if (headerOptions.WriteCTime) */ Write_UInt64DefVector_type(db.CTime, NID::kCTime); |
717 | /* if (headerOptions.WriteATime) */ WriteUInt64DefVector(db.ATime, NID::kATime); | 799 | /* if (headerOptions.WriteATime) */ Write_UInt64DefVector_type(db.ATime, NID::kATime); |
718 | /* if (headerOptions.WriteMTime) */ WriteUInt64DefVector(db.MTime, NID::kMTime); | 800 | /* if (headerOptions.WriteMTime) */ Write_UInt64DefVector_type(db.MTime, NID::kMTime); |
719 | WriteUInt64DefVector(db.StartPos, NID::kStartPos); | 801 | Write_UInt64DefVector_type(db.StartPos, NID::kStartPos); |
720 | 802 | ||
721 | { | 803 | { |
722 | /* ---------- Write Attrib ---------- */ | 804 | /* ---------- Write Attrib ---------- */ |
723 | const unsigned numDefined = BoolVector_CountSum(db.Attrib.Defs); | 805 | const unsigned numDefined = BoolVector_CountSum(db.Attrib.Defs); |
724 | |||
725 | if (numDefined != 0) | 806 | if (numDefined != 0) |
726 | { | 807 | { |
727 | WriteAlignedBools(db.Attrib.Defs, numDefined, NID::kWinAttrib, 2); | 808 | WriteAlignedBools(db.Attrib.Defs, numDefined, NID::kWinAttrib, 2); |
728 | FOR_VECTOR (i, db.Attrib.Defs) | 809 | Write_UInt32DefVector_numDefined(db.Attrib, numDefined); |
729 | { | ||
730 | if (db.Attrib.Defs[i]) | ||
731 | WriteUInt32(db.Attrib.Vals[i]); | ||
732 | } | ||
733 | } | 810 | } |
734 | } | 811 | } |
735 | 812 | ||
@@ -765,13 +842,7 @@ void COutArchive::WriteHeader( | |||
765 | 842 | ||
766 | WriteByte(NID::kParent); | 843 | WriteByte(NID::kParent); |
767 | WriteNumber(dataSize); | 844 | WriteNumber(dataSize); |
768 | if (numIsDir == boolVector.Size()) | 845 | Write_BoolVector_numDefined(boolVector, numIsDir); |
769 | WriteByte(1); | ||
770 | else | ||
771 | { | ||
772 | WriteByte(0); | ||
773 | WriteBoolVector(boolVector); | ||
774 | } | ||
775 | for (i = 0; i < db.Files.Size(); i++) | 846 | for (i = 0; i < db.Files.Size(); i++) |
776 | { | 847 | { |
777 | const CFileItem &file = db.Files[i]; | 848 | const CFileItem &file = db.Files[i]; |
@@ -818,17 +889,17 @@ HRESULT COutArchive::WriteDatabase( | |||
818 | if (!db.CheckNumFiles()) | 889 | if (!db.CheckNumFiles()) |
819 | return E_FAIL; | 890 | return E_FAIL; |
820 | 891 | ||
821 | UInt64 headerOffset; | 892 | CStartHeader sh; |
822 | UInt32 headerCRC; | 893 | sh.NextHeaderOffset = 0; |
823 | UInt64 headerSize; | 894 | sh.NextHeaderSize = 0; |
824 | if (db.IsEmpty()) | 895 | sh.NextHeaderCRC = 0; // CrcCalc(NULL, 0); |
825 | { | 896 | |
826 | headerSize = 0; | 897 | if (!db.IsEmpty()) |
827 | headerOffset = 0; | ||
828 | headerCRC = CrcCalc(NULL, 0); | ||
829 | } | ||
830 | else | ||
831 | { | 898 | { |
899 | CMyComPtr2_Create<ISequentialOutStream, COutStreamWithCRC> crcStream; | ||
900 | crcStream->SetStream(SeqStream); | ||
901 | crcStream->Init(); | ||
902 | |||
832 | bool encodeHeaders = false; | 903 | bool encodeHeaders = false; |
833 | if (options) | 904 | if (options) |
834 | if (options->IsEmpty()) | 905 | if (options->IsEmpty()) |
@@ -837,13 +908,15 @@ HRESULT COutArchive::WriteDatabase( | |||
837 | if (options->PasswordIsDefined || headerOptions.CompressMainHeader) | 908 | if (options->PasswordIsDefined || headerOptions.CompressMainHeader) |
838 | encodeHeaders = true; | 909 | encodeHeaders = true; |
839 | 910 | ||
840 | _outByte.SetStream(SeqStream); | 911 | if (!_outByte.Create(1 << 16)) |
912 | return E_OUTOFMEMORY; | ||
913 | _outByte.SetStream(crcStream.Interface()); | ||
841 | _outByte.Init(); | 914 | _outByte.Init(); |
842 | _crc = CRC_INIT_VAL; | 915 | // _crc = CRC_INIT_VAL; |
843 | _countMode = encodeHeaders; | 916 | _countMode = encodeHeaders; |
844 | _writeToStream = true; | 917 | _writeToStream = true; |
845 | _countSize = 0; | 918 | _countSize = 0; |
846 | WriteHeader(db, /* headerOptions, */ headerOffset); | 919 | WriteHeader(db, /* headerOptions, */ sh.NextHeaderOffset); |
847 | 920 | ||
848 | if (encodeHeaders) | 921 | if (encodeHeaders) |
849 | { | 922 | { |
@@ -852,7 +925,7 @@ HRESULT COutArchive::WriteDatabase( | |||
852 | 925 | ||
853 | _countMode = false; | 926 | _countMode = false; |
854 | _writeToStream = false; | 927 | _writeToStream = false; |
855 | WriteHeader(db, /* headerOptions, */ headerOffset); | 928 | WriteHeader(db, /* headerOptions, */ sh.NextHeaderOffset); |
856 | 929 | ||
857 | if (_countSize != _outByte2.GetPos()) | 930 | if (_countSize != _outByte2.GetPos()) |
858 | return E_FAIL; | 931 | return E_FAIL; |
@@ -876,15 +949,17 @@ HRESULT COutArchive::WriteDatabase( | |||
876 | throw 1; | 949 | throw 1; |
877 | 950 | ||
878 | WriteID(NID::kEncodedHeader); | 951 | WriteID(NID::kEncodedHeader); |
879 | WritePackInfo(headerOffset, packSizes, CUInt32DefVector()); | 952 | WritePackInfo(sh.NextHeaderOffset, packSizes, CUInt32DefVector()); |
880 | WriteUnpackInfo(folders, outFolders); | 953 | WriteUnpackInfo(folders, outFolders); |
881 | WriteByte(NID::kEnd); | 954 | WriteByte(NID::kEnd); |
882 | FOR_VECTOR (i, packSizes) | 955 | |
883 | headerOffset += packSizes[i]; | 956 | sh.NextHeaderOffset += UInt64Vector_CountSum(packSizes); |
884 | } | 957 | } |
885 | RINOK(_outByte.Flush()) | 958 | RINOK(_outByte.Flush()) |
886 | headerCRC = CRC_GET_DIGEST(_crc); | 959 | sh.NextHeaderCRC = crcStream->GetCRC(); |
887 | headerSize = _outByte.GetProcessedSize(); | 960 | // sh.NextHeaderCRC = CRC_GET_DIGEST(_crc); |
961 | // if (CRC_GET_DIGEST(_crc) != sh.NextHeaderCRC) throw 1; | ||
962 | sh.NextHeaderSize = _outByte.GetProcessedSize(); | ||
888 | } | 963 | } |
889 | #ifdef Z7_7Z_VOL | 964 | #ifdef Z7_7Z_VOL |
890 | if (_endMarker) | 965 | if (_endMarker) |
@@ -904,12 +979,8 @@ HRESULT COutArchive::WriteDatabase( | |||
904 | #endif | 979 | #endif |
905 | if (Stream) | 980 | if (Stream) |
906 | { | 981 | { |
907 | CStartHeader h; | ||
908 | h.NextHeaderSize = headerSize; | ||
909 | h.NextHeaderCRC = headerCRC; | ||
910 | h.NextHeaderOffset = headerOffset; | ||
911 | RINOK(Stream->Seek((Int64)_signatureHeaderPos, STREAM_SEEK_SET, NULL)) | 982 | RINOK(Stream->Seek((Int64)_signatureHeaderPos, STREAM_SEEK_SET, NULL)) |
912 | return WriteStartHeader(h); | 983 | return WriteStartHeader(sh); |
913 | } | 984 | } |
914 | return S_OK; | 985 | return S_OK; |
915 | } | 986 | } |