throws MissingObjectException, IncorrectObjectTypeException,
IOException;
+ /**
+ * Get only the size of an object.
+ * <p>
+ * The default implementation of this method opens an ObjectLoader.
+ * Databases are encouraged to override this if a faster access method is
+ * available to them.
+ *
+ * @param objectId
+ * identity of the object to open.
+ * @param typeHint
+ * hint about the type of object being requested;
+ * {@link #OBJ_ANY} if the object type is not known, or does not
+ * matter to the caller.
+ * @return size of object in bytes.
+ * @throws MissingObjectException
+ * the object does not exist.
+ * @throws IncorrectObjectTypeException
+ * typeHint was not OBJ_ANY, and the object's actual type does
+ * not match typeHint.
+ * @throws IOException
+ * the object store cannot be accessed.
+ */
+ public long getObjectSize(AnyObjectId objectId, int typeHint)
+ throws MissingObjectException, IncorrectObjectTypeException,
+ IOException {
+ return open(objectId, typeHint).getSize();
+ }
+
/**
* Release any resources used by this reader.
* <p>
throw new UnsupportedOperationException();
}
+ @Override
+ long getObjectSize1(WindowCursor curs, AnyObjectId objectId) throws IOException {
+ if (unpackedObjects.contains(objectId))
+ return wrapped.getObjectSize2(curs, objectId.name(), objectId);
+ return wrapped.getObjectSize1(curs, objectId);
+ }
+
+ @Override
+ long getObjectSize2(WindowCursor curs, String objectName, AnyObjectId objectId)
+ throws IOException {
+ // This method should never be invoked.
+ throw new UnsupportedOperationException();
+ }
+
@Override
void selectObjectRepresentation(PackWriter packer, ObjectToPack otp,
WindowCursor curs) throws IOException {
return null;
}
+ long getObjectSize(WindowCursor curs, AnyObjectId objectId)
+ throws IOException {
+ long sz = getObjectSizeImpl1(curs, objectId);
+ if (0 <= sz)
+ return sz;
+ return getObjectSizeImpl2(curs, objectId.name(), objectId);
+ }
+
+ final long getObjectSizeImpl1(final WindowCursor curs,
+ final AnyObjectId objectId) throws IOException {
+ long sz;
+
+ sz = getObjectSize1(curs, objectId);
+ if (0 <= sz)
+ return sz;
+
+ for (final AlternateHandle alt : myAlternates()) {
+ sz = alt.db.getObjectSizeImpl1(curs, objectId);
+ if (0 <= sz)
+ return sz;
+ }
+
+ if (tryAgain1()) {
+ sz = getObjectSize1(curs, objectId);
+ if (0 <= sz)
+ return sz;
+ }
+
+ return -1;
+ }
+
+ final long getObjectSizeImpl2(final WindowCursor curs,
+ final String objectName, final AnyObjectId objectId)
+ throws IOException {
+ long sz;
+
+ sz = getObjectSize2(curs, objectName, objectId);
+ if (0 <= sz)
+ return sz;
+
+ for (final AlternateHandle alt : myAlternates()) {
+ sz = alt.db.getObjectSizeImpl2(curs, objectName, objectId);
+ if (0 <= sz)
+ return sz;
+ }
+
+ return -1;
+ }
+
abstract void selectObjectRepresentation(PackWriter packer,
ObjectToPack otp, WindowCursor curs) throws IOException;
abstract ObjectLoader openObject2(WindowCursor curs, String objectName,
AnyObjectId objectId) throws IOException;
+ abstract long getObjectSize1(WindowCursor curs, AnyObjectId objectId)
+ throws IOException;
+
+ abstract long getObjectSize2(WindowCursor curs, String objectName,
+ AnyObjectId objectId) throws IOException;
+
abstract FileObjectDatabase newCachedFileObjectDatabase();
abstract int getStreamFileThreshold();
}
}
+ long getObjectSize1(final WindowCursor curs, final AnyObjectId objectId)
+ throws IOException {
+ PackList pList = packList.get();
+ SEARCH: for (;;) {
+ for (final PackFile p : pList.packs) {
+ try {
+ long sz = p.getObjectSize(curs, objectId);
+ if (0 <= sz)
+ return sz;
+ } catch (PackMismatchException e) {
+ // Pack was modified; refresh the entire pack list.
+ //
+ pList = scanPacks(pList);
+ continue SEARCH;
+ } catch (IOException e) {
+ // Assume the pack is corrupted.
+ //
+ removePack(p);
+ }
+ }
+ return -1;
+ }
+ }
+
+ @Override
+ long getObjectSize2(WindowCursor curs, String objectName,
+ AnyObjectId objectId) throws IOException {
+ try {
+ File path = fileFor(objectName);
+ FileInputStream in = new FileInputStream(path);
+ try {
+ return UnpackedObject.getSize(in, objectId, curs);
+ } finally {
+ in.close();
+ }
+ } catch (FileNotFoundException noFile) {
+ return -1;
+ }
+ }
+
@Override
void selectObjectRepresentation(PackWriter packer, ObjectToPack otp,
WindowCursor curs) throws IOException {
}
}
+ long getObjectSize(final WindowCursor curs, final AnyObjectId id)
+ throws IOException {
+ final long offset = idx().findOffset(id);
+ return 0 < offset ? getObjectSize(curs, offset) : -1;
+ }
+
+ long getObjectSize(final WindowCursor curs, final long pos)
+ throws IOException {
+ final byte[] ib = curs.tempId;
+ readFully(pos, ib, 0, 20, curs);
+ int c = ib[0] & 0xff;
+ final int type = (c >> 4) & 7;
+ long sz = c & 15;
+ int shift = 4;
+ int p = 1;
+ while ((c & 0x80) != 0) {
+ c = ib[p++] & 0xff;
+ sz += (c & 0x7f) << shift;
+ shift += 7;
+ }
+
+ long deltaAt;
+ switch (type) {
+ case Constants.OBJ_COMMIT:
+ case Constants.OBJ_TREE:
+ case Constants.OBJ_BLOB:
+ case Constants.OBJ_TAG:
+ return sz;
+
+ case Constants.OBJ_OFS_DELTA:
+ c = ib[p++] & 0xff;
+ while ((c & 128) != 0)
+ c = ib[p++] & 0xff;
+ deltaAt = pos + p;
+ break;
+
+ case Constants.OBJ_REF_DELTA:
+ deltaAt = pos + p + 20;
+ break;
+
+ default:
+ throw new IOException(MessageFormat.format(
+ JGitText.get().unknownObjectType, type));
+ }
+
+ try {
+ return BinaryDelta.getResultSize(getDeltaHeader(curs, deltaAt));
+ } catch (DataFormatException e) {
+ throw new CorruptObjectException(MessageFormat.format(JGitText
+ .get().objectAtHasBadZlibStream, pos, getPackFile()));
+ }
+ }
+
LocalObjectRepresentation representation(final WindowCursor curs,
final AnyObjectId objectId) throws IOException {
final long pos = idx().findOffset(objectId);
if (isStandardFormat(hdr)) {
in.reset();
- Inflater inf = wc.inflater();
+ Inflater inf = wc.inflater();
InputStream zIn = inflate(in, inf);
int avail = readSome(zIn, hdr, 0, 64);
if (avail < 5)
}
}
+ static long getSize(InputStream in, AnyObjectId id, WindowCursor wc)
+ throws IOException {
+ try {
+ in = buffer(in);
+ in.mark(20);
+ final byte[] hdr = new byte[64];
+ IO.readFully(in, hdr, 0, 2);
+
+ if (isStandardFormat(hdr)) {
+ in.reset();
+ Inflater inf = wc.inflater();
+ InputStream zIn = inflate(in, inf);
+ int avail = readSome(zIn, hdr, 0, 64);
+ if (avail < 5)
+ throw new CorruptObjectException(id,
+ JGitText.get().corruptObjectNoHeader);
+
+ final MutableInteger p = new MutableInteger();
+ Constants.decodeTypeString(id, hdr, (byte) ' ', p);
+ long size = RawParseUtils.parseLongBase10(hdr, p.value, p);
+ if (size < 0)
+ throw new CorruptObjectException(id,
+ JGitText.get().corruptObjectNegativeSize);
+ return size;
+
+ } else {
+ readSome(in, hdr, 2, 18);
+ int c = hdr[0] & 0xff;
+ long size = c & 15;
+ int shift = 4;
+ int p = 1;
+ while ((c & 0x80) != 0) {
+ c = hdr[p++] & 0xff;
+ size += (c & 0x7f) << shift;
+ shift += 7;
+ }
+ return size;
+ }
+ } catch (ZipException badStream) {
+ throw new CorruptObjectException(id,
+ JGitText.get().corruptObjectBadStream);
+ }
+ }
+
private static void checkValidEndOfStream(InputStream in, Inflater inf,
AnyObjectId id, final byte[] buf) throws IOException,
CorruptObjectException {
return ldr;
}
+ public long getObjectSize(AnyObjectId objectId, int typeHint)
+ throws MissingObjectException, IncorrectObjectTypeException,
+ IOException {
+ long sz = db.getObjectSize(this, objectId);
+ if (sz < 0) {
+ if (typeHint == OBJ_ANY)
+ throw new MissingObjectException(objectId.copy(), "unknown");
+ throw new MissingObjectException(objectId.copy(), typeHint);
+ }
+ return sz;
+ }
+
public LocalObjectToPack newObjectToPack(RevObject obj) {
return new LocalObjectToPack(obj);
}