示例#1
0
 public function indexPack($filename, $fix_thin = true)
 {
     $this->f = fopen($filename, "r+b");
     if (!$this->f) {
         throw new Exception("Cannot open file {$filename}");
     }
     flock($this->f, LOCK_EX);
     $this->hash = hash_init("sha1");
     // Read pack header
     $s = $this->getBytes(8);
     if ($s != "PACK") {
         throw new Exception("Invalid pack header");
     }
     $count = Binary::uint32($this->GetBytes(4));
     // Read objects
     for ($i = 0; $i < $count; $i++) {
         $obj = $this->readObject();
     }
     // Check pack sha1 sum
     $fixpos = ftell($this->f);
     $pack_hash = hash_final($this->hash, true);
     $pack_hash_check = fread($this->f, 20);
     if ($pack_hash !== $pack_hash_check) {
         throw new Exception("Invalid pack checksum");
     }
     // Resolve deltas
     foreach ($this->objects as $hash => $obj) {
         $this->resolveDeltas($hash, $obj);
     }
     if (count($this->unresolved_hash) !== 0 && $fix_thin) {
         unset($this->hash);
         foreach ($this->unresolved_hash as $hash => $objs) {
             try {
                 list($type, $data) = $this->repo->getRawObject($hash);
             } catch (Exception $e) {
                 continue;
             }
             // Create new PackObj
             $newobj = new PackObj();
             $newobj->type = $type;
             $newobj->pos = $fixpos;
             // Write object to the file
             fseek($this->f, $fixpos);
             $this->writeObject($type, $data);
             $fixpos = ftell($this->f);
             // Add object to index
             $newhash = $this->addObject($newobj, $data);
             assert($newhash === $hash);
             //resolve child deltas
             $this->resolveObjs($objs, $newobj, $data);
             unset($data);
             unset($this->unresolved_hash[$hash]);
         }
         // fix count of objects in the pack
         fseek($this->f, 8);
         $this->writeInt32(count($this->objects));
         // recalculate hash of entire pack
         ftruncate($this->f, $fixpos);
         fseek($this->f, 0);
         $newhash = hash_init("sha1");
         while (!feof($this->f)) {
             hash_update($newhash, fread($this->f, 0x10000));
         }
         $pack_hash = hash_final($newhash, true);
         fwrite($this->f, $pack_hash);
     }
     if (count($this->unresolved_hash) !== 0 || count($this->unresolved_offs) !== 0) {
         throw new Exception("Cannot resolve deltas");
     }
     fclose($this->f);
     // Build fanout table and pack name
     ksort($this->objects);
     $h = hash_init("sha1");
     $fanout = array();
     for ($i = 0; $i < 256; $i++) {
         $fanout[$i] = 0;
     }
     foreach ($this->objects as $hash => $obj) {
         $fanout[ord($hash[0])]++;
         hash_update($h, $hash);
     }
     for ($i = 1; $i < 256; $i++) {
         $fanout[$i] += $fanout[$i - 1];
     }
     $packname = hash_final($h);
     // Rename the temporary pack file and write index (at this time only index v1 supported)
     rename($filename, sprintf('%s/objects/pack/pack-%s.pack', $this->repo->dir, $packname));
     $this->f = fopen(sprintf('%s/objects/pack/pack-%s.idx', $this->repo->dir, $packname), "wb");
     if (!$this->f) {
         throw new Exception("Cannot open index file");
     }
     $this->hash = hash_init("sha1");
     // Write fanout table
     for ($i = 0; $i < 256; $i++) {
         $this->writeInt32($fanout[$i]);
     }
     // Write objects table
     foreach ($this->objects as $hash => $obj) {
         $this->writeInt32($obj->pos);
         $this->writeBytes($hash);
     }
     // Write original pack hashsum
     $this->writeBytes($pack_hash);
     // Write index hashsum
     $idx_hash = hash_final($this->hash, true);
     fwrite($this->f, $idx_hash);
     fclose($this->f);
 }
示例#2
0
文件: Binary.php 项目: aredridel/glip
 public static function fuint32($f)
 {
     return Binary::uint32(fread($f, 4));
 }
示例#3
0
 protected function uint32_at($pos)
 {
     return Binary::uint32($this->cache, $pos);
 }