void CInArchive::ReadUnpackInfo( const CObjectVector<CByteBuffer> *dataVector, CObjectVector<CFolder> &folders) { WaitAttribute(NID::kFolder); CNum numFolders = ReadNum(); { CStreamSwitch streamSwitch; streamSwitch.Set(this, dataVector); folders.Clear(); folders.Reserve(numFolders); for (CNum i = 0; i < numFolders; i++) { folders.Add(CFolder()); GetNextFolderItem(folders.Back()); } } WaitAttribute(NID::kCodersUnpackSize); CNum i; for (i = 0; i < numFolders; i++) { CFolder &folder = folders[i]; CNum numOutStreams = folder.GetNumOutStreams(); folder.UnpackSizes.Reserve(numOutStreams); for (CNum j = 0; j < numOutStreams; j++) folder.UnpackSizes.Add(ReadNumber()); } for (;;) { UInt64 type = ReadID(); if (type == NID::kEnd) return; if (type == NID::kCRC) { CBoolVector crcsDefined; CRecordVector<UInt32> crcs; ReadHashDigests(numFolders, crcsDefined, crcs); for (i = 0; i < numFolders; i++) { CFolder &folder = folders[i]; folder.UnpackCRCDefined = crcsDefined[i]; folder.UnpackCRC = crcs[i]; } continue; } SkipData(); } }
void CInArchive::ReadPackInfo( UInt64 &dataOffset, CRecordVector<UInt64> &packSizes, CRecordVector<bool> &packCRCsDefined, CRecordVector<UInt32> &packCRCs) { dataOffset = ReadNumber(); CNum numPackStreams = ReadNum(); WaitAttribute(NID::kSize); packSizes.Clear(); packSizes.Reserve(numPackStreams); for (CNum i = 0; i < numPackStreams; i++) packSizes.Add(ReadNumber()); UInt64 type; for (;;) { type = ReadID(); if (type == NID::kEnd) break; if (type == NID::kCRC) { ReadHashDigests(numPackStreams, packCRCsDefined, packCRCs); continue; } SkeepData(); } if (packCRCsDefined.IsEmpty()) { packCRCsDefined.Reserve(numPackStreams); packCRCsDefined.Clear(); packCRCs.Reserve(numPackStreams); packCRCs.Clear(); for (CNum i = 0; i < numPackStreams; i++) { packCRCsDefined.Add(false); packCRCs.Add(0); } } }
void CInArchive::ReadSubStreamsInfo( const CObjectVector<CFolder> &folders, CRecordVector<CNum> &numUnpackStreamsInFolders, CRecordVector<UInt64> &unpackSizes, CBoolVector &digestsDefined, CRecordVector<UInt32> &digests) { numUnpackStreamsInFolders.Clear(); numUnpackStreamsInFolders.Reserve(folders.Size()); UInt64 type; for (;;) { type = ReadID(); if (type == NID::kNumUnpackStream) { for (int i = 0; i < folders.Size(); i++) numUnpackStreamsInFolders.Add(ReadNum()); continue; } if (type == NID::kCRC || type == NID::kSize) break; if (type == NID::kEnd) break; SkipData(); } if (numUnpackStreamsInFolders.IsEmpty()) for (int i = 0; i < folders.Size(); i++) numUnpackStreamsInFolders.Add(1); int i; for (i = 0; i < numUnpackStreamsInFolders.Size(); i++) { // v3.13 incorrectly worked with empty folders // v4.07: we check that folder is empty CNum numSubstreams = numUnpackStreamsInFolders[i]; if (numSubstreams == 0) continue; UInt64 sum = 0; for (CNum j = 1; j < numSubstreams; j++) if (type == NID::kSize) { UInt64 size = ReadNumber(); unpackSizes.Add(size); sum += size; } unpackSizes.Add(folders[i].GetUnpackSize() - sum); } if (type == NID::kSize) type = ReadID(); int numDigests = 0; int numDigestsTotal = 0; for (i = 0; i < folders.Size(); i++) { CNum numSubstreams = numUnpackStreamsInFolders[i]; if (numSubstreams != 1 || !folders[i].UnpackCRCDefined) numDigests += numSubstreams; numDigestsTotal += numSubstreams; } for (;;) { if (type == NID::kCRC) { CBoolVector digestsDefined2; CRecordVector<UInt32> digests2; ReadHashDigests(numDigests, digestsDefined2, digests2); int digestIndex = 0; for (i = 0; i < folders.Size(); i++) { CNum numSubstreams = numUnpackStreamsInFolders[i]; const CFolder &folder = folders[i]; if (numSubstreams == 1 && folder.UnpackCRCDefined) { digestsDefined.Add(true); digests.Add(folder.UnpackCRC); } else for (CNum j = 0; j < numSubstreams; j++, digestIndex++) { digestsDefined.Add(digestsDefined2[digestIndex]); digests.Add(digests2[digestIndex]); } } } else if (type == NID::kEnd) { if (digestsDefined.IsEmpty()) { BoolVector_Fill_False(digestsDefined, numDigestsTotal); digests.Clear(); for (int i = 0; i < numDigestsTotal; i++) digests.Add(0); } return; } else SkipData(); type = ReadID(); } }