/*
* SubstringDiff.java
*
* Copyright (C) 2009-12 by RStudio, Inc.
*
* Unless you have received this program directly from RStudio pursuant
* to the terms of a commercial license agreement with RStudio, then
* this program is licensed to you under the terms of version 3 of the
* GNU Affero General Public License. This program is distributed WITHOUT
* ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
* AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
*
*/
package org.rstudio.core.client.patch;
public class SubstringDiff
{
public SubstringDiff(String origVal, String newVal)
{
// Figure out how many characters at the beginning of the two strings
// are identical.
int headLimit = Math.min(origVal.length(), newVal.length());
int head;
for (head = 0;
head < headLimit && origVal.charAt(head) == newVal.charAt(head);
head++)
{}
// Figure out how many characters at the end of the two strings are
// identical, but don't go past the range we established in the above
// step (i.e., anything already in the head can't be part of the tail).
int tailDelta = newVal.length() - origVal.length();
int tailLimit = Math.max(head, head - tailDelta);
int tail;
for (tail = origVal.length();
tail > tailLimit && origVal.charAt(tail-1) == newVal.charAt(tail+tailDelta-1);
tail--)
{}
// Now we have a chunk of newVal that is unique (it may simply be "")
// and offset_/length_ show what region within oldDoc it replaces.
replacement_ = newVal.substring(head, tail + tailDelta);
offset_ = head;
length_ = tail - head;
}
public String getReplacement()
{
return replacement_;
}
public int getOffset()
{
return offset_;
}
public int getLength()
{
return length_;
}
public String patch(String original)
{
if (isEmpty())
return original;
return original.substring(0, offset_)
+ replacement_
+ original.substring(offset_ + length_);
}
/**
* @return True iff there was no difference between the strings.
*/
public boolean isEmpty()
{
return length_ == 0 && replacement_.length() == 0;
}
private final int offset_;
private final int length_;
private final String replacement_;
/*
public static void test()
{
test("", "", 0, 0, "");
test("a", "a", 1, 0, "");
test("ab", "ab", 2, 0, "");
test("ab", "a", 1, 1, "");
test("abc", "ac", 1, 1, "");
test("abc", "adc", 1, 1, "d");
test("abc", "bc", 0, 1, "");
test("bc", "abc", 0, 0, "a");
test("a\nb\nc", "a\nc", 2, 2, "");
}
static void test(String old, String neu, int offset, int len, String repl)
{
SubstringDiff diff = new SubstringDiff(old, neu);
assert diff.getOffset() == offset
&& diff.getLength() == len
&& diff.getReplacement().equals(repl) :
"\"" + old + "\" - \"" + neu + "\" => " +
"\"" + diff.getReplacement() + "\" [" + diff.getOffset() + ", " + diff.getLength() + "]";
assert diff.patch(old).equals(neu);
}
*/
}