/** * @see http://git.rsbx.net/Documents/Git_Data_Formats.txt * @see http://www.opensource.apple.com/source/Git/Git-17/src/git-htmldocs/technical/pack-format.txt **/ 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; }
public function putRawObject(RawObject $raw_object) { $sha = $raw_object->getSha(); $first = substr($sha, 0, 2); $last = substr($sha, 2); $data = gzcompress($raw_object->getType() . ' ' . $raw_object->getLength() . "" . $raw_object->getData(), 4); if (!$this->isFileRelative('objects/' . $first . '/' . $last)) { $this->writeFileRelative('objects/' . $first . '/' . $last, $data); } }