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;
         }
     }
 }