private static SvnDiffInstruction ReadInstruction(BinaryReaderEOF reader)
        {
            if (reader.EOF)
            {
                return(null);
            }

            SvnDiffInstruction instruction = new SvnDiffInstruction();

            byte opCodeAndLength = reader.ReadByte();

            instruction.OpCode = (SvnDiffInstructionOpCode)((opCodeAndLength & 0xC0) >> 6);

            byte length = (byte)(opCodeAndLength & 0x3F);

            if (length == 0)
            {
                instruction.Length = ReadInt(reader);
            }
            else
            {
                instruction.Length = length;
            }

            if (instruction.OpCode == SvnDiffInstructionOpCode.CopyFromSource ||
                instruction.OpCode == SvnDiffInstructionOpCode.CopyFromTarget)
            {
                instruction.Offset = ReadInt(reader);
            }

            return(instruction);
        }
        public static SvnDiff[] ParseSvnDiff(Stream inputStream)
        {
            BinaryReaderEOF reader = new BinaryReaderEOF(inputStream);

            byte[] signature = reader.ReadBytes(3);
            byte   version   = reader.ReadByte();

            if (signature[0] != 'S' || signature[1] != 'V' || signature[2] != 'N')
            {
                throw new InvalidOperationException("The signature is invalid.");
            }
            if (version != 0)
            {
                throw new Exception("Unsupported SVN diff version");
            }

            List <SvnDiff> diffs = new List <SvnDiff>();

            while (!reader.EOF)
            {
                SvnDiff diff = new SvnDiff();

                diff.SourceViewOffset = ReadInt(reader);
                diff.SourceViewLength = ReadInt(reader);
                diff.TargetViewLength = ReadInt(reader);
                int instructionSectionLength = (int)ReadInt(reader);
                int dataSectionLength        = (int)ReadInt(reader);

                diff.InstructionSectionBytes = reader.ReadBytes(instructionSectionLength);
                diff.DataSectionBytes        = reader.ReadBytes(dataSectionLength);

                diffs.Add(diff);
            }
            return(diffs.ToArray());
        }
        private static ulong ReadInt(BinaryReaderEOF reader, out int bytesRead)
        {
            ulong value = 0;

            bytesRead = 0;

            byte b = reader.ReadByte();

            bytesRead++;

            while ((b & 0x80) != 0)
            {
                value  |= (byte)(b & 0x7F);
                value <<= 7;

                b = reader.ReadByte();
                bytesRead++;
            }

            value |= (ulong)b;

            return(value);
        }