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); }
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 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); }
private static void WriteInstruction(BinaryWriter writer, SvnDiffInstruction instruction) { byte opCodeAndLength = (byte)((int)instruction.OpCode << 6); int bytesWritten = 0; if ((instruction.Length & 0x3F) == instruction.Length) { opCodeAndLength |= (byte)(instruction.Length & 0x3F); writer.Write(opCodeAndLength); } else { writer.Write(opCodeAndLength); WriteInt(writer, instruction.Length, out bytesWritten); } if (instruction.OpCode == SvnDiffInstructionOpCode.CopyFromSource || instruction.OpCode == SvnDiffInstructionOpCode.CopyFromTarget) { WriteInt(writer, instruction.Offset, out bytesWritten); } }