private void ReadUnpackInfo(DataReader mReader, out FolderInfo[] folders) { WaitAttribute(mReader, BlockType.Folder); { int numFolders = mReader.ReadPackedUInt31(); folders = new FolderInfo[numFolders]; for(int i = 0; i < folders.Length; i++) folders[i] = GetNextFolderItem(mReader); } WaitAttribute(mReader, BlockType.CodersUnpackSize); { for(int i = 0; i < folders.Length; i++) { var folder = folders[i]; folder.UnpackSizes = new ulong[folder.GetNumOutStreams()]; for(int j = 0; j < folder.UnpackSizes.Length; j++) folder.UnpackSizes[j] = mReader.ReadPackedUInt64(); } } for(; ; ) { var type = ReadBlockType(mReader); if(type == BlockType.End) break; if(type == BlockType.CRC) { BitVector defined; uint[] crcs; ReadHashDigests(mReader, folders.Length, out defined, out crcs); for(int i = 0; i < folders.Length; i++) if(defined[i]) folders[i].UnpackCRC = crcs[i]; continue; } SkipAttribute(mReader); } }
private void ReadSubStreamsInfo(DataReader mReader, FolderInfo[] folders, out int[] numUnpackStreamsInFolders, out List<ulong> unpackSizes, out BitVector crcDefined, out uint[] crcs) { numUnpackStreamsInFolders = new int[folders.Length]; for(int i = 0; i < numUnpackStreamsInFolders.Length; i++) numUnpackStreamsInFolders[i] = 1; BlockType? type; for(; ; ) { type = ReadBlockType(mReader); if(type == BlockType.NumUnpackStream) { for(int i = 0; i < numUnpackStreamsInFolders.Length; i++) numUnpackStreamsInFolders[i] = mReader.ReadPackedUInt31(); continue; } if(type == BlockType.End || type == BlockType.CRC || type == BlockType.Size) break; SkipAttribute(mReader); } for(int i = 0; i < numUnpackStreamsInFolders.Length; i++) { int numSubstreams = numUnpackStreamsInFolders[i]; if(numSubstreams == 0) continue; ulong sum = 0; if(type == BlockType.Size) { for(int j = 1; j < numSubstreams; j++) { ulong size = mReader.ReadPackedUInt64(); unpackSizes.Add(size); sum += size; } } unpackSizes.Add(folders[i].GetUnpackSize() - sum); } if(type == BlockType.Size) type = ReadBlockType(mReader); int numCRCs = 0; int numCRCsTotal = 0; for(int i = 0; i < folders.Length; i++) { int numSubstreams = numUnpackStreamsInFolders[i]; if(numSubstreams != 1 || folders[i].UnpackCRC == null) numCRCs += numSubstreams; numCRCsTotal += numSubstreams; } for(; ; ) { if(type == BlockType.CRC) { BitVector defined2; uint[] crcs2; ReadHashDigests(mReader, numCRCs, out defined2, out crcs2); } else if(type == BlockType.End) break; else SkipAttribute(mReader); type = ReadBlockType(mReader); } if(crcDefined == null) { throw new NotImplementedException(); } }
private FolderInfo GetNextFolderItem(DataReader mReader) { FolderInfo folder = new FolderInfo(); int numInStreams = 0; int numOutStreams = 0; int numCoders = mReader.ReadPackedUInt31(); folder.Coders = new CoderInfo[numCoders]; for(int i = 0; i < numCoders; i++) { CoderInfo coder = new CoderInfo(); folder.Coders[i] = coder; byte mainByte = mReader.ReadByte(); int idSize = mainByte & 15; if(idSize > 8) // standard 7z also is limited to 8 byte coder ids throw new InvalidDataException(); ulong id = 0; for(int j = idSize - 1; j >= 0; j--) id += (ulong)mReader.ReadByte() << (j * 8); coder.MethodId = id; if((mainByte & 0x10) != 0) { coder.NumInStreams = mReader.ReadPackedUInt31(); coder.NumOutStreams = mReader.ReadPackedUInt31(); } else { coder.NumInStreams = 1; coder.NumOutStreams = 1; } if((mainByte & 0x20) != 0) { int propsSize = mReader.ReadPackedUInt31(); coder.Props = mReader.ReadBytes(propsSize); } // TODO: Warn if 0x40 is set, since it is not defined in the supported versions of the format. if((mainByte & 0x80) != 0) throw new InvalidDataException(); numInStreams += coder.NumInStreams; numOutStreams += coder.NumOutStreams; } int numBindPairs = mReader.ReadPackedUInt31(); folder.BindPairs = new BindPair[numBindPairs]; for(int i = 0; i < numBindPairs; i++) { int inIndex = mReader.ReadPackedUInt31(); int outIndex = mReader.ReadPackedUInt31(); folder.BindPairs[i] = new BindPair(inIndex, outIndex); } if(numInStreams < numBindPairs) throw new InvalidDataException(); int numPackStreams = numInStreams - numBindPairs; folder.PackStreams = new int[numPackStreams]; if(numPackStreams == 1) { bool found = false; for(int i = 0; i < numInStreams; i++) { if(folder.FindBindPairForInStream(i) < 0) { folder.PackStreams[0] = i; found = true; break; } } if(!found) throw new InvalidDataException(); } else { for(int i = 0; i < numPackStreams; i++) folder.PackStreams[i] = mReader.ReadPackedUInt31(); } return folder; }
private void ReadPackInfo(DataReader mReader, out ulong[] packSizes, out BitVector packCRCsDefined, out uint[] packCRCs) { packCRCsDefined = null; packCRCs = null; ulong dataOffset = mReader.ReadPackedUInt64(); int numPackStreams = mReader.ReadPackedUInt31(); WaitAttribute(mReader, BlockType.Size); { packSizes = new ulong[numPackStreams]; for(int i = 0; i < numPackStreams; i++) packSizes[i] = mReader.ReadPackedUInt64(); } for(; ; ) { var type = ReadBlockType(mReader); if(type == BlockType.End) break; if(type == BlockType.CRC) ReadHashDigests(mReader, numPackStreams, out packCRCsDefined, out packCRCs); else SkipAttribute(mReader); } if(packCRCsDefined == null) { packCRCsDefined = new BitVector(numPackStreams); packCRCs = new uint[numPackStreams]; } }