Пример #1
0
 /**
  * Search the index for a pack offset
  *
  * @param resource $index file pointer to index
  * @param string $hash hash to find
  * @param int $low low bound offset
  * @param int $high high bound offset
  * @return int|boolean pack offset or false if not found
  */
 public function SearchIndex($index, $hash, $low, $high)
 {
     /*
      * index v2 structure:
      * magic and version - 2*4 bytes
      * fanout table - 256*4 bytes
      * sha listing - 20*count bytes
      * crc checksums - 4*count bytes
      * offsets - 4*count bytes
      */
     /*
      * get the object count from fanout[255]
      */
     fseek($index, 8 + 4 * 255);
     $objectCount = GitPHP_Pack::fuint32($index);
     /*
      * binary search for the index of the hash in the sha listing
      * between cur and after from the fanout
      */
     $objIndex = false;
     while ($low <= $high) {
         $mid = $low + $high >> 1;
         fseek($index, 8 + 4 * 256 + 20 * $mid);
         $binName = fread($index, 20);
         $name = bin2hex($binName);
         $cmp = strcmp($hash, $name);
         if ($cmp < 0) {
             $high = $mid - 1;
         } else {
             if ($cmp > 0) {
                 $low = $mid + 1;
             } else {
                 $objIndex = $mid;
                 break;
             }
         }
     }
     if ($objIndex === false) {
         return false;
     }
     /*
      * get the offset from the same index in the offset table
      */
     fseek($index, 8 + 4 * 256 + 24 * $objectCount + 4 * $objIndex);
     $offset = GitPHP_Pack::fuint32($index);
     if ($offset & 0x80000000) {
         throw new Exception('64-bit offsets not implemented');
     }
     return $offset;
 }
Пример #2
0
 /**
  * Tests if a pack file is valid
  *
  * @return boolean true if valid
  */
 public function Valid()
 {
     if (!$this->validated) {
         $this->validated = true;
         $this->valid = false;
         $pack = fopen($this->path, 'rb');
         flock($pack, LOCK_SH);
         $magic = fread($pack, 4);
         $version = GitPHP_Pack::fuint32($pack);
         if ($magic == 'PACK' && $version == 2) {
             $this->valid = true;
         }
         flock($pack, LOCK_UN);
         fclose($pack);
     }
     return $this->valid;
 }
Пример #3
0
 /**
  * Find hashes in index matching a prefix
  *
  * @param resource $index file pointer to index
  * @param string $prefix hash prefix
  * @param int $low low bound offset
  * @param int $high high bound offset
  * @return string[] matching hashes
  */
 public function FindHashes($index, $prefix, $low, $high)
 {
     $matches = array();
     $range = $high - $low;
     $prefixlen = strlen($prefix);
     fseek($index, 4 * 256 + 24 * $low);
     for ($i = 0; $i < $range; $i++) {
         GitPHP_Pack::fuint32($index);
         // offset
         $binName = fread($index, 20);
         $name = bin2hex($binName);
         $cmp = substr_compare($name, $prefix, 0, $prefixlen);
         if ($cmp === 0) {
             $matches[] = $name;
         } else {
             if ($cmp > 0) {
                 break;
             }
         }
     }
     return $matches;
 }
Пример #4
0
 /**
  * Reads and unpacks the next 32 bit integer
  *
  * @return int integer
  * @param resource $handle file handle
  */
 public static function fuint32($handle)
 {
     return GitPHP_Pack::uint32(fread($handle, 4));
 }