hellbound/utils/gme/utils.inc.php

360 lines
7.0 KiB
PHP
Raw Permalink Normal View History

2021-11-26 11:16:25 +03:00
<?php
class gmeStrictPropsObject
{
function getTextPropsList()
{
return implode(", ", gme_get_public_props_names($this));
}
function __get($name)
{
throw new Exception("No such property '$name' in class " . get_class($this) . " to get, available properties: " .
$this->getTextPropsList());
}
function __set($name, $value)
{
throw new Exception("No such property '$name' in class " . get_class($this) . " to set, available properties: " .
$this->getTextPropsList());
}
}
class gmeDirtableObject extends gmeStrictPropsObject
{
private $__dirty_props = array();
function get($name)
{
return $this->$name;
}
function set($name, $value)
{
$old_value = $this->$name;
//no need to update the property which has the same value
//also comparing long strings can be slow
if(!is_string($value) && $value === $old_value)
return;
$this->$name = $value;
$this->__dirty_props[$name] = 1;
}
function isDirty()
{
return sizeof($this->__dirty_props) > 0;
}
function isDirtyProp($name)
{
return isset($this->__dirty_props[$name]);
}
function getDirtyProps()
{
return $this->__dirty_props;
}
function undirty()
{
$this->__dirty_props = array();
}
function importPublic(array $props)
{
foreach($props as $key => $value)
$this->set($key, $value);
}
function exportPublic()
{
return gme_get_public_props($this);
}
protected function _markDirtyProp($name)
{
$this->__dirty_props[$name] = 1;
}
protected function _unmarkDirtyProp($name)
{
unset($this->__dirty_props[$name]);
}
}
function gme_get_exception_error(Exception $e, $full_trace = true)
{
return $e->getMessage() . ',' . ($full_trace ? $e->getTraceAsString() : gme_get_exception_short_trace($e));
}
function gme_get_exception_short_trace(Exception $e)
{
$trace = $e->getTrace();
if(!is_array($trace) || !isset($trace[0]) || !isset($trace[0]['file']) || !isset($trace[0]['line']))
return '???(???)';
return $trace[0]['file'] . '(' . $trace[0]['line'] . ')';
}
function gme_q($str)
{
return $str ? '"'.$str.'"' : $str;
}
function gme_get_public_props_names($obj)
{
static $cache = array();
$klass = is_string($obj) ? $obj : get_class($obj);
if(!isset($cache[$klass]))
$cache[$klass] = array_keys(get_class_vars($klass));
return $cache[$klass];
}
function gme_get_public_props($obj)
{
return get_object_vars($obj);
}
function gme_copy_public_props($src, $dst)
{
$props = gme_get_public_props_names($src);
foreach($props as $p)
$dst->$p = $src->$p;
}
function gme_props_arr2flat_arr(array $arr, array $order_props)
{
$flat = array();
foreach($order_props as $p)
$flat[] = $arr[$p];
return $flat;
}
function gme_flat_arr2props_arr(array $flat_arr, array $props)
{
$arr = array();
foreach($props as $i => $p)
$arr[$p] = $flat_arr[$i];
return $arr;
}
function gme_compare_arrays(array $arr1, array $arr2)
{
if(sizeof($arr1) !== sizeof($arr2))
return false;
foreach($arr1 as $idx => $f1)
if($arr2[$idx] !== $f1)
return false;
return true;
}
function gme_crc32f($what)
{
//NOTE: making sure that crc32 is always an unsigned value,
//even on 32 bit platform, this is achieved by converting the int
//to float
$v = crc32($what);
if(0 > $v)
$v += 0x100000000;
return floatval($v);
}
function gme_crc28($what)
{
return crc32($what) & 0xFFFFFFF;
}
function gme_static_hash($whar)
{
$hash = 0;
for($i = 0; $i < strlen($whar); ++$i)
{
$hash = ((65599 * $hash) & 0x0FFFFFFF) + ord($whar[$i]);
}
return ($hash ^ ($hash >> 16));
}
function gme_crc16($what)
{
return crc32($what) & 0xFFFF;
}
function gme_pack_array($fmt, array $args)
{
array_unshift($args, $fmt . sizeof($args));
return call_user_func_array('pack', $args);
}
function gme_unpack_array($fmt, $binstr)
{
return unpack("$fmt*", $binstr);
}
function gme_pack_int_array(array $arr)
{
return gme_pack_array('L', $arr);
}
function gme_unpack_int_array($bin)
{
return gme_unpack_array('L', $bin);
}
function gme_pack_map($kfmt, $fmt, array $map)
{
$arr = array();
foreach($map as $k => $v)
{
$arr[] = $k;
$arr[] = $v;
}
return gme_pack_array($fmt, $arr);
}
function gme_unpack_map($kfmt, $fmt, $binstr)
{
$map = array();
$arr = gme_unpack_array($fmt, $binstr);
//unpack for some reason start indices from 1
for($i=1;$i<=sizeof($arr);$i+=2)
{
$map[$arr[$i]] = $arr[$i+1];
}
return $map;
}
function gme_pack_int_map(array $map)
{
return gme_pack_map('L', 'L', $map);
}
function gme_unpack_int_map($bin)
{
return gme_unpack_map('L', 'L', $bin);
}
function gme_json2array($js)
{
$arr = json_decode($js, true);
if($arr === null)
{
if(function_exists('json_last_error'))
{
switch(json_last_error())
{
case JSON_ERROR_DEPTH:
throw new Exception("Maximum stack depth exceeded: $js");
case JSON_ERROR_CTRL_CHAR:
throw new Exception("Unexpected control character found: $js");
case JSON_ERROR_SYNTAX:
throw new Exception("Syntax error, malformed JSON: $js");
}
}
else
{
throw new Exception("Could not parse json string: $js");
}
}
return $arr;
}
function gme_json2array_safe($js)
{
try
{
return gme_json2array($js);
}
catch(Exception $e)
{
return array();
}
}
function gme_clamp($v, $min, $max)
{
return max(min($v, $max), $min);
}
function gme_paginate($total, $step)
{
//pages are returned as an array where each element is in interval [N, Y)
$pages = array();
$steps = (int)($total/$step);
$rest = $total % $step;
for($i=1;$i<=$steps;++$i)
$pages[] = array(($i-1)*$step, $i*$step);
if($rest != 0)
$pages[] = array(($i-1)*$step, ($i-1)*$step + $rest);
return $pages;
}
function gme_paginate_array(array $arr, $limit)
{
$splitted = array();
$pages = gme_paginate(sizeof($arr), $limit);
foreach($pages as $page)
{
$tmp = array();
for($i=$page[0];$i<$page[1];++$i)
$tmp[] = $arr[$i];
$splitted[] = $tmp;
}
return $splitted;
}
function gme_normalize_url($url)
{
$parts = explode('/', $url);
$new = array();
foreach($parts as $part)
{
if($part === '..')
array_pop($new);
else
$new[] = $part;
}
return implode('/', $new);
}
function gme_decrypt($encrypted, $pass, $iv)
{
return openssl_decrypt($encrypted, 'AES256', $pass, false, $iv);
}
function gme_encrypt($data, $pass, $iv)
{
return openssl_encrypt($data, 'AES256', $pass, false, $iv);
}
function gme_millisecs($precision = 6)
{
$utimestamp = microtime(true);
$timestamp = floor($utimestamp);
return round(($utimestamp - $timestamp) * pow(10, $precision));
}
function gme_var_dump($v, $max_len = -1, $whitespace_preserve = true)
{
$str = str_replace("\n", "", var_export($v, true));
if(!$whitespace_preserve)
$str = preg_replace("~\s+~", "", $str);
if($max_len > -1 && strlen($str) > $max_len)
$str = substr($str, 0, $max_len) . '...';
return $str;
}
function gme_is_win()
{
return !(DIRECTORY_SEPARATOR == '/');
}