package org.tmatesoft.svn.core.internal.wc2.patch;
import org.tmatesoft.svn.core.SVNErrorCode;
import org.tmatesoft.svn.core.SVNErrorMessage;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.internal.wc.SVNErrorManager;
import org.tmatesoft.svn.core.internal.wc.patch.SVNPatchFileStream;
import org.tmatesoft.svn.util.SVNLogType;
import java.io.IOException;
public class SvnDiffHunk implements Comparable<SvnDiffHunk> {
private SvnPatch patch;
private SVNPatchFileStream patchFileStream;
private Range diffTextRange;
private Range originalTextRange;
private Range modifiedTextRange;
private int originalStart;
private int originalLength;
private int modifiedStart;
private int modifiedLength;
private int leadingContext;
private int trailingContext;
public void resetDiffText() {
this.diffTextRange.current = diffTextRange.start;
}
public void resetOriginalText() {
if (patch.isReverse()) {
modifiedTextRange.current = modifiedTextRange.start;
} else {
originalTextRange.current = originalTextRange.start;
}
}
public void resetModifiedText() {
if (patch.isReverse()) {
originalTextRange.current = originalTextRange.start;
} else {
modifiedTextRange.current = modifiedTextRange.start;
}
}
public int getDirectedOriginalStart() {
return patch.isReverse() ? modifiedStart : originalStart;
}
public int getDirectedOriginalLength() {
return patch.isReverse() ? modifiedLength : originalLength;
}
public int getDirectedModifiedStart() {
return patch.isReverse() ? originalStart : modifiedStart;
}
public int getDirectedModifiedLength() {
return patch.isReverse() ? originalLength : modifiedLength;
}
public int getLeadingContext() {
return leadingContext;
}
public int getTrailingContext() {
return trailingContext;
}
public void setOriginalStart(int originalStart) {
this.originalStart = originalStart;
}
public void setOriginalLength(int originalLength) {
this.originalLength = originalLength;
}
public void setModifiedStart(int modifiedStart) {
this.modifiedStart = modifiedStart;
}
public void setModifiedLength(int modifiedLength) {
this.modifiedLength = modifiedLength;
}
public void setDiffTextRange(Range diffTextRange) {
this.diffTextRange = diffTextRange;
}
public void setOriginalTextRange(Range originalTextRange) {
this.originalTextRange = originalTextRange;
}
public void setModifiedTextRange(Range modifiedTextRange) {
this.modifiedTextRange = modifiedTextRange;
}
private int getOriginalStart() {
return originalStart;
}
public int getOriginalLength() {
return originalLength;
}
private int getModifiedStart() {
return modifiedStart;
}
public int getModifiedLength() {
return modifiedLength;
}
public void setLeadingContext(int leadingContext) {
this.leadingContext = leadingContext;
}
public void setTrailingContext(int trailingContext) {
this.trailingContext = trailingContext;
}
public void setPatch(SvnPatch patch) {
this.patch = patch;
}
public String readLineDiffText(String[] eolStr, boolean[] eof) throws IOException, SVNException {
if (diffTextRange.current >= diffTextRange.end) {
eof[0] = true;
if (eolStr != null) {
eolStr[0] = null;
}
return "";
}
long pos = patchFileStream.getSeekPosition();
patchFileStream.setSeekPosition(diffTextRange.current);
long maxLen = diffTextRange.end - diffTextRange.current;
String line = readLine(patchFileStream, eolStr, eof);
diffTextRange.current = 0;
diffTextRange.current = patchFileStream.getSeekPosition();
patchFileStream.setSeekPosition(pos);
if (patch.isReverse()) {
if (line.startsWith("+")) {
line = "-" + line.substring("+".length());
} else if (line.startsWith("-")) {
line = "+" + line.substring("-".length());
}
}
return line;
}
public String readLineOriginalText(String[] eolStr, boolean[] eof) throws SVNException {
return readLineOriginalOrModified(patch.isReverse() ? modifiedTextRange : originalTextRange,
eolStr, eof, patch.isReverse() ? '-' : '+');
}
public String readLineModifiedText(String[] eolStr, boolean[] eof) throws SVNException {
return readLineOriginalOrModified(patch.isReverse() ? originalTextRange : modifiedTextRange,
eolStr, eof, patch.isReverse() ? '+' : '-');
}
private String readLineOriginalOrModified(Range range, String[] eolStr, boolean[] eof, char forbidden) throws SVNException {
try {
if (range.current >= range.end) {
eof[0] = true;
if (eolStr != null) {
eolStr[0] = null;
}
return "";
}
long pos = patchFileStream.getSeekPosition();
patchFileStream.setSeekPosition(range.current);
boolean filtered;
long maxLen;
String str;
do {
maxLen = range.end - range.current;
String oldEol = null;
if (maxLen < 0 && eolStr != null) {
oldEol = eolStr[0];
}
str = readLine(patchFileStream, eolStr, eof);
//here we apply "maxLen" restriction; suppose str="abcd\n", maxLen=3: we should cut str to "abc" and forget about finding EOL
if (maxLen >= 0 && str.length() >= maxLen) {
str = str.substring(0, (int) maxLen);
if (eolStr != null && eolStr[0] != null && !str.endsWith("\r") && !str.endsWith("\n")) {
eolStr[0] = null;
}
if (eof != null) {
eof[0] = maxLen == 0;
}
} else if (maxLen < 0 && eolStr != null) {
eolStr[0] = oldEol;
}
range.current = patchFileStream.getSeekPosition();
filtered = (str.length() > 0) && (str.charAt(0) == forbidden || str.charAt(0) == '\\');
} while (filtered && !eof[0]);
String result;
if (filtered) {
result = "";
} else if (str.startsWith("+") || str.startsWith("-") || str.startsWith(" ")) {
result = str.substring(1);
} else {
result = str;
}
patchFileStream.setSeekPosition(pos);
return result;
} catch (IOException e) {
SVNErrorMessage errorMessage = SVNErrorMessage.create(SVNErrorCode.IO_ERROR);
SVNErrorManager.error(errorMessage, SVNLogType.WC);
}
return null;
}
private String readLine(SVNPatchFileStream patchFileStream, String[] eolStr, boolean[] eof) throws IOException, SVNException {
StringBuffer lineBuffer = new StringBuffer();
StringBuffer eolStrBuffer = new StringBuffer();
if (eof != null) {
eof[0] = patchFileStream.readLineWithEol(lineBuffer, eolStrBuffer);
}
if (eolStr != null) {
eolStr[0] = eolStrBuffer.length() == 0 ? null : eolStrBuffer.toString();
}
return lineBuffer.toString();
//
//
// String str = patchFileStream.readLine();
// eof[0] = str == null;
// if (str != null) {
// int suffixSize = 0;
// if (str.endsWith("\r\n")) {
// suffixSize = 2;
// } else if (str.endsWith("\n") || str.endsWith("\r")) {
// suffixSize = 1;
// }
// if (suffixSize > 0) {
// eolStr[0] = str.substring(str.length() - suffixSize);
// str = str.substring(0, str.length() - suffixSize);
// }
// }
// return str;
}
public int compareTo(SvnDiffHunk diffHunk) {
if (getOriginalStart() < diffHunk.getOriginalStart()) {
return -1;
}
if (getOriginalStart() > diffHunk.getOriginalStart()) {
return 1;
}
return 0;
}
public void setPatchFileStream(SVNPatchFileStream patchFileStream) {
this.patchFileStream = patchFileStream;
}
public void decreaseOriginalLength() {
originalLength--;
}
public void decreaseModifiedLength() {
modifiedLength--;
}
static class Range {
private long start;
private long end;
private long current;
public Range(long start, long end, long current) {
this.start = start;
this.end = end;
this.current = current;
}
}
}