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