You are here

private function Database::binSearch in Smart IP 7.2

Same name and namespace in other branches
  1. 6.2 includes/vendor/ip2location/ip2location-php/IP2Location.php \IP2Location\Database::binSearch()

Perform a binary search on the given IP number and return a pointer to its record

@access private

Parameters

int $version IP version to use for searching:

int $ipNumber IP number to look for:

Return value

int|boolean

1 call to Database::binSearch()
Database::lookup in includes/vendor/ip2location/ip2location-php/IP2Location.php
This function will look the given IP address up in the database and return the result(s) asked for

File

includes/vendor/ip2location/ip2location-php/IP2Location.php, line 1472

Class

Database
IP2Location database class

Namespace

IP2Location

Code

private function binSearch($version, $ipNumber) {
  if (false === $version) {

    // unrecognized version
    return false;
  }

  // initialize fields
  $base = $this->ipBase[$version];
  $offset = $this->offset[$version];
  $width = $this->columnWidth[$version];
  $high = $this->ipCount[$version];
  $low = 0;

  //hjlim
  $indexBaseStart = $this->indexBaseAddr[$version];
  if ($indexBaseStart > 0) {
    $indexPos = 0;
    switch ($version) {
      case 4:
        $ipNum1_2 = intval($ipNumber >> 16);
        $indexPos = $indexBaseStart + ($ipNum1_2 << 3);
        break;
      case 6:
        $ipNum1 = intval(bcdiv($ipNumber, bcpow('2', '112')));
        $indexPos = $indexBaseStart + ($ipNum1 << 3);
        break;
      default:
        return false;
    }
    $low = $this
      ->readWord($indexPos);
    $high = $this
      ->readWord($indexPos + 4);
  }

  // as long as we can narrow down the search...
  while ($low <= $high) {
    $mid = (int) ($low + ($high - $low >> 1));

    // Read IP ranges to get boundaries
    $ip_from = $this
      ->readIp($version, $base + $width * $mid);
    $ip_to = $this
      ->readIp($version, $base + $width * ($mid + 1));

    // determine whether to return, repeat on the lower half, or repeat on the upper half
    switch (self::ipBetween($version, $ipNumber, $ip_from, $ip_to)) {
      case 0:
        return $base + $offset + $mid * $width;
      case -1:
        $high = $mid - 1;
        break;
      case 1:
        $low = $mid + 1;
        break;
    }
  }

  // nothing found
  return false;
}