public static SvnDiff CreateReplaceDiff(byte[] bytes, int index, int length)
        {
            SvnDiff svnDiff = null;

            if (length > 0)
            {
                svnDiff = new SvnDiff();

                svnDiff.SourceViewOffset = 0;
                svnDiff.SourceViewLength = 0;
                svnDiff.TargetViewLength = (ulong)length;

                MemoryStream instructionStream = new MemoryStream();
                BinaryWriter instructionWriter = new BinaryWriter(instructionStream);
                MemoryStream dataStream        = new MemoryStream();
                BinaryWriter dataWriter        = new BinaryWriter(dataStream);

                dataWriter.Write(bytes, index, length);
                dataWriter.Flush();

                svnDiff.DataSectionBytes = dataStream.ToArray();

                SvnDiffInstruction instruction = new SvnDiffInstruction();
                instruction.OpCode = SvnDiffInstructionOpCode.CopyFromNewData;
                instruction.Length = (ulong)length;

                WriteInstruction(instructionWriter, instruction);
                instructionWriter.Flush();

                svnDiff.InstructionSectionBytes = instructionStream.ToArray();
            }
            return(svnDiff);
        }
        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());
        }
        public static byte[] ApplySvnDiff(SvnDiff svnDiff, byte[] source, int sourceDataStartIndex)
        {
            const int BUFFER_EXPAND_SIZE = 5000;

            byte[] buffer      = new byte[BUFFER_EXPAND_SIZE];
            int    targetIndex = 0;

            MemoryStream    instructionStream = new MemoryStream(svnDiff.InstructionSectionBytes);
            BinaryReaderEOF instructionReader = new BinaryReaderEOF(instructionStream);
            MemoryStream    dataStream        = new MemoryStream(svnDiff.DataSectionBytes);
            BinaryReader    dataReader        = new BinaryReader(dataStream);

            SvnDiffInstruction instruction = ReadInstruction(instructionReader);

            while (instruction != null)
            {
                if (targetIndex + (int)instruction.Length > buffer.Length)
                {
                    Array.Resize(ref buffer, buffer.Length + (int)instruction.Length + BUFFER_EXPAND_SIZE);
                }

                switch (instruction.OpCode)
                {
                case SvnDiffInstructionOpCode.CopyFromSource:
                    Array.Copy(source,
                               (int)instruction.Offset + sourceDataStartIndex,
                               buffer,
                               targetIndex,
                               (int)instruction.Length);
                    targetIndex += (int)instruction.Length;
                    break;

                case SvnDiffInstructionOpCode.CopyFromTarget:
                    // Cannot use Array.Copy because Offset + Length may be greater then starting targetIndex
                    for (int i = 0; i < (int)instruction.Length; i++)
                    {
                        buffer[targetIndex] = buffer[(int)instruction.Offset + i];
                        targetIndex++;
                    }
                    break;

                case SvnDiffInstructionOpCode.CopyFromNewData:
                    byte[] newData = dataReader.ReadBytes((int)instruction.Length);
                    Array.Copy(newData, 0, buffer, targetIndex, newData.Length);
                    targetIndex += newData.Length;
                    break;
                }

                instruction = ReadInstruction(instructionReader);
            }

            Array.Resize(ref buffer, targetIndex);
            return(buffer);
        }
        public static void WriteSvnDiff(SvnDiff svnDiff, Stream stream)
        {
            BinaryWriter writer = new BinaryWriter(stream);

            if (svnDiff != null)
            {
                int bytesWritten;
                WriteInt(writer, svnDiff.SourceViewOffset, out bytesWritten);
                WriteInt(writer, svnDiff.SourceViewLength, out bytesWritten);
                WriteInt(writer, svnDiff.TargetViewLength, out bytesWritten);
                WriteInt(writer, (ulong)svnDiff.InstructionSectionBytes.Length, out bytesWritten);
                WriteInt(writer, (ulong)svnDiff.DataSectionBytes.Length, out bytesWritten);

                writer.Write(svnDiff.InstructionSectionBytes);
                writer.Write(svnDiff.DataSectionBytes);
            }
            writer.Flush();
        }
示例#5
0
        public static string GetBase64SvnDiffData(byte[] data)
        {
            int index = 0;

            using (MemoryStream svnDiffStream = new MemoryStream())
            {
                SvnDiffEngine.WriteSvnDiffSignature(svnDiffStream);
                while (index < data.Length)
                {
                    int length = data.Length - index;
                    if (length > MAX_DIFF_SIZE)
                    {
                        length = MAX_DIFF_SIZE;
                    }

                    SvnDiff svnDiff = SvnDiffEngine.CreateReplaceDiff(data, index, length);
                    SvnDiffEngine.WriteSvnDiff(svnDiff, svnDiffStream);

                    index += length;
                }
                byte[] diff = svnDiffStream.ToArray();
                return(Convert.ToBase64String(diff));
            }
        }