海量编程文章、技术教程与实战案例

网站首页 > 技术文章 正文

java文本对比工具源码7

yimeika 2025-07-03 20:41:41 技术文章 18 ℃

/**

* Add some padding on text start and end so that edges can match something.

* Intended to be called only from within patch_apply.

* @param patches Array of Patch objects.

* @return The padding string added to each side.

*/

public String patch_addPadding(LinkedList<Patch> patches) {

short paddingLength = this.Patch_Margin;

String nullPadding = "";

for (short x = 1; x <= paddingLength; x++) {

nullPadding += String.valueOf((char) x);

}

// Bump all the patches forward.

for (Patch aPatch : patches) {

aPatch.start1 += paddingLength;

aPatch.start2 += paddingLength;

}

// Add some padding on start of first diff.

Patch patch = patches.getFirst();

LinkedList<Diff> diffs = patch.diffs;

if (diffs.isEmpty() || diffs.getFirst().operation != Operation.EQUAL) {

// Add nullPadding equality.

diffs.addFirst(new Diff(Operation.EQUAL, nullPadding));

patch.start1 -= paddingLength; // Should be 0.

patch.start2 -= paddingLength; // Should be 0.

patch.length1 += paddingLength;

patch.length2 += paddingLength;

} else if (paddingLength > diffs.getFirst().text.length()) {

// Grow first equality.

Diff firstDiff = diffs.getFirst();

int extraLength = paddingLength - firstDiff.text.length();

firstDiff.text = nullPadding.substring(firstDiff.text.length())

+ firstDiff.text;

patch.start1 -= extraLength;

patch.start2 -= extraLength;

patch.length1 += extraLength;

patch.length2 += extraLength;

}

// Add some padding on end of last diff.

patch = patches.getLast();

diffs = patch.diffs;

if (diffs.isEmpty() || diffs.getLast().operation != Operation.EQUAL) {

// Add nullPadding equality.

diffs.addLast(new Diff(Operation.EQUAL, nullPadding));

patch.length1 += paddingLength;

patch.length2 += paddingLength;

} else if (paddingLength > diffs.getLast().text.length()) {

// Grow last equality.

Diff lastDiff = diffs.getLast();

int extraLength = paddingLength - lastDiff.text.length();

lastDiff.text += nullPadding.substring(0, extraLength);

patch.length1 += extraLength;

patch.length2 += extraLength;

}

return nullPadding;

}

/**

* Look through the patches and break up any which are longer than the

* maximum limit of the match algorithm.

* Intended to be called only from within patch_apply.

* @param patches LinkedList of Patch objects.

*/

public void patch_splitMax(LinkedList<Patch> patches) {

short patch_size = Match_MaxBits;

String precontext, postcontext;

Patch patch;

int start1, start2;

boolean empty;

Operation diff_type;

String diff_text;

ListIterator<Patch> pointer = patches.listIterator();

Patch bigpatch = pointer.hasNext() ? pointer.next() : null;

while (bigpatch != null) {

if (bigpatch.length1 <= Match_MaxBits) {

bigpatch = pointer.hasNext() ? pointer.next() : null;

continue;

}

// Remove the big old patch.

pointer.remove();

start1 = bigpatch.start1;

start2 = bigpatch.start2;

precontext = "";

while (!bigpatch.diffs.isEmpty()) {

// Create one of several smaller patches.

patch = new Patch();

empty = true;

patch.start1 = start1 - precontext.length();

patch.start2 = start2 - precontext.length();

if (precontext.length() != 0) {

patch.length1 = patch.length2 = precontext.length();

patch.diffs.add(new Diff(Operation.EQUAL, precontext));

}

while (!bigpatch.diffs.isEmpty()

&& patch.length1 < patch_size - Patch_Margin) {

diff_type = bigpatch.diffs.getFirst().operation;

diff_text = bigpatch.diffs.getFirst().text;

if (diff_type == Operation.INSERT) {

// Insertions are harmless.

patch.length2 += diff_text.length();

start2 += diff_text.length();

patch.diffs.addLast(bigpatch.diffs.removeFirst());

empty = false;

} else if (diff_type == Operation.DELETE && patch.diffs.size() == 1

&& patch.diffs.getFirst().operation == Operation.EQUAL

&& diff_text.length() > 2 * patch_size) {

// This is a large deletion. Let it pass in one chunk.

patch.length1 += diff_text.length();

start1 += diff_text.length();

empty = false;

patch.diffs.add(new Diff(diff_type, diff_text));

bigpatch.diffs.removeFirst();

} else {

// Deletion or equality. Only take as much as we can stomach.

diff_text = diff_text.substring(0, Math.min(diff_text.length(),

patch_size - patch.length1 - Patch_Margin));

patch.length1 += diff_text.length();

start1 += diff_text.length();

if (diff_type == Operation.EQUAL) {

patch.length2 += diff_text.length();

start2 += diff_text.length();

} else {

empty = false;

}

patch.diffs.add(new Diff(diff_type, diff_text));

if (diff_text.equals(bigpatch.diffs.getFirst().text)) {

bigpatch.diffs.removeFirst();

} else {

bigpatch.diffs.getFirst().text = bigpatch.diffs.getFirst().text

.substring(diff_text.length());

}

}

}

// Compute the head context for the next patch.

precontext = diff_text2(patch.diffs);

precontext = precontext.substring(Math.max(0, precontext.length()

- Patch_Margin));

// Append the end context for this patch.

if (diff_text1(bigpatch.diffs).length() > Patch_Margin) {

postcontext = diff_text1(bigpatch.diffs).substring(0, Patch_Margin);

} else {

postcontext = diff_text1(bigpatch.diffs);

}

if (postcontext.length() != 0) {

patch.length1 += postcontext.length();

patch.length2 += postcontext.length();

if (!patch.diffs.isEmpty()

&& patch.diffs.getLast().operation == Operation.EQUAL) {

patch.diffs.getLast().text += postcontext;

} else {

patch.diffs.add(new Diff(Operation.EQUAL, postcontext));

}

}

if (!empty) {

pointer.add(patch);

}

}

bigpatch = pointer.hasNext() ? pointer.next() : null;

}

}

/**

* Take a list of patches and return a textual representation.

* @param patches List of Patch objects.

* @return Text representation of patches.

*/

public String patch_toText(List<Patch> patches) {

StringBuilder text = new StringBuilder();

for (Patch aPatch : patches) {

text.append(aPatch);

}

return text.toString();

}

Tags:

最近发表
标签列表