<?php
if ( !function_exists("json_decode") ) {
function json_decode($text) {
eval("\$var=".preg_replace('/(\"[^\"]+\"):/', "$1=>", preg_replace('/\}|\]/', ")", preg_replace('/\[|\{/', "array(", $text))).";");
return $var;
}
}
if ( !function_exists("json_encode") ) {
function json_encode($var) {
if ( is_array($var) && count($var) && (array_keys($var)!==range(0,sizeof($var)-1)) ) {
$res = array();
foreach ( array_keys($var) as $key )
$res[] = "\"$key\":".json_encode($var{$key});
return "{".join(",",$res)."}";
}
if ( is_array($var) ) {
$res = array();
foreach ( array_keys($var) as $key )
$res[] = json_encode($var{$key});
return "[".join(",",$res)."]";
}
if ( is_string($var) ) {
return "\"".addslashes($var)."\"";
}
if ( is_numeric($var) ) {
return $var;
}
return "";
}
}
class Geobaza {
function Geobaza($filepath="geobaza.dat") {
$this->is_valid = false;
$this->error_message = "";
$this->fp_binary_tree = fopen($filepath, 'r');
if ( !$this->fp_binary_tree ) {
$this->error_message = "Can't open binary tree file \"".$filepath."\"";
return false;
}
$data = fread($this->fp_binary_tree, 7);
if ( $data != "GEOBAZA" ) {
$this->error_message = "Invalid datafile signature";
return false;
}
$data = fread($this->fp_binary_tree, 2);
$unp = unpack('nlen', $data);
$data = fread($this->fp_binary_tree, $unp['len']);
$this->headers = json_decode($data, true);
$this->level_size = array();
for(;;) {
$data = fread($this->fp_binary_tree, 1);
$unp = unpack('Cdata', $data);
$hi = ($unp['data']>>4) & 0x0f;
$lo = $unp['data'] & 0x0f;
$this->level_size[] = $hi;
if ( $hi == 0 )
break;
$this->level_size[] = $lo;
if ( $lo == 0 )
break;
}
$this->start_offset = ftell($this->fp_binary_tree);
$this->is_valid = true;
}
function __destruct() {
fclose($this->fp_binary_tree);
}
function lookup($ip) {
if ( !$this->is_valid )
return false;
$ipint = ip2long($ip);
$shift = 32;
$offset = $this->start_offset;
$result = array();
for($l=0; $l<sizeof($this->level_size); $l++) {
$shift -= $this->level_size[$l];
$index = (($ipint>>$shift)) & ((1<<$this->level_size[$l])-1);
$tell = $offset+$index*4;
fseek($this->fp_binary_tree, $tell, 0);
$data = fread($this->fp_binary_tree, 4);
$unp = unpack('Ndata',$data);
$offset = $unp['data'] & 0xffffffff;
if ( $offset & 0x80000000 ) {
while ( $offset ) {
$tell = $offset & 0x7fffffff;
fseek($this->fp_binary_tree, $tell, 0);
$data = fread($this->fp_binary_tree, 2);
$unp = unpack('nlen', $data);
$length = $unp['len'] & 0xffff;
if ( !$length )
return "";
$info = fread($this->fp_binary_tree, $length);
$unpacked_data = json_decode($info, true);
if ( isset($unpacked_data['special']) ) {
return $unpacked_data;
}
$result[] = $unpacked_data;
$data = fread($this->fp_binary_tree, 4);
$unp = unpack('Nparent', $data);
$offset = $unp['parent'];
}
break;
}
}
return array('items'=>$result);
}
var $is_valid;
function is_valid() {
return $this->is_valid;
}
var $error_message;
function get_error() {
return $this->error_message;
}
var $headers;
function get_headers() {
return $this->headers;
}
var $level_size;
var $start_offset;
var $fp_binary_tree;
var $dbh;
}
?>