Gittern\Transport\Packfile::getRawObjectAtOffset PHP Method

getRawObjectAtOffset() public method

See also: http://git.rsbx.net/Documents/Git_Data_Formats.txt
See also: http://www.opensource.apple.com/source/Git/Git-17/src/git-htmldocs/technical/pack-format.txt
public getRawObjectAtOffset ( $offset )
    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;
    }