Author: Magnus Nordlander
示例#1
0
 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;
 }
示例#2
0
 public function desiccate(Index $index)
 {
     $writer = new StringWriter();
     $entries = $index->getEntries();
     $writer->writeString8(Index::SIGNATURE);
     $writer->writeUInt32BE(Index::VERSION);
     $writer->writeUInt32BE(count($entries));
     $contents_offset = $writer->getOffset();
     usort($entries, function ($a, $b) {
         $cmp = strcmp($a->getName(), $b->getName());
         if ($cmp == 0) {
             return ($a->getStage() - $b->getStage());
         }
         return $cmp;
     });
     foreach ($entries as $entry) {
         $start = $writer->getOffset();
         $this->writeEntryTime($writer, $entry->getCtime());
         $this->writeEntryTime($writer, $entry->getMtime());
         $writer->writeUInt32BE($entry->getDev());
         $writer->writeUInt32BE($entry->getInode());
         $writer->writeUInt32BE($entry->getMode());
         $writer->writeUInt32BE($entry->getUid());
         $writer->writeUInt32BE($entry->getGid());
         $writer->writeUInt32BE($entry->getFileSize());
         $writer->writeHHex($entry->getBlob()->getSha());
         //FIXME: Stage
         $writer->writeUInt16BE(strlen($entry->getName()));
         $stop = $writer->getOffset();
         $length = $stop - $start + strlen($entry->getName()) + 1;
         //We need at least 1 NUL
         $padded_length = ceil($length / 8) * 8;
         $rest_length = $padded_length - $length;
         $writer->writeString8($entry->getName(), strlen($entry->getName()) + 1 + $rest_length);
     }
     $writer->writeHHex(sha1($writer->toString()));
     return $writer->toString();
 }