public function hydrate($data) { $index = new Index(); $reader = new StringReader($data); $signature = $reader->readString8(4); $version = $reader->readUInt32BE(); if ($signature != Index::SIGNATURE || $version != Index::VERSION) { throw new IndexVersionException("IndexHydrator only supports indexes with signature " . Index::SIGNATURE . " and version " . Index::VERSION); } $entries = $reader->readUInt32BE(); $extended_contents_start = $reader->getOffset(); for ($i = 0; $i < $entries; $i++) { $entry = new IndexEntry(); $start = $reader->getOffset(); $entry->setCtime($this->readEntryTime($reader)); $entry->setMtime($this->readEntryTime($reader)); $entry->setDev($reader->readUInt32BE()); $entry->setInode($reader->readUInt32BE()); $entry->setMode($reader->readUInt32BE()); $entry->setUid($reader->readUInt32BE()); $entry->setGid($reader->readUInt32BE()); $entry->setFileSize($reader->readUInt32BE()); $entry->setBlob(new BlobProxy($this->repo, $reader->readHHex(20))); $flags = $reader->readUInt16BE(); $entry->setName(rtrim($reader->readString16(($flags & 0xfff) + 1, $foo, true), "")); //+1 is to capture mandatory NUL $entry->setStage(($flags & 0x3000) >> 12); $stop = $reader->getOffset(); $length = $stop - $start; $padded_length = ceil($length / 8) * 8; $reader->setOffset($start + $padded_length); $index->addEntry($entry); } while ($reader->getOffset() < $reader->getSize() - 20) { $name = $reader->readString8(4); if (ord($name[0]) >= 0x41 && ord($name[0]) <= 0x5a) { // Optional extension, just skip it $data_size = $reader->readUInt32BE(); $reader->skip($data_size); } else { throw new IndexVersionException("IndexHydrator doesn't support the mandatory " . $name . " extension"); } } $extended_contents_stop = $reader->getOffset(); $reader->setOffset(0); $calculated_sha = sha1($reader->read($extended_contents_stop)); $checksum = $reader->readHHex(20); if ($checksum != $calculated_sha) { throw new ChecksumException("Index checksum does not match"); } return $index; }
public function write($key, $content, array $metadata = null) { $blob = new Blob(); $blob->setContents($content); $this->repo->desiccateGitObject($blob); $entry = new IndexEntry(); $entry->setCtime(time() . ".0"); $entry->setMtime(time() . ".0"); $entry->setDev(0); $entry->setInode(0); $entry->setMode(0100644); $entry->setUid(0); $entry->setGid(0); $entry->setFileSize(strlen($content)); $entry->setBlob($blob); $entry->setName($key); $entry->setStage(0); $this->getIndex()->addEntry($entry); $this->flushIfSupposedTo(); }