예제 #1
0
        private bool DecodeWindow()
        {
            int num = delta.ReadByte();

            if (num == -1)
            {
                return(false);
            }
            int  num2 = -1;
            bool flag = (num & 4) == 4;

            num &= 0xFB;
            Stream stream;

            switch (num & 3)
            {
            case 0:
                stream = null;
                break;

            case 1:
                if (original == null)
                {
                    throw new VcdiffFormatException("Source stream requested by delta but not provided by caller.");
                }
                stream = original;
                break;

            case 2:
                stream = output;
                num2   = (int)output.Position;
                break;

            case 3:
                throw new VcdiffFormatException("Invalid window indicator - bits 0 and 1 both set.");

            default:
                throw new VcdiffFormatException("Invalid window indicator - bits 3-7 not all zero.");
            }
            byte[] array = null;
            int    num3  = 0;

            if (stream != null)
            {
                num3 = IOHelper.ReadBigEndian7BitEncodedInt(delta);
                int num4 = IOHelper.ReadBigEndian7BitEncodedInt(delta);
                stream.Position = num4;
                array           = IOHelper.CheckedReadBytes(stream, num3);
                if (num2 != -1)
                {
                    stream.Position = num2;
                }
            }
            IOHelper.ReadBigEndian7BitEncodedInt(delta);
            int num5 = IOHelper.ReadBigEndian7BitEncodedInt(delta);

            byte[]       array2       = new byte[num5];
            MemoryStream memoryStream = new MemoryStream(array2, writable: true);

            if (IOHelper.CheckedReadByte(delta) != 0)
            {
                throw new VcdiffFormatException("VcdiffDecoder is unable to handle compressed delta sections.");
            }
            int size  = IOHelper.ReadBigEndian7BitEncodedInt(delta);
            int size2 = IOHelper.ReadBigEndian7BitEncodedInt(delta);
            int size3 = IOHelper.ReadBigEndian7BitEncodedInt(delta);

            if (flag)
            {
                IOHelper.CheckedReadBytes(delta, 4);
            }
            byte[]       array3        = IOHelper.CheckedReadBytes(delta, size);
            byte[]       buffer        = IOHelper.CheckedReadBytes(delta, size2);
            byte[]       addresses     = IOHelper.CheckedReadBytes(delta, size3);
            int          num6          = 0;
            MemoryStream memoryStream2 = new MemoryStream(buffer, writable: false);

            cache.Reset(addresses);
            while (true)
            {
                int num7 = memoryStream2.ReadByte();
                if (num7 == -1)
                {
                    break;
                }
                for (int i = 0; i < 2; i++)
                {
                    Instruction instruction = codeTable[num7, i];
                    int         num8        = instruction.Size;
                    if (num8 == 0 && instruction.Type != 0)
                    {
                        num8 = IOHelper.ReadBigEndian7BitEncodedInt(memoryStream2);
                    }
                    switch (instruction.Type)
                    {
                    case InstructionType.Add:
                        memoryStream.Write(array3, num6, num8);
                        num6 += num8;
                        break;

                    case InstructionType.Copy:
                    {
                        int num9 = cache.DecodeAddress((int)memoryStream.Position + num3, instruction.Mode);
                        if (array != null && num9 < array.Length)
                        {
                            memoryStream.Write(array, num9, num8);
                            break;
                        }
                        num9 -= num3;
                        if (num9 + num8 < memoryStream.Position)
                        {
                            memoryStream.Write(array2, num9, num8);
                            break;
                        }
                        for (int k = 0; k < num8; k++)
                        {
                            memoryStream.WriteByte(array2[num9++]);
                        }
                        break;
                    }

                    case InstructionType.Run:
                    {
                        byte value = array3[num6++];
                        for (int j = 0; j < num8; j++)
                        {
                            memoryStream.WriteByte(value);
                        }
                        break;
                    }

                    default:
                        throw new VcdiffFormatException("Invalid instruction type found.");

                    case InstructionType.NoOp:
                        break;
                    }
                }
            }
            output.Write(array2, 0, num5);
            adler.Update(array2, 0, num5);
            return(true);
        }