public function binarySearch( $ip )
    {
        //check and conver the ip address
        if ( is_string($ip) ) $ip = self::safeIp2long($ip);
        if ( $this->totalBlocks == 0 ) {
            //check and open the original db file
            if ( $this->dbFileHandler == NULL ) {
                $this->dbFileHandler = fopen($this->dbFile, 'r');
                if ( $this->dbFileHandler == false ) {
                    throw new Exception("Fail to open the db file {$this->dbFile}");
                }
            }

            fseek($this->dbFileHandler, 0);
            $superBlock = fread($this->dbFileHandler, 8);

            $this->firstIndexPtr = self::getLong($superBlock, 0);
            $this->lastIndexPtr  = self::getLong($superBlock, 4);
            $this->totalBlocks   = ($this->lastIndexPtr-$this->firstIndexPtr)/INDEX_BLOCK_LENGTH + 1;
        }

        //binary search to define the data
        $l = 0;
        $h = $this->totalBlocks;
        $dataPtr = 0;
        while ( $l <= $h ) {
            $m = (($l + $h) >> 1);
            $p = $m * INDEX_BLOCK_LENGTH;

            fseek($this->dbFileHandler, $this->firstIndexPtr + $p);
            $buffer = fread($this->dbFileHandler, INDEX_BLOCK_LENGTH);
            $sip    = self::getLong($buffer, 0);
            if ( $ip < $sip ) {
                $h = $m - 1;
            } else {
                $eip = self::getLong($buffer, 4);
                if ( $ip > $eip ) {
                    $l = $m + 1;
                } else {
                    $dataPtr = self::getLong($buffer, 8);
                    break;
                }
            }
        }

        //not matched just stop it here
        if ( $dataPtr == 0 ) return NULL;


        //get the data
        $dataLen = (($dataPtr >> 24) & 0xFF);
        $dataPtr = ($dataPtr & 0x00FFFFFF);

        fseek($this->dbFileHandler, $dataPtr);
        $data = fread($this->dbFileHandler, $dataLen);

        return array(
            'city_id' => self::getLong($data, 0), 
            'region'  => substr($data, 4)
        );
    }