public bool CheckStructure() { const int kNumCodersMax = 32; // don't change it const int kMaskSize = 32; // it must be >= kNumCodersMax const int kNumBindsMax = 32; if (Coders.Count > kNumCodersMax || BindPairs.Count > kNumBindsMax) return false; { var v = new BitVector(BindPairs.Count + PackStreams.Count); for (int i = 0; i < BindPairs.Count; i++) if (v.GetAndSet(BindPairs[i].InIndex)) return false; for (int i = 0; i < PackStreams.Count; i++) if (v.GetAndSet(PackStreams[i])) return false; } { var v = new BitVector(UnpackSizes.Count); for (int i = 0; i < BindPairs.Count; i++) if (v.GetAndSet(BindPairs[i].OutIndex)) return false; } uint[] mask = new uint[kMaskSize]; { List<int> inStreamToCoder = new List<int>(); List<int> outStreamToCoder = new List<int>(); for (int i = 0; i < Coders.Count; i++) { CCoderInfo coder = Coders[i]; for (int j = 0; j < coder.NumInStreams; j++) inStreamToCoder.Add(i); for (int j = 0; j < coder.NumOutStreams; j++) outStreamToCoder.Add(i); } for (int i = 0; i < BindPairs.Count; i++) { CBindPair bp = BindPairs[i]; mask[inStreamToCoder[bp.InIndex]] |= (1u << outStreamToCoder[bp.OutIndex]); } } for (int i = 0; i < kMaskSize; i++) for (int j = 0; j < kMaskSize; j++) if (((1u << j) & mask[i]) != 0) mask[i] |= mask[j]; for (int i = 0; i < kMaskSize; i++) if (((1u << i) & mask[i]) != 0) return false; return true; }
private void ReadHeader(ArchiveDatabase db, IPasswordProvider getTextPassword) { #if DEBUG Log.WriteLine("-- ReadHeader --"); Log.PushIndent(); #endif try { BlockType? type = ReadId(); if (type == BlockType.ArchiveProperties) { ReadArchiveProperties(); type = ReadId(); } List<byte[]> dataVector = null; if (type == BlockType.AdditionalStreamsInfo) { dataVector = ReadAndDecodePackedStreams(db.StartPositionAfterHeader, getTextPassword); type = ReadId(); } List<long> unpackSizes; List<uint?> digests; if (type == BlockType.MainStreamsInfo) { ReadStreamsInfo(dataVector, out db.DataStartPosition, out db.PackSizes, out db.PackCRCs, out db.Folders, out db.NumUnpackStreamsVector, out unpackSizes, out digests); db.DataStartPosition += db.StartPositionAfterHeader; type = ReadId(); } else { unpackSizes = new List<long>(db.Folders.Count); digests = new List<uint?>(db.Folders.Count); db.NumUnpackStreamsVector = new List<int>(db.Folders.Count); for (int i = 0; i < db.Folders.Count; i++) { var folder = db.Folders[i]; unpackSizes.Add(folder.GetUnpackSize()); digests.Add(folder.UnpackCRC); db.NumUnpackStreamsVector.Add(1); } } db.Files.Clear(); if (type == BlockType.End) return; if (type != BlockType.FilesInfo) throw new InvalidOperationException(); int numFiles = ReadNum(); #if DEBUG Log.WriteLine("NumFiles: " + numFiles); #endif db.Files = new List<CFileItem>(numFiles); for (int i = 0; i < numFiles; i++) db.Files.Add(new CFileItem()); BitVector emptyStreamVector = new BitVector(numFiles); BitVector emptyFileVector = null; BitVector antiFileVector = null; int numEmptyStreams = 0; for (; ; ) { type = ReadId(); if (type == BlockType.End) break; long size = checked((long)ReadNumber()); // TODO: throw invalid data on negative int oldPos = _currentReader.Offset; switch (type) { case BlockType.Name: using (var streamSwitch = new CStreamSwitch()) { streamSwitch.Set(this, dataVector); #if DEBUG Log.Write("FileNames:"); #endif for (int i = 0; i < db.Files.Count; i++) { db.Files[i].Name = _currentReader.ReadString(); #if DEBUG Log.Write(" " + db.Files[i].Name); #endif } #if DEBUG Log.WriteLine(); #endif } break; case BlockType.WinAttributes: #if DEBUG Log.Write("WinAttributes:"); #endif ReadAttributeVector(dataVector, numFiles, delegate(int i, uint? attr) { db.Files[i].Attrib = attr; #if DEBUG Log.Write(" " + (attr.HasValue ? attr.Value.ToString("x8") : "n/a")); #endif }); #if DEBUG Log.WriteLine(); #endif break; case BlockType.EmptyStream: emptyStreamVector = ReadBitVector(numFiles); #if DEBUG Log.Write("EmptyStream: "); #endif for (int i = 0; i < emptyStreamVector.Length; i++) { if (emptyStreamVector[i]) { #if DEBUG Log.Write("x"); #endif numEmptyStreams++; } else { #if DEBUG Log.Write("."); #endif } } #if DEBUG Log.WriteLine(); #endif emptyFileVector = new BitVector(numEmptyStreams); antiFileVector = new BitVector(numEmptyStreams); break; case BlockType.EmptyFile: emptyFileVector = ReadBitVector(numEmptyStreams); #if DEBUG Log.Write("EmptyFile: "); for (int i = 0; i < numEmptyStreams; i++) Log.Write(emptyFileVector[i] ? "x" : "."); Log.WriteLine(); #endif break; case BlockType.Anti: antiFileVector = ReadBitVector(numEmptyStreams); #if DEBUG Log.Write("Anti: "); for (int i = 0; i < numEmptyStreams; i++) Log.Write(antiFileVector[i] ? "x" : "."); Log.WriteLine(); #endif break; case BlockType.StartPos: #if DEBUG Log.Write("StartPos:"); #endif ReadNumberVector(dataVector, numFiles, delegate(int i, long? startPos) { db.Files[i].StartPos = startPos; #if DEBUG Log.Write(" " + (startPos.HasValue ? startPos.Value.ToString() : "n/a")); #endif }); #if DEBUG Log.WriteLine(); #endif break; case BlockType.CTime: #if DEBUG Log.Write("CTime:"); #endif ReadDateTimeVector(dataVector, numFiles, delegate(int i, DateTime? time) { db.Files[i].CTime = time; #if DEBUG Log.Write(" " + (time.HasValue ? time.Value.ToString() : "n/a")); #endif }); #if DEBUG Log.WriteLine(); #endif break; case BlockType.ATime: #if DEBUG Log.Write("ATime:"); #endif ReadDateTimeVector(dataVector, numFiles, delegate(int i, DateTime? time) { db.Files[i].ATime = time; #if DEBUG Log.Write(" " + (time.HasValue ? time.Value.ToString() : "n/a")); #endif }); #if DEBUG Log.WriteLine(); #endif break; case BlockType.MTime: #if DEBUG Log.Write("MTime:"); #endif ReadDateTimeVector(dataVector, numFiles, delegate(int i, DateTime? time) { db.Files[i].MTime = time; #if DEBUG Log.Write(" " + (time.HasValue ? time.Value.ToString() : "n/a")); #endif }); #if DEBUG Log.WriteLine(); #endif break; case BlockType.Dummy: #if DEBUG Log.Write("Dummy: " + size); #endif for (long j = 0; j < size; j++) if (ReadByte() != 0) throw new InvalidOperationException(); break; default: SkipData(size); break; } // since 0.3 record sizes must be correct bool checkRecordsSize = (db.MajorVersion > 0 || db.MinorVersion > 2); if (checkRecordsSize && _currentReader.Offset - oldPos != size) throw new InvalidOperationException(); } int emptyFileIndex = 0; int sizeIndex = 0; for (int i = 0; i < numFiles; i++) { CFileItem file = db.Files[i]; file.HasStream = !emptyStreamVector[i]; if (file.HasStream) { file.IsDir = false; file.IsAnti = false; file.Size = unpackSizes[sizeIndex]; file.Crc = digests[sizeIndex]; sizeIndex++; } else { file.IsDir = !emptyFileVector[emptyFileIndex]; file.IsAnti = antiFileVector[emptyFileIndex]; emptyFileIndex++; file.Size = 0; file.Crc = null; } } } finally { #if DEBUG Log.PopIndent(); #endif } }
private BitVector ReadBitVector(int length) { var bits = new BitVector(length); byte data = 0; byte mask = 0; for (int i = 0; i < length; i++) { if (mask == 0) { data = ReadByte(); mask = 0x80; } if ((data & mask) != 0) bits.SetBit(i); mask >>= 1; } return bits; }
public bool CheckStructure() { int num; int num2; if ((this.Coders.Count > 0x20) || (this.BindPairs.Count > 0x20)) { return false; } BitVector vector = new BitVector(this.BindPairs.Count + this.PackStreams.Count); for (num = 0; num < this.BindPairs.Count; num++) { if (vector.GetAndSet(this.BindPairs[num].InIndex)) { return false; } } for (num = 0; num < this.PackStreams.Count; num++) { if (vector.GetAndSet(this.PackStreams[num])) { return false; } } vector = new BitVector(this.UnpackSizes.Count); for (num = 0; num < this.BindPairs.Count; num++) { if (vector.GetAndSet(this.BindPairs[num].OutIndex)) { return false; } } uint[] numArray = new uint[0x20]; List<int> list = new List<int>(); List<int> list2 = new List<int>(); for (num = 0; num < this.Coders.Count; num++) { CCoderInfo info = this.Coders[num]; num2 = 0; while (num2 < info.NumInStreams) { list.Add(num); num2++; } num2 = 0; while (num2 < info.NumOutStreams) { list2.Add(num); num2++; } } for (num = 0; num < this.BindPairs.Count; num++) { CBindPair pair = this.BindPairs[num]; numArray[list[pair.InIndex]] |= ((uint) 1) << list2[pair.OutIndex]; } for (num = 0; num < 0x20; num++) { for (num2 = 0; num2 < 0x20; num2++) { if (((((int) 1) << num2) & numArray[num]) != 0) { numArray[num] |= numArray[num2]; } } } for (num = 0; num < 0x20; num++) { if (((((int) 1) << num) & numArray[num]) != 0) { return false; } } return true; }
private void ReadHeader(ArchiveDatabase db, IPasswordProvider getTextPassword) { Action<int, uint?> action = null; Action<int, long?> action2 = null; Action<int, DateTime?> action3 = null; Action<int, DateTime?> action4 = null; Action<int, DateTime?> action5 = null; SharpCompress.Compressor.LZMA.Log.WriteLine("-- ReadHeader --"); SharpCompress.Compressor.LZMA.Log.PushIndent(" "); try { List<long> list2; List<uint?> list3; int num; long num6; int num7; bool flag2; BlockType? nullable = this.ReadId(); if (((BlockType) nullable) == BlockType.ArchiveProperties) { this.ReadArchiveProperties(); nullable = this.ReadId(); } List<byte[]> dataVector = null; if (((BlockType) nullable) == BlockType.AdditionalStreamsInfo) { dataVector = this.ReadAndDecodePackedStreams(db.StartPositionAfterHeader, getTextPassword); nullable = this.ReadId(); } if (((BlockType) nullable) == BlockType.MainStreamsInfo) { this.ReadStreamsInfo(dataVector, out db.DataStartPosition, out db.PackSizes, out db.PackCRCs, out db.Folders, out db.NumUnpackStreamsVector, out list2, out list3); db.DataStartPosition += db.StartPositionAfterHeader; nullable = this.ReadId(); } else { list2 = new List<long>(db.Folders.Count); list3 = new List<uint?>(db.Folders.Count); db.NumUnpackStreamsVector = new List<int>(db.Folders.Count); for (num = 0; num < db.Folders.Count; num++) { CFolder folder = db.Folders[num]; list2.Add(folder.GetUnpackSize()); list3.Add(folder.UnpackCRC); db.NumUnpackStreamsVector.Add(1); } } db.Files.Clear(); if (((BlockType) nullable) == BlockType.End) { return; } if (((BlockType) nullable) != BlockType.FilesInfo) { throw new InvalidOperationException(); } int capacity = this.ReadNum(); SharpCompress.Compressor.LZMA.Log.WriteLine("NumFiles: " + capacity); db.Files = new List<CFileItem>(capacity); num = 0; while (num < capacity) { db.Files.Add(new CFileItem()); num++; } BitVector vector = new BitVector(capacity); BitVector vector2 = null; BitVector vector3 = null; int length = 0; goto Label_06FC; Label_02DA: nullable = this.ReadId(); if (((BlockType) nullable) == BlockType.End) { goto Label_0704; } long size = (long) this.ReadNumber(); int offset = this._currentReader.Offset; BlockType valueOrDefault = nullable.GetValueOrDefault(); if (nullable.HasValue) { switch (valueOrDefault) { case BlockType.EmptyStream: vector = this.ReadBitVector(capacity); SharpCompress.Compressor.LZMA.Log.Write("EmptyStream: "); num = 0; goto Label_04AD; case BlockType.EmptyFile: vector2 = this.ReadBitVector(length); SharpCompress.Compressor.LZMA.Log.Write("EmptyFile: "); num = 0; goto Label_0519; case BlockType.Anti: vector3 = this.ReadBitVector(length); SharpCompress.Compressor.LZMA.Log.Write("Anti: "); num = 0; goto Label_056E; case BlockType.Name: goto Label_0370; case BlockType.CTime: goto Label_05BC; case BlockType.ATime: goto Label_05F3; case BlockType.MTime: goto Label_062A; case BlockType.WinAttributes: goto Label_0420; case BlockType.StartPos: goto Label_0585; case BlockType.Dummy: SharpCompress.Compressor.LZMA.Log.Write("Dummy: " + size); num6 = 0L; goto Label_0697; } } goto Label_06A5; Label_0370: using (CStreamSwitch switch2 = new CStreamSwitch()) { switch2.Set(this, dataVector); SharpCompress.Compressor.LZMA.Log.Write("FileNames:"); num = 0; while (num < db.Files.Count) { db.Files[num].Name = this._currentReader.ReadString(); SharpCompress.Compressor.LZMA.Log.Write(" " + db.Files[num].Name); num++; } SharpCompress.Compressor.LZMA.Log.WriteLine(); } goto Label_06B0; Label_0420: SharpCompress.Compressor.LZMA.Log.Write("WinAttributes:"); if (action == null) { action = delegate (int i, uint? attr) { db.Files[i].Attrib = attr; SharpCompress.Compressor.LZMA.Log.Write(" " + (attr.HasValue ? attr.Value.ToString("x8") : "n/a")); }; } this.ReadAttributeVector(dataVector, capacity, action); SharpCompress.Compressor.LZMA.Log.WriteLine(); goto Label_06B0; Label_0471: if (vector[num]) { SharpCompress.Compressor.LZMA.Log.Write("x"); length++; } else { SharpCompress.Compressor.LZMA.Log.Write("."); } num++; Label_04AD: if (num < vector.Length) { goto Label_0471; } SharpCompress.Compressor.LZMA.Log.WriteLine(); vector2 = new BitVector(length); vector3 = new BitVector(length); goto Label_06B0; Label_04F5: SharpCompress.Compressor.LZMA.Log.Write(vector2[num] ? "x" : "."); num++; Label_0519: if (num < length) { goto Label_04F5; } SharpCompress.Compressor.LZMA.Log.WriteLine(); goto Label_06B0; Label_054A: SharpCompress.Compressor.LZMA.Log.Write(vector3[num] ? "x" : "."); num++; Label_056E: if (num < length) { goto Label_054A; } SharpCompress.Compressor.LZMA.Log.WriteLine(); goto Label_06B0; Label_0585: SharpCompress.Compressor.LZMA.Log.Write("StartPos:"); if (action2 == null) { action2 = delegate (int i, long? startPos) { db.Files[i].StartPos = startPos; SharpCompress.Compressor.LZMA.Log.Write(" " + (startPos.HasValue ? startPos.Value.ToString() : "n/a")); }; } this.ReadNumberVector(dataVector, capacity, action2); SharpCompress.Compressor.LZMA.Log.WriteLine(); goto Label_06B0; Label_05BC: SharpCompress.Compressor.LZMA.Log.Write("CTime:"); if (action3 == null) { action3 = delegate (int i, DateTime? time) { db.Files[i].CTime = time; SharpCompress.Compressor.LZMA.Log.Write(" " + (time.HasValue ? time.Value.ToString() : "n/a")); }; } this.ReadDateTimeVector(dataVector, capacity, action3); SharpCompress.Compressor.LZMA.Log.WriteLine(); goto Label_06B0; Label_05F3: SharpCompress.Compressor.LZMA.Log.Write("ATime:"); if (action4 == null) { action4 = delegate (int i, DateTime? time) { db.Files[i].ATime = time; SharpCompress.Compressor.LZMA.Log.Write(" " + (time.HasValue ? time.Value.ToString() : "n/a")); }; } this.ReadDateTimeVector(dataVector, capacity, action4); SharpCompress.Compressor.LZMA.Log.WriteLine(); goto Label_06B0; Label_062A: SharpCompress.Compressor.LZMA.Log.Write("MTime:"); if (action5 == null) { action5 = delegate (int i, DateTime? time) { db.Files[i].MTime = time; SharpCompress.Compressor.LZMA.Log.Write(" " + (time.HasValue ? time.Value.ToString() : "n/a")); }; } this.ReadDateTimeVector(dataVector, capacity, action5); SharpCompress.Compressor.LZMA.Log.WriteLine(); goto Label_06B0; Label_067B: if (this.ReadByte() != 0) { throw new InvalidOperationException(); } num6 += 1L; Label_0697: if (num6 < size) { goto Label_067B; } goto Label_06B0; Label_06A5: this.SkipData(size); Label_06B0: if (((db.MajorVersion > 0) || (db.MinorVersion > 2)) && ((this._currentReader.Offset - offset) != size)) { throw new InvalidOperationException(); } Label_06FC: flag2 = true; goto Label_02DA; Label_0704: num7 = 0; int num8 = 0; for (num = 0; num < capacity; num++) { CFileItem item = db.Files[num]; item.HasStream = !vector[num]; if (item.HasStream) { item.IsDir = false; item.IsAnti = false; item.Size = list2[num8]; item.Crc = list3[num8]; num8++; } else { item.IsDir = !vector2[num7]; item.IsAnti = vector3[num7]; num7++; item.Size = 0L; item.Crc = null; } } } finally { SharpCompress.Compressor.LZMA.Log.PopIndent(); } }
private BitVector ReadBitVector(int length) { BitVector vector = new BitVector(length); byte num = 0; byte num2 = 0; for (int i = 0; i < length; i++) { if (num2 == 0) { num = this.ReadByte(); num2 = 0x80; } if ((num & num2) != 0) { vector.SetBit(i); } num2 = (byte) (num2 >> 1); } return vector; }