in proxy-chooser/classes/IP2Location.php [691:804]
public function __construct($file = null, $mode = self::FILE_IO, $defaultFields = self::ALL)
{
// find the referred file and its size
$rfile = self::findFile($file);
$size = filesize($rfile);
// initialize caching backend
switch ($mode) {
case self::SHARED_MEMORY:
// verify the shmop extension is loaded
if (!\extension_loaded('shmop')) {
throw new \Exception(__CLASS__ . ": Please make sure your PHP setup has the 'shmop' extension enabled.", self::EXCEPTION_NO_SHMOP);
}
$limit = self::getMemoryLimit();
if ($limit !== false && $size > $limit) {
throw new \Exception(__CLASS__ . ": Insufficient memory to load file '{$rfile}'.", self::EXCEPTION_NO_MEMORY);
}
$this->mode = self::SHARED_MEMORY;
$shmKey = self::getShmKey($rfile);
// try to open the shared memory segment
$this->resource = @shmop_open($shmKey, 'a', 0, 0);
if ($this->resource === false) {
// the segment did not exist, create it and load the database into it
$fp = fopen($rfile, 'r');
if ($fp === false) {
throw new \Exception(__CLASS__ . ": Unable to open file '{$rfile}'.", self::EXCEPTION_FILE_OPEN_FAILED);
}
// try to open the memory segment for exclusive access
$shmId = @shmop_open($shmKey, 'n', self::SHM_PERMS, $size);
if ($shmId === false) {
throw new \Exception(__CLASS__ . ": Unable to create shared memory block '{$shmKey}'.", self::EXCEPTION_SHMOP_CREATE_FAILED);
}
// load SHM_CHUNK_SIZE bytes at a time
$pointer = 0;
while ($pointer < $size) {
$buf = fread($fp, self::SHM_CHUNK_SIZE);
shmop_write($shmId, $buf, $pointer);
$pointer += self::SHM_CHUNK_SIZE;
}
shmop_close($shmId);
fclose($fp);
// now open the memory segment for readonly access
$this->resource = @shmop_open($shmKey, 'a', 0, 0);
if ($this->resource === false) {
throw new \Exception(__CLASS__ . ": Unable to access shared memory block '{$shmKey}' for reading.", self::EXCEPTION_SHMOP_READING_FAILED);
}
}
break;
case self::FILE_IO:
$this->mode = self::FILE_IO;
$this->resource = @fopen($rfile, 'r');
if ($this->resource === false) {
throw new \Exception(__CLASS__ . ": Unable to open file '{$rfile}'.", self::EXCEPTION_FILE_OPEN_FAILED);
}
break;
case self::MEMORY_CACHE:
$this->mode = self::MEMORY_CACHE;
$this->resource = $rfile;
if (!\array_key_exists($rfile, self::$buffer)) {
$limit = self::getMemoryLimit();
if ($limit !== false && $size > $limit) {
throw new \Exception(__CLASS__ . ": Insufficient memory to load file '{$rfile}'.", self::EXCEPTION_NO_MEMORY);
}
self::$buffer[$rfile] = @file_get_contents($rfile);
if (self::$buffer[$rfile] === false) {
throw new \Exception(__CLASS__ . ": Unable to open file '{$rfile}'.", self::EXCEPTION_FILE_OPEN_FAILED);
}
}
break;
default:
}
// determine the platform's float size
//
// NB: this should be a constant instead, and some unpack / typebanging magic
// should be used to accomodate different float sizes, but, as the libreary
// is written, this is the sanest thing to do anyway
//
if (self::$floatSize === null) {
self::$floatSize = \strlen(pack('f', M_PI));
}
// set default fields to retrieve
$this->defaultFields = $defaultFields;
// extract database metadata
$this->type = $this->readByte(1) - 1;
$this->columnWidth[4] = $this->readByte(2) * 4;
$this->columnWidth[6] = $this->columnWidth[4] + 12;
$this->offset[4] = -4;
$this->offset[6] = 8;
$this->year = 2000 + $this->readByte(3);
$this->month = $this->readByte(4);
$this->day = $this->readByte(5);
$this->date = date('Y-m-d', strtotime("{$this->year}-{$this->month}-{$this->day}"));
$this->ipCount[4] = $this->readWord(6);
$this->ipBase[4] = $this->readWord(10); //hjlim readword
$this->ipCount[6] = $this->readWord(14);
$this->ipBase[6] = $this->readWord(18);
$this->indexBaseAddr[4] = $this->readWord(22); //hjlim
$this->indexBaseAddr[6] = $this->readWord(26); //hjlim
}