public LzmaStream(byte[] properties, Stream inputStream, long inputSize, long outputSize, Stream presetDictionary, bool isLZMA2) { this.outWindow = new OutWindow(); this.rangeDecoder = new SharpCompress.Compressor.LZMA.RangeCoder.Decoder(); this.position = 0L; this.endReached = false; this.inputPosition = 0L; this.uncompressedChunk = false; this.needDictReset = true; this.needProps = true; this.props = new byte[5]; this.inputStream = inputStream; this.inputSize = inputSize; this.outputSize = outputSize; this.isLZMA2 = isLZMA2; if (!isLZMA2) { this.dictionarySize = BitConverter.ToInt32(properties, 1); this.outWindow.Create(this.dictionarySize); if (presetDictionary != null) { this.outWindow.Train(presetDictionary); } this.rangeDecoder.Init(inputStream); this.decoder = new SharpCompress.Compressor.LZMA.Decoder(); this.decoder.SetDecoderProperties(properties); this.props = properties; this.availableBytes = (outputSize < 0L) ? 0x7fffffffffffffffL : outputSize; this.rangeDecoderLimit = inputSize; } else { this.dictionarySize = 2 | (properties[0] & 1); this.dictionarySize = this.dictionarySize << ((properties[0] >> 1) + 11); this.outWindow.Create(this.dictionarySize); if (presetDictionary != null) { this.outWindow.Train(presetDictionary); this.needDictReset = false; } this.props = new byte[1]; this.availableBytes = 0L; } }
private void ReadArchive(HeaderBuffer headerBytes) { while (true) { var prop = headerBytes.ReadProperty(); switch (prop) { case HeaderProperty.kEncodedHeader: { ArchiveInfo = ReadPackedStreams(headerBytes); stream.Seek((long)ArchiveInfo.PackPosition + BaseOffset, SeekOrigin.Begin); var firstFolder = ArchiveInfo.Folders.First(); ulong unpackSize = firstFolder.GetUnpackSize(); ulong packSize = ArchiveInfo.PackedStreams.Select(x => x.PackedSize) .Aggregate((ulong)0, (sum, size) => sum + size); byte[] unpackedBytes = new byte[(int)unpackSize]; Decoder decoder = new Decoder(); decoder.SetDecoderProperties(firstFolder.Coders[0].Properties); using (MemoryStream outStream = new MemoryStream(unpackedBytes)) { decoder.Code(stream, outStream, (long)(packSize), (long)unpackSize, null); } headerBytes = new HeaderBuffer { Bytes = unpackedBytes }; } break; case HeaderProperty.kHeader: { ReadFileHeader(headerBytes); return; } default: throw new NotSupportedException("7Zip header " + prop); } } }
private void decodeChunkHeader() { int num = this.inputStream.ReadByte(); this.inputPosition += 1L; if (num == 0) { this.endReached = true; } else { if ((num >= 0xe0) || (num == 1)) { this.needProps = true; this.needDictReset = false; this.outWindow.Reset(); } else if (this.needDictReset) { throw new DataErrorException(); } if (num >= 0x80) { this.uncompressedChunk = false; this.availableBytes = (num & 0x1f) << 0x10; this.availableBytes += ((this.inputStream.ReadByte() << 8) + this.inputStream.ReadByte()) + 1; this.inputPosition += 2L; this.rangeDecoderLimit = ((this.inputStream.ReadByte() << 8) + this.inputStream.ReadByte()) + 1; this.inputPosition += 2L; if (num >= 0xc0) { this.needProps = false; this.props[0] = (byte)this.inputStream.ReadByte(); this.inputPosition += 1L; this.decoder = new SharpCompress.Compressor.LZMA.Decoder(); this.decoder.SetDecoderProperties(this.props); } else { if (this.needProps) { throw new DataErrorException(); } if (num >= 160) { this.decoder = new SharpCompress.Compressor.LZMA.Decoder(); this.decoder.SetDecoderProperties(this.props); } } this.rangeDecoder.Init(this.inputStream); } else { if (num > 2) { throw new DataErrorException(); } this.uncompressedChunk = true; this.availableBytes = ((this.inputStream.ReadByte() << 8) + this.inputStream.ReadByte()) + 1; this.inputPosition += 2L; } } }
private void decodeChunkHeader() { int num = this.inputStream.ReadByte(); this.inputPosition += 1L; if (num == 0) { this.endReached = true; } else { if ((num >= 0xe0) || (num == 1)) { this.needProps = true; this.needDictReset = false; this.outWindow.Reset(); } else if (this.needDictReset) { throw new DataErrorException(); } if (num >= 0x80) { this.uncompressedChunk = false; this.availableBytes = (num & 0x1f) << 0x10; this.availableBytes += ((this.inputStream.ReadByte() << 8) + this.inputStream.ReadByte()) + 1; this.inputPosition += 2L; this.rangeDecoderLimit = ((this.inputStream.ReadByte() << 8) + this.inputStream.ReadByte()) + 1; this.inputPosition += 2L; if (num >= 0xc0) { this.needProps = false; this.props[0] = (byte) this.inputStream.ReadByte(); this.inputPosition += 1L; this.decoder = new SharpCompress.Compressor.LZMA.Decoder(); this.decoder.SetDecoderProperties(this.props); } else { if (this.needProps) { throw new DataErrorException(); } if (num >= 160) { this.decoder = new SharpCompress.Compressor.LZMA.Decoder(); this.decoder.SetDecoderProperties(this.props); } } this.rangeDecoder.Init(this.inputStream); } else { if (num > 2) { throw new DataErrorException(); } this.uncompressedChunk = true; this.availableBytes = ((this.inputStream.ReadByte() << 8) + this.inputStream.ReadByte()) + 1; this.inputPosition += 2L; } } }