public function getRawObjectAtOffset($offset)
{
$this->reader->setOffset($offset);
$header_part = $this->reader->readUInt8();
$type = $header_part >> 4 & 0x7;
$size = $header_part & 0xf;
for ($size_shift_offset = 4; $header_part & 0x80; $size_shift_offset += 7) {
$header_part = $this->reader->readUInt8();
$size |= ($header_part & 0x7f) << $size_shift_offset;
}
if ($type == self::OBJ_REF_DELTA) {
$sha = $this->reader->readHHex(20);
$delta = gzuncompress($this->reader->read($size + 512), $size);
$base_object = $this->getRawObjectForSha($sha);
$type = $base_object->getType();
if (strlen($delta) != $size) {
throw new InvalidPackfileException(sprintf("Unexpected delta length, expected %d, was %d", $size, strlen($delta)));
}
$data = $this->patchDelta($delta, $base_object);
$raw_object = new RawObject($type, $data);
} else {
if ($type == self::OBJ_OFS_DELTA) {
$base_offset_part = $this->reader->readUInt8();
$base_offset = $base_offset_part & 0x7f;
while ($base_offset_part & 0x80) {
$base_offset_part = $this->reader->readUInt8();
$base_offset += 1;
$base_offset = $base_offset << 7;
$base_offset |= $base_offset_part & 0x7f;
}
$base_offset = $offset - $base_offset;
$delta = gzuncompress($this->reader->read($size + 512), $size);
if (strlen($delta) != $size) {
throw new InvalidPackfileException(sprintf("Unexpected delta length, expected %d, was %d", $size, strlen($delta)));
}
$base_object = $this->getRawObjectAtOffset($base_offset);
$type = $base_object->getType();
$data = $this->patchDelta($delta, $base_object);
$raw_object = new RawObject($type, $data);
} else {
$data = gzuncompress($this->reader->read($size + 512), $size);
$raw_object = new RawObject($type, $data);
if ($raw_object->getLength() != $size) {
throw new InvalidPackfileException(sprintf("Unexpected RawObject length, expected %d, was %d", $size, $raw_object->getLength()));
}
}
}
return $raw_object;
}