import org.eclipse.jgit.lib.StoredObjectRepresentation;
class LocalObjectRepresentation extends StoredObjectRepresentation {
- final PackedObjectLoader ldr;
+ static LocalObjectRepresentation newWhole(PackFile f, long p, long length) {
+ LocalObjectRepresentation r = new LocalObjectRepresentation() {
+ @Override
+ public int getFormat() {
+ return PACK_WHOLE;
+ }
+ };
+ r.pack = f;
+ r.offset = p;
+ r.length = length;
+ return r;
+ }
- LocalObjectRepresentation(PackedObjectLoader ldr) {
- this.ldr = ldr;
+ static LocalObjectRepresentation newDelta(PackFile f, long p, long n,
+ ObjectId base) {
+ LocalObjectRepresentation r = new Delta();
+ r.pack = f;
+ r.offset = p;
+ r.length = n;
+ r.baseId = base;
+ return r;
}
- @Override
- public int getFormat() {
- if (ldr instanceof DeltaPackedObjectLoader)
- return PACK_DELTA;
- if (ldr instanceof WholePackedObjectLoader)
- return PACK_WHOLE;
- return FORMAT_OTHER;
+ static LocalObjectRepresentation newDelta(PackFile f, long p, long n,
+ long base) {
+ LocalObjectRepresentation r = new Delta();
+ r.pack = f;
+ r.offset = p;
+ r.length = n;
+ r.baseOffset = base;
+ return r;
}
+ PackFile pack;
+
+ long offset;
+
+ long length;
+
+ private long baseOffset;
+
+ private ObjectId baseId;
+
@Override
public int getWeight() {
- long sz = ldr.getRawSize();
- if (Integer.MAX_VALUE < sz)
- return WEIGHT_UNKNOWN;
- return (int) sz;
+ return (int) Math.min(length, Integer.MAX_VALUE);
}
@Override
public ObjectId getDeltaBase() {
- try {
- return ldr.getDeltaBase();
- } catch (IOException e) {
- return null;
+ if (baseId == null && getFormat() == PACK_DELTA) {
+ try {
+ baseId = pack.findObjectForOffset(baseOffset);
+ } catch (IOException error) {
+ return null;
+ }
+ }
+ return baseId;
+ }
+
+ private static final class Delta extends LocalObjectRepresentation {
+ @Override
+ public int getFormat() {
+ return PACK_DELTA;
}
}
}
// Rip apart the header so we can discover the size.
//
- readFully(src.copyOffset, buf, 0, 20, curs);
+ readFully(src.offset, buf, 0, 20, curs);
int c = buf[0] & 0xff;
final int typeCode = (c >> 4) & 7;
long inflatedLength = c & 15;
crc1.update(buf, 0, headerCnt);
crc2.update(buf, 0, headerCnt);
- readFully(src.copyOffset + headerCnt, buf, 0, 20, curs);
+ readFully(src.offset + headerCnt, buf, 0, 20, curs);
crc1.update(buf, 0, 20);
crc2.update(buf, 0, headerCnt);
headerCnt += 20;
crc2.update(buf, 0, headerCnt);
}
- final long dataOffset = src.copyOffset + headerCnt;
- final long dataLength;
+ final long dataOffset = src.offset + headerCnt;
+ final long dataLength = src.length;
final long expectedCRC;
final ByteArrayWindow quickCopy;
// we report it missing instead.
//
try {
- dataLength = findEndOffset(src.copyOffset) - dataOffset;
quickCopy = curs.quickCopy(this, dataOffset, dataLength);
if (idx().hasCRC32Support()) {
}
}
if (crc1.getValue() != expectedCRC) {
- setCorrupt(src.copyOffset);
+ setCorrupt(src.offset);
throw new CorruptObjectException(MessageFormat.format(
JGitText.get().objectAtHasBadZlibStream,
- src.copyOffset, getPackFile()));
+ src.offset, getPackFile()));
}
} else {
// We don't have a CRC32 code in the index, so compute it
}
}
if (!inf.finished() || inf.getBytesRead() != dataLength) {
- setCorrupt(src.copyOffset);
+ setCorrupt(src.offset);
throw new EOFException(MessageFormat.format(
JGitText.get().shortCompressedStreamAt,
- src.copyOffset));
+ src.offset));
}
expectedCRC = crc1.getValue();
}
} catch (DataFormatException dataFormat) {
- setCorrupt(src.copyOffset);
+ setCorrupt(src.offset);
CorruptObjectException corruptObject = new CorruptObjectException(
MessageFormat.format(
JGitText.get().objectAtHasBadZlibStream,
- src.copyOffset, getPackFile()));
+ src.offset, getPackFile()));
corruptObject.initCause(dataFormat);
StoredObjectRepresentationNotAvailableException gone;
}
if (crc2.getValue() != expectedCRC) {
throw new CorruptObjectException(MessageFormat.format(JGitText
- .get().objectAtHasBadZlibStream, src.copyOffset,
+ .get().objectAtHasBadZlibStream, src.offset,
getPackFile()));
}
}
}
}
+ LocalObjectRepresentation representation(final WindowCursor curs,
+ final AnyObjectId objectId) throws IOException {
+ final long pos = idx().findOffset(objectId);
+ if (pos < 0)
+ return null;
+
+ final byte[] ib = curs.tempId;
+ readFully(pos, ib, 0, 20, curs);
+ int c = ib[0] & 0xff;
+ int p = 1;
+ final int typeCode = (c >> 4) & 7;
+ while ((c & 0x80) != 0)
+ c = ib[p++] & 0xff;
+
+ long len = (findEndOffset(pos) - pos);
+ switch (typeCode) {
+ case Constants.OBJ_COMMIT:
+ case Constants.OBJ_TREE:
+ case Constants.OBJ_BLOB:
+ case Constants.OBJ_TAG:
+ return LocalObjectRepresentation.newWhole(this, pos, len - p);
+
+ case Constants.OBJ_OFS_DELTA: {
+ c = ib[p++] & 0xff;
+ long ofs = c & 127;
+ while ((c & 128) != 0) {
+ ofs += 1;
+ c = ib[p++] & 0xff;
+ ofs <<= 7;
+ ofs += (c & 127);
+ }
+ ofs = pos - ofs;
+ return LocalObjectRepresentation.newDelta(this, pos, len - p, ofs);
+ }
+
+ case Constants.OBJ_REF_DELTA: {
+ len -= p;
+ len -= Constants.OBJECT_ID_LENGTH;
+ readFully(pos + p, ib, 0, 20, curs);
+ ObjectId id = ObjectId.fromRaw(ib);
+ return LocalObjectRepresentation.newDelta(this, pos, len, id);
+ }
+
+ default:
+ throw new IOException(MessageFormat.format(
+ JGitText.get().unknownObjectType, typeCode));
+ }
+ }
+
private long findEndOffset(final long startOffset)
throws IOException, CorruptObjectException {
final long maxOffset = length - 20;