package org.eclipse.jgit.patch;
import static org.eclipse.jgit.util.RawParseUtils.nextLF;
import static org.eclipse.jgit.util.RawParseUtils.parseBase10;
import java.io.IOException;
import java.io.OutputStream;
import java.text.MessageFormat;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.AbbreviatedObjectId;
import org.eclipse.jgit.util.MutableInteger;
public class extends HunkHeader {
private abstract static class extends OldImage {
int ;
}
private CombinedOldImage[] ;
(CombinedFileHeader fh, int offset) {
super(fh, offset, null);
old = new CombinedOldImage[fh.getParentCount()];
for (int i = 0; i < old.length; i++) {
final int imagePos = i;
old[i] = new CombinedOldImage() {
@Override
public AbbreviatedObjectId () {
return fh.getOldId(imagePos);
}
};
}
}
@Override
public CombinedFileHeader () {
return (CombinedFileHeader) super.getFileHeader();
}
@Override
public OldImage () {
return getOldImage(0);
}
public OldImage (int nthParent) {
return old[nthParent];
}
@Override
void () {
final byte[] buf = file.buf;
final MutableInteger ptr = new MutableInteger();
ptr.value = nextLF(buf, startOffset, ' ');
for (CombinedOldImage o : old) {
o.startLine = -parseBase10(buf, ptr.value, ptr);
if (buf[ptr.value] == ',') {
o.lineCount = parseBase10(buf, ptr.value + 1, ptr);
} else {
o.lineCount = 1;
}
}
newStartLine = parseBase10(buf, ptr.value + 1, ptr);
if (buf[ptr.value] == ',')
newLineCount = parseBase10(buf, ptr.value + 1, ptr);
else
newLineCount = 1;
}
@Override
int parseBody(Patch script, int end) {
final byte[] buf = file.buf;
int c = nextLF(buf, startOffset);
for (CombinedOldImage o : old) {
o.nDeleted = 0;
o.nAdded = 0;
o.nContext = 0;
}
nContext = 0;
int nAdded = 0;
SCAN: for (int eol; c < end; c = eol) {
eol = nextLF(buf, c);
if (eol - c < old.length + 1) {
break SCAN;
}
switch (buf[c]) {
case ' ':
case '-':
case '+':
break;
default:
break SCAN;
}
int localcontext = 0;
for (int ancestor = 0; ancestor < old.length; ancestor++) {
switch (buf[c + ancestor]) {
case ' ':
localcontext++;
old[ancestor].nContext++;
continue;
case '-':
old[ancestor].nDeleted++;
continue;
case '+':
old[ancestor].nAdded++;
nAdded++;
continue;
default:
break SCAN;
}
}
if (localcontext == old.length)
nContext++;
}
for (int ancestor = 0; ancestor < old.length; ancestor++) {
final CombinedOldImage o = old[ancestor];
final int cmp = o.nContext + o.nDeleted;
if (cmp < o.lineCount) {
final int missingCnt = o.lineCount - cmp;
script.error(buf, startOffset, MessageFormat.format(
JGitText.get().truncatedHunkLinesMissingForAncestor,
Integer.valueOf(missingCnt),
Integer.valueOf(ancestor + 1)));
}
}
if (nContext + nAdded < newLineCount) {
final int missingCount = newLineCount - (nContext + nAdded);
script.error(buf, startOffset, MessageFormat.format(
JGitText.get().truncatedHunkNewLinesMissing,
Integer.valueOf(missingCount)));
}
return c;
}
@Override
void (OutputStream[] out) throws IOException {
final byte[] buf = file.buf;
int ptr = startOffset;
int eol = nextLF(buf, ptr);
if (endOffset <= eol)
return;
out[0].write(buf, ptr, eol - ptr);
SCAN: for (ptr = eol; ptr < endOffset; ptr = eol) {
eol = nextLF(buf, ptr);
if (eol - ptr < old.length + 1) {
break SCAN;
}
switch (buf[ptr]) {
case ' ':
case '-':
case '+':
break;
default:
break SCAN;
}
int delcnt = 0;
for (int ancestor = 0; ancestor < old.length; ancestor++) {
switch (buf[ptr + ancestor]) {
case '-':
delcnt++;
out[ancestor].write(buf, ptr, eol - ptr);
continue;
case ' ':
out[ancestor].write(buf, ptr, eol - ptr);
continue;
case '+':
continue;
default:
break SCAN;
}
}
if (delcnt < old.length) {
out[old.length].write(buf, ptr, eol - ptr);
}
}
}
@Override
void (final StringBuilder sb, final String[] text,
final int[] offsets) {
final byte[] buf = file.buf;
int ptr = startOffset;
int eol = nextLF(buf, ptr);
if (endOffset <= eol)
return;
copyLine(sb, text, offsets, 0);
SCAN: for (ptr = eol; ptr < endOffset; ptr = eol) {
eol = nextLF(buf, ptr);
if (eol - ptr < old.length + 1) {
break SCAN;
}
switch (buf[ptr]) {
case ' ':
case '-':
case '+':
break;
default:
break SCAN;
}
boolean copied = false;
for (int ancestor = 0; ancestor < old.length; ancestor++) {
switch (buf[ptr + ancestor]) {
case ' ':
case '-':
if (copied)
skipLine(text, offsets, ancestor);
else {
copyLine(sb, text, offsets, ancestor);
copied = true;
}
continue;
case '+':
continue;
default:
break SCAN;
}
}
if (!copied) {
copyLine(sb, text, offsets, old.length);
}
}
}
}