private static Stream CreateDecoderStream(Stream[] packStreams, long[] packSizes, Stream[] outStreams, CFolder folderInfo, int coderIndex, IPasswordProvider pass)
 {
     int num2;
     CCoderInfo info = folderInfo.Coders[coderIndex];
     if (info.NumOutStreams != 1)
     {
         throw new NotSupportedException("Multiple output streams are not supported.");
     }
     int inStreamIndex = 0;
     for (num2 = 0; num2 < coderIndex; num2++)
     {
         inStreamIndex += folderInfo.Coders[num2].NumInStreams;
     }
     int num3 = 0;
     for (num2 = 0; num2 < coderIndex; num2++)
     {
         num3 += folderInfo.Coders[num2].NumOutStreams;
     }
     Stream[] inStreams = new Stream[info.NumInStreams];
     num2 = 0;
     while (num2 < inStreams.Length)
     {
         int num4 = folderInfo.FindBindPairForInStream(inStreamIndex);
         if (num4 >= 0)
         {
             int outIndex = folderInfo.BindPairs[num4].OutIndex;
             if (outStreams[outIndex] != null)
             {
                 throw new NotSupportedException("Overlapping stream bindings are not supported.");
             }
             int num6 = FindCoderIndexForOutStreamIndex(folderInfo, outIndex);
             inStreams[num2] = CreateDecoderStream(packStreams, packSizes, outStreams, folderInfo, num6, pass);
             if (outStreams[outIndex] != null)
             {
                 throw new NotSupportedException("Overlapping stream bindings are not supported.");
             }
             outStreams[outIndex] = inStreams[num2];
         }
         else
         {
             int index = folderInfo.FindPackStreamArrayIndex(inStreamIndex);
             if (index < 0)
             {
                 throw new NotSupportedException("Could not find input stream binding.");
             }
             inStreams[num2] = packStreams[index];
         }
         num2++;
         inStreamIndex++;
     }
     long limit = folderInfo.UnpackSizes[num3];
     return DecoderRegistry.CreateDecoderStream(info.MethodId, inStreams, info.Props, pass, limit);
 }
        private void GetNextFolderItem(CFolder folder)
        {
            #if DEBUG
            Log.WriteLine("-- GetNextFolderItem --");
            Log.PushIndent();
            #endif
            try
            {
                int numCoders = ReadNum();
            #if DEBUG
                Log.WriteLine("NumCoders: " + numCoders);
            #endif
                folder.Coders = new List<CCoderInfo>(numCoders);
                int numInStreams = 0;
                int numOutStreams = 0;
                for (int i = 0; i < numCoders; i++)
                {
            #if DEBUG
                    Log.WriteLine("-- Coder --");
                    Log.PushIndent();
            #endif
                    try
                    {
                        CCoderInfo coder = new CCoderInfo();
                        folder.Coders.Add(coder);

                        byte mainByte = ReadByte();
                        int idSize = (mainByte & 0xF);
                        byte[] longID = new byte[idSize];
                        ReadBytes(longID, 0, idSize);
            #if DEBUG
                        Log.WriteLine("MethodId: " + String.Join("", Enumerable.Range(0, idSize).Select(x => longID[x].ToString("x2")).ToArray()));
            #endif
                        if (idSize > 8)
                            throw new NotSupportedException();
                        ulong id = 0;
                        for (int j = 0; j < idSize; j++)
                            id |= (ulong)longID[idSize - 1 - j] << (8 * j);
                        coder.MethodId = new CMethodId(id);

                        if ((mainByte & 0x10) != 0)
                        {
                            coder.NumInStreams = ReadNum();
                            coder.NumOutStreams = ReadNum();
            #if DEBUG
                            Log.WriteLine("Complex Stream (In: " + coder.NumInStreams + " - Out: " + coder.NumOutStreams + ")");
            #endif
                        }
                        else
                        {
            #if DEBUG
                            Log.WriteLine("Simple Stream (In: 1 - Out: 1)");
            #endif
                            coder.NumInStreams = 1;
                            coder.NumOutStreams = 1;
                        }

                        if ((mainByte & 0x20) != 0)
                        {
                            int propsSize = ReadNum();
                            coder.Props = new byte[propsSize];
                            ReadBytes(coder.Props, 0, propsSize);
            #if DEBUG
                            Log.WriteLine("Settings: " + String.Join("", coder.Props.Select(bt => bt.ToString("x2")).ToArray()));
            #endif
                        }

                        if ((mainByte & 0x80) != 0)
                            throw new NotSupportedException();

                        numInStreams += coder.NumInStreams;
                        numOutStreams += coder.NumOutStreams;
                    }
                    finally
                    {
            #if DEBUG
                        Log.PopIndent();
            #endif
                    }
                }

                int numBindPairs = numOutStreams - 1;
                folder.BindPairs = new List<CBindPair>(numBindPairs);
            #if DEBUG
                Log.WriteLine("BindPairs: " + numBindPairs);
                Log.PushIndent();
            #endif
                for (int i = 0; i < numBindPairs; i++)
                {
                    CBindPair bp = new CBindPair();
                    bp.InIndex = ReadNum();
                    bp.OutIndex = ReadNum();
                    folder.BindPairs.Add(bp);
            #if DEBUG
                    Log.WriteLine("#" + i + " - In: " + bp.InIndex + " - Out: " + bp.OutIndex);
            #endif
                }
            #if DEBUG
                Log.PopIndent();
            #endif

                if (numInStreams < numBindPairs)
                    throw new NotSupportedException();

                int numPackStreams = numInStreams - numBindPairs;
                //folder.PackStreams.Reserve(numPackStreams);
                if (numPackStreams == 1)
                {
                    for (int i = 0; i < numInStreams; i++)
                    {
                        if (folder.FindBindPairForInStream(i) < 0)
                        {
            #if DEBUG
                            Log.WriteLine("Single PackStream: #" + i);
            #endif
                            folder.PackStreams.Add(i);
                            break;
                        }
                    }

                    if (folder.PackStreams.Count != 1)
                        throw new NotSupportedException();
                }
                else
                {
            #if DEBUG
                    Log.WriteLine("Multiple PackStreams ...");
                    Log.PushIndent();
            #endif
                    for (int i = 0; i < numPackStreams; i++)
                    {
                        var num = ReadNum();
            #if DEBUG
                        Log.WriteLine("#" + i + " - " + num);
            #endif
                        folder.PackStreams.Add(num);
                    }
            #if DEBUG
                    Log.PopIndent();
            #endif
                }
            }
            finally
            {
            #if DEBUG
                Log.PopIndent();
            #endif
            }
        }
        private static Stream CreateDecoderStream(Stream[] packStreams, long[] packSizes, Stream[] outStreams,
            CFolder folderInfo, int coderIndex, IPasswordProvider pass)
        {
            var coderInfo = folderInfo.Coders[coderIndex];
            if (coderInfo.NumOutStreams != 1)
                throw new NotSupportedException("Multiple output streams are not supported.");

            int inStreamId = 0;
            for (int i = 0; i < coderIndex; i++)
                inStreamId += folderInfo.Coders[i].NumInStreams;

            int outStreamId = 0;
            for (int i = 0; i < coderIndex; i++)
                outStreamId += folderInfo.Coders[i].NumOutStreams;

            Stream[] inStreams = new Stream[coderInfo.NumInStreams];

            for (int i = 0; i < inStreams.Length; i++, inStreamId++)
            {
                int bindPairIndex = folderInfo.FindBindPairForInStream(inStreamId);
                if (bindPairIndex >= 0)
                {
                    int pairedOutIndex = folderInfo.BindPairs[bindPairIndex].OutIndex;

                    if (outStreams[pairedOutIndex] != null)
                        throw new NotSupportedException("Overlapping stream bindings are not supported.");

                    int otherCoderIndex = FindCoderIndexForOutStreamIndex(folderInfo, pairedOutIndex);
                    inStreams[i] = CreateDecoderStream(packStreams, packSizes, outStreams, folderInfo, otherCoderIndex,
                                                       pass);
                    //inStreamSizes[i] = folderInfo.UnpackSizes[pairedOutIndex];

                    if (outStreams[pairedOutIndex] != null)
                        throw new NotSupportedException("Overlapping stream bindings are not supported.");

                    outStreams[pairedOutIndex] = inStreams[i];
                }
                else
                {
                    int index = folderInfo.FindPackStreamArrayIndex(inStreamId);
                    if (index < 0)
                        throw new NotSupportedException("Could not find input stream binding.");

                    inStreams[i] = packStreams[index];
                    //inStreamSizes[i] = packSizes[index];
                }
            }

            long unpackSize = folderInfo.UnpackSizes[outStreamId];
            return DecoderRegistry.CreateDecoderStream(coderInfo.MethodId, inStreams, coderInfo.Props, pass, unpackSize);
        }
 private void GetNextFolderItem(CFolder folder)
 {
     SharpCompress.Compressor.LZMA.Log.WriteLine("-- GetNextFolderItem --");
     SharpCompress.Compressor.LZMA.Log.PushIndent("  ");
     try
     {
         int num4;
         int capacity = this.ReadNum();
         SharpCompress.Compressor.LZMA.Log.WriteLine("NumCoders: " + capacity);
         folder.Coders = new List<CCoderInfo>(capacity);
         int num2 = 0;
         int num3 = 0;
         for (num4 = 0; num4 < capacity; num4++)
         {
             SharpCompress.Compressor.LZMA.Log.WriteLine("-- Coder --");
             SharpCompress.Compressor.LZMA.Log.PushIndent("  ");
             try
             {
                 CCoderInfo item = new CCoderInfo();
                 folder.Coders.Add(item);
                 byte num5 = this.ReadByte();
                 int length = num5 & 15;
                 byte[] longID = new byte[length];
                 this.ReadBytes(longID, 0, length);
                 SharpCompress.Compressor.LZMA.Log.WriteLine("MethodId: " + string.Join("", Enumerable.ToArray<string>(Enumerable.Select<int, string>(Enumerable.Range(0, length), delegate (int x) {
                     return longID[x].ToString("x2");
                 }))));
                 if (length > 8)
                 {
                     throw new NotSupportedException();
                 }
                 ulong id = 0L;
                 for (int i = 0; i < length; i++)
                 {
                     id |= (ulong)longID[(length - 1) - i] << (8 * i);
                 }
                 item.MethodId = new CMethodId(id);
                 if ((num5 & 0x10) != 0)
                 {
                     item.NumInStreams = this.ReadNum();
                     item.NumOutStreams = this.ReadNum();
                     SharpCompress.Compressor.LZMA.Log.WriteLine(string.Concat(new object[] { "Complex Stream (In: ", item.NumInStreams, " - Out: ", item.NumOutStreams, ")" }));
                 }
                 else
                 {
                     SharpCompress.Compressor.LZMA.Log.WriteLine("Simple Stream (In: 1 - Out: 1)");
                     item.NumInStreams = 1;
                     item.NumOutStreams = 1;
                 }
                 if ((num5 & 0x20) != 0)
                 {
                     int num9 = this.ReadNum();
                     item.Props = new byte[num9];
                     this.ReadBytes(item.Props, 0, num9);
                     SharpCompress.Compressor.LZMA.Log.WriteLine("Settings: " + string.Join("", Enumerable.ToArray<string>(Enumerable.Select<byte, string>(item.Props, delegate (byte bt) {
                         return bt.ToString("x2");
                     }))));
                 }
                 if ((num5 & 0x80) != 0)
                 {
                     throw new NotSupportedException();
                 }
                 num2 += item.NumInStreams;
                 num3 += item.NumOutStreams;
             }
             finally
             {
                 SharpCompress.Compressor.LZMA.Log.PopIndent();
             }
         }
         int num10 = num3 - 1;
         folder.BindPairs = new List<CBindPair>(num10);
         SharpCompress.Compressor.LZMA.Log.WriteLine("BindPairs: " + num10);
         SharpCompress.Compressor.LZMA.Log.PushIndent("  ");
         for (num4 = 0; num4 < num10; num4++)
         {
             CBindPair pair = new CBindPair();
             pair.InIndex = this.ReadNum();
             pair.OutIndex = this.ReadNum();
             folder.BindPairs.Add(pair);
             SharpCompress.Compressor.LZMA.Log.WriteLine(string.Concat(new object[] { "#", num4, " - In: ", pair.InIndex, " - Out: ", pair.OutIndex }));
         }
         SharpCompress.Compressor.LZMA.Log.PopIndent();
         if (num2 < num10)
         {
             throw new NotSupportedException();
         }
         int num11 = num2 - num10;
         if (num11 == 1)
         {
             for (num4 = 0; num4 < num2; num4++)
             {
                 if (folder.FindBindPairForInStream(num4) < 0)
                 {
                     SharpCompress.Compressor.LZMA.Log.WriteLine("Single PackStream: #" + num4);
                     folder.PackStreams.Add(num4);
                     break;
                 }
             }
             if (folder.PackStreams.Count != 1)
             {
                 throw new NotSupportedException();
             }
         }
         else
         {
             SharpCompress.Compressor.LZMA.Log.WriteLine("Multiple PackStreams ...");
             SharpCompress.Compressor.LZMA.Log.PushIndent("  ");
             for (num4 = 0; num4 < num11; num4++)
             {
                 int num12 = this.ReadNum();
                 SharpCompress.Compressor.LZMA.Log.WriteLine(string.Concat(new object[] { "#", num4, " - ", num12 }));
                 folder.PackStreams.Add(num12);
             }
             SharpCompress.Compressor.LZMA.Log.PopIndent();
         }
     }
     finally
     {
         SharpCompress.Compressor.LZMA.Log.PopIndent();
     }
 }