|
What this is
Other links
The source code
/*
* Sun Public License Notice
*
* The contents of this file are subject to the Sun Public License
* Version 1.0 (the "License"). You may not use this file except in
* compliance with the License. A copy of the License is available at
* http://www.sun.com/
*
* The Original Code is NetBeans. The Initial Developer of the Original
* Code is Sun Microsystems, Inc. Portions Copyright 1997-2003 Sun
* Microsystems, Inc. All Rights Reserved.
*/
package org.netbeans.modules.diff.builtin;
import java.io.BufferedReader;
import java.io.PushbackReader;
import java.io.Reader;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import org.netbeans.api.diff.Difference;
import org.netbeans.modules.diff.cmdline.CmdlineDiffProvider;
/**
* Utility class for patch application.
*
* @author Martin Entlicher
*/
public class Patch extends Reader {
private static final int CONTEXT_DIFF = 0;
private static final int NORMAL_DIFF = 1;
private static final int UNIFIED_DIFF = 2;
private Difference[] diffs;
private PushbackReader source;
private int currDiff = 0;
private int line = 1;
private String newLine = null; // String, that is used to separate lines
private StringBuffer buff = new StringBuffer();
/** Creates a new instance of Patch */
private Patch(Difference[] diffs, Reader source) {
this.diffs = diffs;
this.source = new PushbackReader(new BufferedReader(source), 1);
}
/**
* Apply the patch to the source.
* @param diffs The differences to patch
* @param source The source stream
* @return The patched stream
* @throws IOException When reading from the source stread fails
* @throws ParseException When the source does not match the patch to be applied
*/
public static Reader apply(Difference[] diffs, Reader source) {//throws IOException, ParseException {
return new Patch(diffs, source);
}
/**
* Parse the differences.
*
public static Difference[] parse(Reader source) throws IOException {
return parseContextDiff(source);
}
*/
/**
* Parse the differences and corresponding file names.
*/
public static FileDifferences[] parse(Reader source) throws IOException {
List fileDifferences = new ArrayList();
//int pushBackLimit = DIFFERENCE_DELIMETER.length();
//PushbackReader recognizedSource = new PushbackReader(source, pushBackLimit);
Patch.SinglePatchReader patchReader = new Patch.SinglePatchReader(source);
int[] diffType = new int[1];
String[] fileName = new String[1];
while (patchReader.hasNextPatch(diffType, fileName)) {
//System.out.println("Have a next patch of name '"+fileName[0]+"'");
Difference[] diffs = null;
switch (diffType[0]) {
case CONTEXT_DIFF:
diffs = parseContextDiff(patchReader);
break;
case UNIFIED_DIFF:
diffs = parseUnifiedDiff(patchReader);
break;
case NORMAL_DIFF:
diffs = parseNormalDiff(patchReader);
break;
}
if (diffs != null) {
fileDifferences.add(new FileDifferences((fileName[0] != null) ? fileName[0].intern() : null, diffs));
}
}
return (FileDifferences[]) fileDifferences.toArray(new FileDifferences[fileDifferences.size()]);
}
public int read(char[] cbuf, int off, int length) throws java.io.IOException {
if (buff.length() < length) {
doRetrieve(length - buff.length());
}
int ret = Math.min(buff.length(), length);
if (ret == 0) return -1;
String retStr = buff.substring(0, ret);
char[] retChars = retStr.toCharArray();
System.arraycopy(retChars, 0, cbuf, off, ret);
buff.delete(0, ret);
return ret;
}
public void close() throws java.io.IOException {
source.close();
}
private void doRetrieve(int length) throws IOException {
for (int size = 0; size < length; line++) {
if (currDiff < diffs.length &&
((Difference.ADD == diffs[currDiff].getType() &&
line == (diffs[currDiff].getFirstStart() + 1)) ||
(Difference.ADD != diffs[currDiff].getType() &&
line == diffs[currDiff].getFirstStart()))) {
if (compareText(source, diffs[currDiff].getFirstText())) {
String text = convertNewLines(diffs[currDiff].getSecondText(), newLine);
buff.append(text);
currDiff++;
} else {
throw new IOException("Patch not applicable.");
}
}
StringBuffer newLineBuffer = null;
if (newLine == null) {
newLineBuffer = new StringBuffer();
}
String lineStr = readLine(source, newLineBuffer);
if (newLineBuffer != null) newLine = newLineBuffer.toString();
if (lineStr == null) break;
buff.append(lineStr);
buff.append(newLine);
}
}
/** Reads a line and returns the char sequence for newline */
private static String readLine(PushbackReader r, StringBuffer nl) throws IOException {
StringBuffer line = new StringBuffer();
int ic = r.read();
if (ic == -1) return null;
char c = (char) ic;
while (c != '\n' && c != '\r') {
line.append(c);
ic = r.read();
if (ic == -1) break;
c = (char) ic;
}
if (nl != null) {
nl.append(c);
}
if (c == '\r') {
try {
ic = r.read();
if (ic != -1) {
c = (char) ic;
if (c != '\n') r.unread(c);
else if (nl != null) nl.append(c);
}
} catch (IOException ioex) {}
}
return line.toString();
}
private static String convertNewLines(String text, String newLine) {
if (text == null) return ""; // NOI18N
if (newLine == null) return text;
StringBuffer newText = new StringBuffer();
for (int i = 0; i < text.length(); i++) {
char c = text.charAt(i);
if (c == '\n') newText.append(newLine);
else if (c == '\r') {
if ((i + 1) < text.length() && text.charAt(i + 1) == '\n') {
i++;
newText.append(newLine);
}
} else newText.append(c);
}
return newText.toString();
}
private boolean compareText(PushbackReader source, String text) throws IOException {
if (text == null || text.length() == 0) return true;
text = adjustTextNL(text);
char[] chars = new char[text.length()];
int pos = 0;
int n;
String readStr = "";
do {
n = source.read(chars, 0, chars.length - pos);
if (n > 0) {
pos += n;
readStr = readStr + new String(chars, 0, n);
}
if (readStr.endsWith("\r")) {
try {
char c = (char) source.read();
if (c != '\n') source.unread(c);
else readStr += c;
} catch (IOException ioex) {}
}
readStr = adjustTextNL(readStr);
pos = readStr.length();
} while (n > 0 && pos < chars.length);
readStr.getChars(0, readStr.length(), chars, 0);
line += numChars('\n', chars);
//System.out.println("Comparing text of the diff:\n'"+text+"'\nWith the read text:\n'"+readStr+"'\n");
//System.out.println(" EQUALS = "+readStr.equals(text));
return readStr.equals(text);
}
/**
* When comparing the two texts, it's important to ignore different line endings.
* This method assures, that only '\n' is used as the line ending.
*/
private String adjustTextNL(String text) {
text = org.openide.util.Utilities.replaceString(text, "\r\n", "\n");
text = org.openide.util.Utilities.replaceString(text, "\n\r", "\n");
text = org.openide.util.Utilities.replaceString(text, "\r", "\n");
return text;
}
private static int numChars(char c, char[] chars) {
int n = 0;
for (int i = 0; i < chars.length; i++) {
if (chars[i] == c) n++;
}
return n;
}
private static final String CONTEXT_MARK1B = "*** ";
private static final String CONTEXT_MARK1E = " ****";
private static final String CONTEXT_MARK2B = "--- ";
private static final String CONTEXT_MARK2E = " ----";
private static final String CONTEXT_MARK_DELIMETER = ",";
private static final String DIFFERENCE_DELIMETER = "***************";
private static final String LINE_PREP = " ";
private static final String LINE_PREP_ADD = "+ ";
private static final String LINE_PREP_REMOVE = "- ";
private static final String LINE_PREP_CHANGE = "! ";
private static Difference[] parseContextDiff(Reader in) throws IOException {
BufferedReader br = new BufferedReader(in);
ArrayList diffs = new ArrayList();
String line = null;
do {
if (line == null || !DIFFERENCE_DELIMETER.equals(line)) {
do {
line = br.readLine();
} while (line != null && !DIFFERENCE_DELIMETER.equals(line));
}
int[] firstInterval = new int[2];
line = br.readLine();
if (line != null && line.startsWith(CONTEXT_MARK1B)) {
try {
readNums(line, CONTEXT_MARK1B.length(), firstInterval);
} catch (NumberFormatException nfex) {
throw new IOException(nfex.getLocalizedMessage());
}
} else continue;
ArrayList firstChanges = new ArrayList(); // List of intervals and texts
line = fillChanges(firstInterval, br, CONTEXT_MARK2B, firstChanges);
int[] secondInterval = new int[2];
if (line != null && line.startsWith(CONTEXT_MARK2B)) {
try {
readNums(line, CONTEXT_MARK2B.length(), secondInterval);
} catch (NumberFormatException nfex) {
throw new IOException(nfex.getLocalizedMessage());
}
} else continue;
ArrayList secondChanges = new ArrayList(); // List of intervals and texts
line = fillChanges(secondInterval, br, DIFFERENCE_DELIMETER, secondChanges);
mergeChanges(firstInterval, secondInterval, firstChanges, secondChanges, diffs);
} while (line != null);
return (Difference[]) diffs.toArray(new Difference[diffs.size()]);
}
private static void readNums(String str, int off, int[] values) throws NumberFormatException {
int end = str.indexOf(CONTEXT_MARK_DELIMETER, off);
if (end > 0) {
values[0] = Integer.parseInt(str.substring(off, end).trim());
} else throw new NumberFormatException("Missing comma.");
off = end + 1;
end = str.indexOf(' ', off);
if (end > 0) {
values[1] = Integer.parseInt(str.substring(off, end).trim());
} else throw new NumberFormatException("Missing final space.");
}
private static String fillChanges(int[] interval, BufferedReader br,
String untilStartsWith, List changes) throws IOException {
String line = br.readLine();
for (int pos = interval[0]; pos <= interval[1]; pos++) {
if (line == null || line.startsWith(untilStartsWith)) break;
if (line.startsWith(LINE_PREP_ADD)) {
int[] changeInterval = new int[3];
changeInterval[0] = pos;
changeInterval[2] = Difference.ADD;
StringBuffer changeText = new StringBuffer();
changeText.append(line.substring(LINE_PREP_ADD.length()));
changeText.append('\n');
do {
line = br.readLine();
if (line == null)
break;
if (line.startsWith(LINE_PREP_ADD)) {
changeText.append(line.substring(LINE_PREP_ADD.length()));
changeText.append('\n');
} else {
break;
}
pos++;
} while (true);
changeInterval[1] = pos;
changes.add(changeInterval);
changes.add(changeText.toString());
} else if (line.startsWith(LINE_PREP_REMOVE)) {
int[] changeInterval = new int[3];
changeInterval[0] = pos;
changeInterval[2] = Difference.DELETE;
StringBuffer changeText = new StringBuffer();
changeText.append(line.substring(LINE_PREP_REMOVE.length()));
changeText.append('\n');
do {
line = br.readLine();
if (line == null)
break;
if (line.startsWith(LINE_PREP_REMOVE)) {
changeText.append(line.substring(LINE_PREP_REMOVE.length()));
changeText.append('\n');
} else {
break;
}
pos++;
} while (true);
changeInterval[1] = pos;
changes.add(changeInterval);
changes.add(changeText.toString());
} else if (line.startsWith(LINE_PREP_CHANGE)) {
int[] changeInterval = new int[3];
changeInterval[0] = pos;
changeInterval[2] = Difference.CHANGE;
StringBuffer changeText = new StringBuffer();
changeText.append(line.substring(LINE_PREP_CHANGE.length()));
changeText.append('\n');
do {
line = br.readLine();
if (line == null)
break;
if (line.startsWith(LINE_PREP_CHANGE)) {
changeText.append(line.substring(LINE_PREP_CHANGE.length()));
changeText.append('\n');
} else {
break;
}
pos++;
} while (true);
changeInterval[1] = pos;
changes.add(changeInterval);
changes.add(changeText.toString());
} else {
line = br.readLine();
}
}
return line;
}
private static void mergeChanges(int[] firstInterval, int[] secondInterval,
List firstChanges, List secondChanges, List diffs) {
int p1, p2;
int n1 = firstChanges.size();
int n2 = secondChanges.size();
//System.out.println("mergeChanges(("+firstInterval[0]+", "+firstInterval[1]+"), ("+secondInterval[0]+", "+secondInterval[1]+"))");
//System.out.println("firstChanges.size() = "+n1);
//System.out.println("secondChanges.size() = "+n2);
int firstToSecondIntervalShift = secondInterval[0] - firstInterval[0];
//System.out.println("shift = "+firstToSecondIntervalShift);
for (p1 = p2 = 0; p1 < n1 || p2 < n2; ) {
boolean isAddRemove = true;
while (isAddRemove && p1 < n1) {
int[] interval = (int[]) firstChanges.get(p1);
if (p2 < n2) {
int[] interval2 = (int[]) secondChanges.get(p2);
if (interval[0] + firstToSecondIntervalShift > interval2[0]) break;
// We need to set differences successively. Differences with
// higher line numbers must not precede differences with
// smaller line numbers
}
isAddRemove = interval[2] == Difference.ADD || interval[2] == Difference.DELETE;
if (isAddRemove) {
if (interval[2] == Difference.ADD) {
diffs.add(new Difference(interval[2], interval[0] - 1, 0,
interval[0] + firstToSecondIntervalShift,
interval[1] + firstToSecondIntervalShift,
(String) firstChanges.get(p1 + 1), ""));
firstToSecondIntervalShift += interval[1] - interval[0] + 1;
} else {
diffs.add(new Difference(interval[2], interval[0], interval[1],
interval[0] + firstToSecondIntervalShift - 1, 0,
(String) firstChanges.get(p1 + 1), ""));
firstToSecondIntervalShift -= interval[1] - interval[0] + 1;
}
p1 += 2;
//System.out.println("added diff = "+diffs.get(diffs.size() - 1));
//System.out.println("new shift = "+firstToSecondIntervalShift);
}
}
isAddRemove = true;
while (isAddRemove && p2 < n2) {
int[] interval = (int[]) secondChanges.get(p2);
isAddRemove = interval[2] == Difference.ADD || interval[2] == Difference.DELETE;
if (isAddRemove) {
if (interval[2] == Difference.ADD) {
diffs.add(new Difference(interval[2],
interval[0] - firstToSecondIntervalShift - 1, 0,
interval[0], interval[1],
"", (String) secondChanges.get(p2 + 1)));
firstToSecondIntervalShift += interval[1] - interval[0] + 1;
} else {
diffs.add(new Difference(interval[2],
interval[0] - firstToSecondIntervalShift,
interval[1] - firstToSecondIntervalShift,
interval[0] - 1, 0,
"", (String) secondChanges.get(p2 + 1)));
firstToSecondIntervalShift -= interval[1] - interval[0] + 1;
}
p2 += 2;
//System.out.println("added diff = "+diffs.get(diffs.size() - 1));
//System.out.println("new shift = "+firstToSecondIntervalShift);
}
}
// Change is remaining
if (p1 < n1 && p2 < n2) {
int[] interval1 = (int[]) firstChanges.get(p1);
int[] interval2 = (int[]) secondChanges.get(p2);
diffs.add(new Difference(interval1[2], interval1[0], interval1[1],
interval2[0], interval2[1],
(String) firstChanges.get(p1 + 1),
(String) secondChanges.get(p2 + 1)));
p1 += 2;
p2 += 2;
firstToSecondIntervalShift += interval2[1] - interval2[0] - (interval1[1] - interval1[0]);
//System.out.println("added diff = "+diffs.get(diffs.size() - 1));
//System.out.println("new shift = "+firstToSecondIntervalShift);
}
}
}
private static final String UNIFIED_MARK = "@@";
private static final String UNIFIED_MARK1 = "--- ";
private static final String UNIFIED_MARK2 = "+++ ";
private static final String LINE_PREP_UNIF_ADD = "+";
private static final String LINE_PREP_UNIF_REMOVE = "-";
private static final String LINE_PREP_UNIF_CHANGE = null;
private static Difference[] parseUnifiedDiff(Reader in) throws IOException {
BufferedReader br = new BufferedReader(in);
ArrayList diffs = new ArrayList();
String line = null;
do {
while (line == null || !(line.startsWith(UNIFIED_MARK) &&
line.length() > UNIFIED_MARK.length() &&
line.endsWith(UNIFIED_MARK))) {
line = br.readLine();
if (line == null) break;
}
if (line == null) continue;
int[] intervals = new int[4];
try {
readUnifiedNums(line, UNIFIED_MARK.length(), intervals);
} catch (NumberFormatException nfex) {
throw new IOException(nfex.getLocalizedMessage());
}
line = fillUnidifChanges(intervals, br, diffs);
} while (line != null);
return (Difference[]) diffs.toArray(new Difference[diffs.size()]);
}
private static void readUnifiedNums(String str, int off, int[] values) throws NumberFormatException {
while (str.charAt(off) == ' ' || str.charAt(off) == '-') off++;
int end = str.indexOf(CONTEXT_MARK_DELIMETER, off);
if (end > 0) {
values[0] = Integer.parseInt(str.substring(off, end).trim());
} else throw new NumberFormatException("Missing comma.");
off = end + 1;
end = str.indexOf(' ', off);
if (end > 0) {
values[1] = Integer.parseInt(str.substring(off, end).trim());
} else throw new NumberFormatException("Missing middle space.");
off = end + 1;
while (str.charAt(off) == ' ' || str.charAt(off) == '+') off++;
end = str.indexOf(CONTEXT_MARK_DELIMETER, off);
if (end > 0) {
values[2] = Integer.parseInt(str.substring(off, end).trim());
} else throw new NumberFormatException("Missing second comma.");
off = end + 1;
end = str.indexOf(' ', off);
if (end > 0) {
values[3] = Integer.parseInt(str.substring(off, end).trim());
} else throw new NumberFormatException("Missing final space.");
values[1] += values[0] - 1;
values[3] += values[2] - 1;
}
private static String fillUnidifChanges(int[] interval, BufferedReader br,
List diffs) throws IOException {
String line = br.readLine();
int pos1 = interval[0];
int pos2 = interval[2];
while (line != null && pos1 <= interval[1] && pos2 <= interval[3]) {
if (line.startsWith(LINE_PREP_UNIF_ADD)) {
int begin = pos2;
StringBuffer changeText = new StringBuffer();
changeText.append(line.substring(LINE_PREP_UNIF_ADD.length()));
changeText.append('\n');
do {
line = br.readLine();
pos2++;
if (line.startsWith(LINE_PREP_UNIF_ADD)) {
changeText.append(line.substring(LINE_PREP_UNIF_ADD.length()));
changeText.append('\n');
} else {
break;
}
} while (true);
Difference diff = null;
if (diffs.size() > 0) {
Difference previousDiff = (Difference) diffs.get(diffs.size() - 1);
if (Difference.DELETE == previousDiff.getType() && previousDiff.getFirstEnd() == (pos1 - 1)) {
diff = new Difference(Difference.CHANGE,
previousDiff.getFirstStart(), previousDiff.getFirstEnd(),
begin, pos2 - 1, previousDiff.getFirstText(), changeText.toString());
diffs.remove(diffs.size() - 1);
}
}
if (diff == null) {
diff = new Difference(Difference.ADD, pos1 - 1, 0, begin, pos2 - 1, null, changeText.toString());
}
diffs.add(diff);
} else if (line.startsWith(LINE_PREP_UNIF_REMOVE)) {
int begin = pos1;
StringBuffer changeText = new StringBuffer();
changeText.append(line.substring(LINE_PREP_UNIF_REMOVE.length()));
changeText.append('\n');
do {
line = br.readLine();
pos1++;
if (line.startsWith(LINE_PREP_UNIF_REMOVE)) {
changeText.append(line.substring(LINE_PREP_UNIF_REMOVE.length()));
changeText.append('\n');
} else {
break;
}
} while (true);
Difference diff = null;
if (diffs.size() > 0) {
Difference previousDiff = (Difference) diffs.get(diffs.size() - 1);
if (Difference.ADD == previousDiff.getType() && previousDiff.getSecondEnd() == (pos2 - 1)) {
diff = new Difference(Difference.CHANGE, begin, pos1 - 1,
previousDiff.getFirstStart(), previousDiff.getFirstEnd(),
changeText.toString(), previousDiff.getFirstText());
diffs.remove(diffs.size() - 1);
}
}
if (diff == null) {
diff = new Difference(Difference.DELETE, begin, pos1 - 1, pos2 - 1, 0, changeText.toString(), null);
}
diffs.add(diff);
} else {
line = br.readLine();
pos1++;
pos2++;
}
}
return line;
}
private static Difference[] parseNormalDiff(Reader in) throws IOException {
Pattern normRegexp;
try {
normRegexp = Pattern.compile(CmdlineDiffProvider.DIFF_REGEXP);
} catch (PatternSyntaxException rsex) {
normRegexp = null;
}
StringBuffer firstText = new StringBuffer();
StringBuffer secondText = new StringBuffer();
BufferedReader br = new BufferedReader(in);
ArrayList diffs = new ArrayList();
String line;
while ((line = br.readLine()) != null) {
CmdlineDiffProvider.outputLine(line, normRegexp, diffs, firstText, secondText);
}
CmdlineDiffProvider.setTextOnLastDifference(diffs, firstText, secondText);
return (Difference[]) diffs.toArray(new Difference[diffs.size()]);
}
/**
* A reader, that will not read more, than a single patch content
* from the supplied reader with possibly more patches.
*/
private static class SinglePatchReader extends Reader {
private static final int BUFF_SIZE = 512;
private PushbackReader in;
private char[] buffer = new char[BUFF_SIZE];
private int buffLength = 0;
private int buffPos = 0;
private boolean isAtEndOfPatch = false;
public SinglePatchReader(Reader in) {
this.in = new PushbackReader(in, BUFF_SIZE);
}
public int read(char[] values, int offset, int length) throws java.io.IOException {
//System.out.println("SinglePatchReader.read("+offset+", "+length+")");
int totRead = 0;
while (length > 0) {
int buffCopyLength;
if (length < buffLength) {
buffCopyLength = length;
length = 0;
} else {
if (buffLength > 0) {
buffCopyLength = buffLength;
length -= buffLength;
} else {
if (isAtEndOfPatch) {
length = 0;
buffCopyLength = -1;
} else {
buffLength = readTillEndOfPatch(buffer);
buffPos = 0;
if (buffLength <= 0) {
buffCopyLength = -1;
} else {
buffCopyLength = Math.min(length, buffLength);
length -= buffCopyLength;
}
}
}
}
if (buffCopyLength > 0) {
System.arraycopy(buffer, buffPos, values, offset, buffCopyLength);
offset += buffCopyLength;
buffLength -= buffCopyLength;
buffPos += buffCopyLength;
totRead += buffCopyLength;
} else {
length = 0;
}
}
if (totRead == 0) totRead = -1;
//System.out.println(" read = '"+((totRead >= 0) ? new String(values, 0, totRead) : "NOTHING")+"', totRead = "+totRead);
return totRead;
}
private int readTillEndOfPatch(char[] buffer) throws IOException {
int length = in.read(buffer);
String input = new String(buffer);
int end = 0;
if (input.startsWith(FILE_INDEX) || ((end = input.indexOf("\n"+FILE_INDEX))) >= 0) {
isAtEndOfPatch = true;
} else {
end = input.lastIndexOf('\n');
if (end >= 0) end++;
}
if (end >= 0 && end < length) {
in.unread(buffer, end, length - end);
length = end;
}
if (end == 0) length = -1;
return length;
}
public void close() throws java.io.IOException {
// Do nothing!
}
private static final String FILE_INDEX = "Index: "; // NOI18N
private boolean hasNextPatch(int[] diffType, String[] fileName) throws IOException {
isAtEndOfPatch = false; // We're prepared for the next patch
PushbackReader patchSource = in;
char[] buff = new char[DIFFERENCE_DELIMETER.length()];
int length;
Pattern normRegexp;
boolean contextBeginDetected = false;
try {
normRegexp = Pattern.compile(CmdlineDiffProvider.DIFF_REGEXP);
} catch (PatternSyntaxException rsex) {
normRegexp = null;
}
while ((length = patchSource.read(buff)) > 0) {
String input = new String(buff, 0, length);
int nl;
int nln = input.indexOf('\n');
int nlr = input.indexOf('\r');
if (nln < 0) nl = nlr;
else nl = nln;
if (nl >= 0) {
if (nln > 0 && nln == nlr + 1) {
input = input.substring(0, nl - 1);
} else {
input = input.substring(0, nl);
}
if (nl + 1 < length) {
patchSource.unread(buff, nl + 1, length - (nl + 1));
length = nl + 1;
}
}
if (input.equals(DIFFERENCE_DELIMETER)) {
diffType[0] = CONTEXT_DIFF;
patchSource.unread(buff, 0, length);
return true;
} else if (input.startsWith(UNIFIED_MARK + " ")) {
diffType[0] = UNIFIED_DIFF;
patchSource.unread(buff, 0, length);
return true;
} else if (input.startsWith(FILE_INDEX)) {
StringBuffer name = new StringBuffer(input.substring(FILE_INDEX.length()));
if (nl < 0) {
int r;
char c;
while ((c = (char) (r = patchSource.read())) != '\n' && r != -1) {
name.append(c);
}
}
fileName[0] = name.toString();
} else if (input.startsWith(CONTEXT_MARK1B) || !contextBeginDetected && input.startsWith(UNIFIED_MARK1)) {
StringBuffer name;
if (input.startsWith(CONTEXT_MARK1B)) {
contextBeginDetected = true;
name = new StringBuffer(input.substring(CONTEXT_MARK1B.length()));
} else {
name = new StringBuffer(input.substring(UNIFIED_MARK1.length()));
}
String sname = name.toString();
int spaceIndex = sname.indexOf('\t');
if (spaceIndex > 0) {
name = name.delete(spaceIndex, name.length());
}
if (nl < 0) {
int r = 0;
char c = 0;
if (spaceIndex < 0) {
while ((c = (char) (r = patchSource.read())) != '\n' && c != '\r' && c != '\t' && r != -1) {
name.append(c);
}
}
if (c != '\n' && c != '\r' && r != -1) {
while ((c = (char) (r = patchSource.read())) != '\n' && c != '\r' && r != -1) ; // Read the rest of the line
}
if (c == '\r') {
r = patchSource.read();
if (r != -1) {
c = (char) r;
if (c != '\n') patchSource.unread(c);
}
}
}
fileName[0] = name.toString();
} else if (normRegexp != null && normRegexp.matcher(input).matches()) {
diffType[0] = NORMAL_DIFF;
patchSource.unread(buff, 0, length);
return true;
} else { // Read the rest of the garbaged line
if (nl < 0) {
int r;
char c;
while ((c = (char) (r = patchSource.read())) != '\n' && c != '\r' && r != -1) ;
if (c == '\r') {
r = patchSource.read();
if (r != -1) {
c = (char) r;
if (c != '\n') patchSource.unread(c);
}
}
}
}
}
return false;
}
}
public static class FileDifferences extends Object {
private String fileName;
private Difference[] diffs;
public FileDifferences(String fileName, Difference[] diffs) {
this.fileName = fileName;
this.diffs = diffs;
}
public final String getFileName() {
return fileName;
}
public final Difference[] getDifferences() {
return diffs;
}
}
}
|
| ... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.