@ -309,7 +309,7 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> {
// Rip apart the header so we can discover the size.
// Rip apart the header so we can discover the size.
//
//
readFully ( src . c opyO ffset, buf , 0 , 20 , curs ) ;
readFully ( src . offset , buf , 0 , 20 , curs ) ;
int c = buf [ 0 ] & 0xff ;
int c = buf [ 0 ] & 0xff ;
final int typeCode = ( c > > 4 ) & 7 ;
final int typeCode = ( c > > 4 ) & 7 ;
long inflatedLength = c & 15 ;
long inflatedLength = c & 15 ;
@ -331,7 +331,7 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> {
crc1 . update ( buf , 0 , headerCnt ) ;
crc1 . update ( buf , 0 , headerCnt ) ;
crc2 . update ( buf , 0 , headerCnt ) ;
crc2 . update ( buf , 0 , headerCnt ) ;
readFully ( src . c opyO ffset + headerCnt , buf , 0 , 20 , curs ) ;
readFully ( src . offset + headerCnt , buf , 0 , 20 , curs ) ;
crc1 . update ( buf , 0 , 20 ) ;
crc1 . update ( buf , 0 , 20 ) ;
crc2 . update ( buf , 0 , headerCnt ) ;
crc2 . update ( buf , 0 , headerCnt ) ;
headerCnt + = 20 ;
headerCnt + = 20 ;
@ -340,8 +340,8 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> {
crc2 . update ( buf , 0 , headerCnt ) ;
crc2 . update ( buf , 0 , headerCnt ) ;
}
}
final long dataOffset = src . c opyO ffset + headerCnt ;
final long dataOffset = src . offset + headerCnt ;
final long dataLength ;
final long dataLength = src . length ;
final long expectedCRC ;
final long expectedCRC ;
final ByteArrayWindow quickCopy ;
final ByteArrayWindow quickCopy ;
@ -349,7 +349,6 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> {
// we report it missing instead.
// we report it missing instead.
//
//
try {
try {
dataLength = findEndOffset ( src . copyOffset ) - dataOffset ;
quickCopy = curs . quickCopy ( this , dataOffset , dataLength ) ;
quickCopy = curs . quickCopy ( this , dataOffset , dataLength ) ;
if ( idx ( ) . hasCRC32Support ( ) ) {
if ( idx ( ) . hasCRC32Support ( ) ) {
@ -370,10 +369,10 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> {
}
}
}
}
if ( crc1 . getValue ( ) ! = expectedCRC ) {
if ( crc1 . getValue ( ) ! = expectedCRC ) {
setCorrupt ( src . c opyO ffset) ;
setCorrupt ( src . offset ) ;
throw new CorruptObjectException ( MessageFormat . format (
throw new CorruptObjectException ( MessageFormat . format (
JGitText . get ( ) . objectAtHasBadZlibStream ,
JGitText . get ( ) . objectAtHasBadZlibStream ,
src . c opyO ffset, getPackFile ( ) ) ) ;
src . offset , getPackFile ( ) ) ) ;
}
}
} else {
} else {
// We don't have a CRC32 code in the index, so compute it
// We don't have a CRC32 code in the index, so compute it
@ -399,20 +398,20 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> {
}
}
}
}
if ( ! inf . finished ( ) | | inf . getBytesRead ( ) ! = dataLength ) {
if ( ! inf . finished ( ) | | inf . getBytesRead ( ) ! = dataLength ) {
setCorrupt ( src . c opyO ffset) ;
setCorrupt ( src . offset ) ;
throw new EOFException ( MessageFormat . format (
throw new EOFException ( MessageFormat . format (
JGitText . get ( ) . shortCompressedStreamAt ,
JGitText . get ( ) . shortCompressedStreamAt ,
src . c opyO ffset) ) ;
src . offset ) ) ;
}
}
expectedCRC = crc1 . getValue ( ) ;
expectedCRC = crc1 . getValue ( ) ;
}
}
} catch ( DataFormatException dataFormat ) {
} catch ( DataFormatException dataFormat ) {
setCorrupt ( src . c opyO ffset) ;
setCorrupt ( src . offset ) ;
CorruptObjectException corruptObject = new CorruptObjectException (
CorruptObjectException corruptObject = new CorruptObjectException (
MessageFormat . format (
MessageFormat . format (
JGitText . get ( ) . objectAtHasBadZlibStream ,
JGitText . get ( ) . objectAtHasBadZlibStream ,
src . c opyO ffset, getPackFile ( ) ) ) ;
src . offset , getPackFile ( ) ) ) ;
corruptObject . initCause ( dataFormat ) ;
corruptObject . initCause ( dataFormat ) ;
StoredObjectRepresentationNotAvailableException gone ;
StoredObjectRepresentationNotAvailableException gone ;
@ -458,7 +457,7 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> {
}
}
if ( crc2 . getValue ( ) ! = expectedCRC ) {
if ( crc2 . getValue ( ) ! = expectedCRC ) {
throw new CorruptObjectException ( MessageFormat . format ( JGitText
throw new CorruptObjectException ( MessageFormat . format ( JGitText
. get ( ) . objectAtHasBadZlibStream , src . c opyO ffset,
. get ( ) . objectAtHasBadZlibStream , src . offset ,
getPackFile ( ) ) ) ;
getPackFile ( ) ) ) ;
}
}
}
}
@ -661,6 +660,55 @@ public class PackFile implements Iterable<PackIndex.MutableEntry> {
}
}
}
}
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 )
private long findEndOffset ( final long startOffset )
throws IOException , CorruptObjectException {
throws IOException , CorruptObjectException {
final long maxOffset = length - 20 ;
final long maxOffset = length - 20 ;