public void Extract2(int index, int length, string expectedToString) { Substring substring = new Substring("abcde", new Range(1, 3)); Assert.AreEqual(expectedToString, substring.Extract(index, length).ToString()); }
// Determines the longest common subsequence between two sequences and populates the // list of diffs derived from the result as we go. Each recursive step identifies // a middle "snake" (a common sequence) then splits the problem until nothing remains. private void ComputeLCS(Substring left, Substring right) { int n = left.Length; int m = right.Length; if (n != 0 && m != 0) { int middleSnakeLeftStartIndex, middleSnakeRightStartIndex, middleSnakeLength; int ses = FindMiddleSnake(left, right, out middleSnakeLeftStartIndex, out middleSnakeRightStartIndex, out middleSnakeLength); if (ses > 1) { // If SES >= 2 then the edit script includes at least 2 differences, so we divide the problem. ComputeLCS( left.Extract(0, middleSnakeLeftStartIndex), right.Extract(0, middleSnakeRightStartIndex)); EmitDiffsFromCommonSequence( left.Range.StartIndex + middleSnakeLeftStartIndex, right.Range.StartIndex + middleSnakeRightStartIndex, middleSnakeLength); ComputeLCS( left.Extract(middleSnakeLeftStartIndex + middleSnakeLength), right.Extract(middleSnakeRightStartIndex + middleSnakeLength)); } else { // If SES = 1, then exactly one symbol needs to be added or deleted from either sequence. // If SES = 0, then both sequences are equal. if (ses != 0) { // The middle snake is the common part after the change so we just need to grab the // common part before the change. EmitDiffsFromCommonSequence( left.Range.StartIndex, right.Range.StartIndex, Math.Min(middleSnakeLeftStartIndex, middleSnakeRightStartIndex)); } EmitDiffsFromCommonSequence( left.Range.StartIndex + middleSnakeLeftStartIndex, right.Range.StartIndex + middleSnakeRightStartIndex, middleSnakeLength); } } }
private static void FastDiff(IList<Diff> diffs, Substring left, Substring right, bool boundRuntime) { // If either document is empty, then the change covers the whole document. if (left.Length == 0 || right.Length == 0) { diffs.Add(new Diff(DiffKind.Change, left.Range, right.Range)); return; } // Reduce the problem size by identifying a common prefix and suffix, if any. int commonPrefixLength = left.FindCommonPrefixLength(right); if (commonPrefixLength != 0) { if (commonPrefixLength == left.Length && commonPrefixLength == right.Length) { diffs.Add(new Diff(DiffKind.NoChange, left.Range, right.Range)); return; } diffs.Add(new Diff(DiffKind.NoChange, new Range(left.Range.StartIndex, commonPrefixLength), new Range(right.Range.StartIndex, commonPrefixLength))); } int commonSuffixLength = left.Extract(commonPrefixLength).FindCommonSuffixLength(right.Extract(commonPrefixLength)); // Now work on the middle part. Substring leftMiddle = left.Extract(commonPrefixLength, left.Length - commonPrefixLength - commonSuffixLength); Substring rightMiddle = right.Extract(commonPrefixLength, right.Length - commonPrefixLength - commonSuffixLength); SlowDiff(diffs, leftMiddle, rightMiddle, boundRuntime); // Tack on the final diff for the common suffix, if any. if (commonSuffixLength != 0) { diffs.Add(new Diff(DiffKind.NoChange, new Range(leftMiddle.Range.EndIndex, commonSuffixLength), new Range(rightMiddle.Range.EndIndex, commonSuffixLength))); } }
private static void WriteContext(MarkupStreamWriter writer, Substring context, int maxContextLength) { if (context.Length < maxContextLength) { writer.Write(context.ToString()); } else { int split = maxContextLength / 2; if (split > 0) { writer.Write(context.Extract(0, split).ToString()); writer.WriteEllipsis(); writer.Write(context.Extract(context.Length - split)); } } }