public function __construct()

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
	}