diff --git a/config.inc.php b/config.inc.php index f00b2f4..0673d7e 100644 --- a/config.inc.php +++ b/config.inc.php @@ -37,13 +37,13 @@ function config_set_base_dirs(array $dirs) $CONFIG_BASE_DIRS = array_map(function($d) { return normalize_path($d); }, $dirs); } -function config_base_dirs() +function config_base_dirs() : array { global $CONFIG_BASE_DIRS; return $CONFIG_BASE_DIRS; } -function config_map_base_dir($file, $normalized = false, $strict = true, $dirs = null) +function config_map_base_dir(string $file, bool $normalized = false, bool $strict = true, ?array $dirs = null) : ?string { if(!is_array($dirs)) $dirs = config_base_dirs(); @@ -57,7 +57,7 @@ function config_map_base_dir($file, $normalized = false, $strict = true, $dirs = return null; } -function config_real_path($rel_path, $strict = true, $dirs = null) +function config_real_path(string $rel_path, bool $strict = true, ?array $dirs = null) : ?string { if(!is_array($dirs)) $dirs = config_base_dirs(); @@ -69,25 +69,25 @@ function config_real_path($rel_path, $strict = true, $dirs = null) return null; } -function config_build_dir() +function config_build_dir() : string { global $GAME_ROOT; return "$GAME_ROOT/build/tmp/"; } -function config_set_worker_init_fn($fn) +function config_set_worker_init_fn(callable $fn) { global $CONFIG_INIT_WORKER_FUNC; $CONFIG_INIT_WORKER_FUNC = $fn; } -function config_scan_files() +function config_scan_files() : array { $files = scan_files_rec(config_base_dirs(), array('conf.js')); return config_filter_files($files); } -function config_filter_files(array $files) +function config_filter_files(array $files) : array { global $CONFIG_FILTER_FN; if($CONFIG_FILTER_FN != null) @@ -101,13 +101,54 @@ function config_set_files_filter_fn(callable $fn) $CONFIG_FILTER_FN = $fn; } -function config_pack_bundle(array $cache_entries, $use_lz4 = false, $use_config_refs = false) +function config_pack_bundle( + array $cache_entries, + bool $use_lz4 = false, + bool $use_config_refs = false, + int $binary_format = 1, + ?int $version = null +) : string { global $GAME_ROOT; - $binary_format = 1; - $version = game_version_code(); + if(is_null($version)) + $version = game_version_code(); + $packed_data = null; + + if($binary_format == 1) + { + $packed_data = _config_pack_bundle_fmt1( + $cache_entries, + $use_lz4, + $use_config_refs, + $version + ); + } + else if($binary_format == 2) + { + $packed_data = _config_pack_bundle_fmt2( + $cache_entries, + $use_lz4, + $use_config_refs, + $version + ); + } + else + throw new Exception("Unknown binary format: $binary_format"); + + echo "CONF.BUNDLE: entries " . sizeof($cache_entries) . "; total " . kb($packed_data) . + "; format $binary_format; lz4 $use_lz4; refs $use_config_refs; CRC " . crc32($packed_data) . "\n"; + + return $packed_data; +} + +function _config_pack_bundle_fmt1( + array $cache_entries, + bool $use_lz4 = false, + bool $use_config_refs = false, + int $version) : string +{ $MAP = array(); $STRIDMAP = array(); @@ -149,21 +190,109 @@ function config_pack_bundle(array $cache_entries, $use_lz4 = false, $use_config_ $payloads_bundle .= $item[1]; $packed_data = - pack("C", $binary_format) . + pack("C", 1) . pack("V", $version) . pack("V", strlen($header_msgpack)) . $header_msgpack . $payloads_bundle; - echo "CONF.BUNDLE: entries " . sizeof($cache_entries) . "; total " . kb($packed_data) . - "; lz4 $use_lz4; refs $use_config_refs; CRC " . crc32($packed_data) . "\n"; + return $packed_data; +} + +function _config_pack_bundle_fmt2( + array $cache_entries, + bool $use_lz4 = false, + bool $use_config_refs = false, + int $version) : string +{ + $MAP = array(); + $STRIDMAP = array(); + $STRIDLIST = array(); + + $payloads = array(); + $strids = array(); + $payloads_offset = 0; + foreach($cache_entries as $entry) + { + list($format, $payload) = _config_get_payload($entry, $use_lz4, $use_config_refs); + $payload_size = strlen($payload); + $payloads[] = array($payloads_offset, $payload, $format, $payload_size); + $payloads_offset += $payload_size; + + $strids_indices = array(); + $strid_parts = explode('/', ltrim($entry->strid, '@')); + foreach($strid_parts as $strid_part) + { + if(!isset($STRIDMAP[$strid_part])) + { + $strid_index = count($STRIDLIST); + $STRIDLIST[] = $strid_part; + $STRIDMAP[$strid_part] = $strid_index; + $strids_indices[] = $strid_index; + } + else + $strids_indices[] = $STRIDMAP[$strid_part]; + } + $strids[] = $strids_indices; + } + + $header = array(); + foreach($cache_entries as $idx => $entry) + { + if(isset($MAP[$entry->id])) + throw new Exception("Duplicating config id for '{$entry->strid}' conflicts with '{$MAP[$entry->id]}'"); + $MAP[$entry->id] = $entry->strid; + + $header[] = array( + $payloads[$idx][2], //format + $entry->id, + $strids[$idx], //strid as a lookup indices + $entry->class_id, + $payloads[$idx][0], //offset + $payloads[$idx][3] //size + ); + } + + $strids_msgpack = config_msgpack_pack($STRIDLIST); + + $header_msgpack = config_msgpack_pack($header); + $payloads_bundle = ''; + foreach($payloads as $item) + $payloads_bundle .= $item[1]; + + $packed_data = + pack("C", 2) . + pack("V", $version) . + pack("V", strlen($strids_msgpack)) . + pack("V", strlen($header_msgpack)) . + $strids_msgpack . + $header_msgpack . + $payloads_bundle; return $packed_data; } -function config_unpack_bundle($packed_data) +function config_unpack_bundle(string $packed_data) : array +{ + $packed_info = substr($packed_data, 0, 1); + $info = unpack('Cformat', $packed_info); + + if($info['format'] === 1) + { + return _config_unpack_bundle_fmt1($packed_data); + } + else if($info['format'] === 2) + { + return _config_unpack_bundle_fmt2($packed_data); + } + else + throw new Exception("Unknown format: {$info['format']}"); +} + +function _config_unpack_bundle_fmt1(string $packed_data) : array { $packed_info = substr($packed_data, 0, 1+4+4); + $info = unpack('Cformat/Vversion/Vheader_len', $packed_info); if($info['format'] !== 1) @@ -172,7 +301,7 @@ function config_unpack_bundle($packed_data) $header_msgpack = substr($packed_data, 1+4+4, $info['header_len']); $header = config_msgpack_unpack($header_msgpack); - $payloads_bundle = substr($packed_data, 1+4+4 + $info['header_len']); + $payloads_bundle = substr($packed_data, 1+4+4+$info['header_len']); $entries = array(); foreach($header as $item) @@ -187,7 +316,37 @@ function config_unpack_bundle($packed_data) return $entries; } -function _config_get_payload(ConfigCacheEntry $ce, $use_lz4, $use_config_refs) +function _config_unpack_bundle_fmt2(string $packed_data) : array +{ + $packed_info = substr($packed_data, 0, 1+4+4+4); + + $info = unpack('Cformat/Vversion/Vstrids_len/Vheader_len', $packed_info); + + if($info['format'] !== 2) + throw new Exception("Unknown format: {$info['format']}"); + + $strids_msgpack = substr($packed_data, 1+4+4+4, $info['strids_len']); + $strids = config_msgpack_unpack($strids_msgpack); + + $header_msgpack = substr($packed_data, 1+4+4+4+$info['strids_len'], $info['header_len']); + $header = config_msgpack_unpack($header_msgpack); + + $payloads_bundle = substr($packed_data, 1+4+4+4+$info['strids_len']+$info['header_len']); + + $entries = array(); + foreach($header as $item) + { + list($format, $id, $strid_crc, $class_id, $offset, $size) = $item; + + $payload = substr($payloads_bundle, $offset, $size); + + $entries[$id] = array($class_id, _config_unpack_payload($format, $payload)); + } + + return $entries; +} + +function _config_get_payload(ConfigCacheEntry $ce, bool $use_lz4, bool $use_config_refs) : array { $format = ConfigCacheEntry::FMT_BINARY; $payload = null; @@ -210,7 +369,7 @@ function _config_get_payload(ConfigCacheEntry $ce, $use_lz4, $use_config_refs) return array($format, $payload); } -function _config_unpack_payload($format, $payload) +function _config_unpack_payload(int $format, string $payload) : array { $msg_packed = null; if($format === ConfigCacheEntry::FMT_LZ4) @@ -224,7 +383,13 @@ function _config_unpack_payload($format, $payload) return config_msgpack_unpack($msg_packed); } -function config_make_standalone_ext_bundle(array $configs, $file_path, $use_lz4 = true) +function config_make_standalone_ext_bundle( + array $configs, + string $file_path, + bool $use_lz4 = true, + int $binary_format = 1, + ?int $version = null +) { $cache_entries = array(); foreach($configs as $conf) @@ -243,41 +408,41 @@ function config_make_standalone_ext_bundle(array $configs, $file_path, $use_lz4 $cache_entries[] = $entry; } - $packed_data = config_pack_bundle($cache_entries, $use_lz4); + $packed_data = config_pack_bundle($cache_entries, $use_lz4, false, $binary_format, $version); ensure_write($file_path, $packed_data); } -function config_bench_load($file) +function config_bench_load(string $file) { $base_dir = config_map_base_dir($file); - list($proto_id, $_) = config_ensure_header($base_dir, $file); - if(!$proto_id) - throw new Exception("Bad proto_id: {$proto_id}"); + list($conf_id, $_) = config_ensure_header($base_dir, $file); + if(!$conf_id) + throw new Exception("Bad conf id: {$conf_id}"); $t = microtime(true); $parse_res = config_parse(config_base_dirs(), $file); if($parse_res->error !== 0) throw new Exception("Error({$parse_res->error}) while loading JSON from {$file}:\n" . $parse_res->error_descr); echo "PARSE: " . (microtime(true) - $t) . "\n"; $t = microtime(true); - $config = config_load_ex($base_dir, $file, $parse_res->parsed_arr, $proto_id); + $config = config_load_ex($base_dir, $file, $parse_res->parsed_arr, $conf_id); echo "LOAD: " . (microtime(true) - $t) . "\n"; } -function config_get_tmp_build_path($file) +function config_get_tmp_build_path(string $file) : string { $name = str_replace(":", "-", str_replace("\\", "-", str_replace("/", "-", normalize_path($file)))); $name = ltrim($name, "-"); return normalize_path(config_build_dir() . "/$name"); } -function config_get_includes_map_path() +function config_get_includes_map_path() : string { return config_build_dir() . "/includes.map"; } -function config_load_includes_map($file = null) +function config_load_includes_map(?string $file = null) : array { $file = $file ? $file : config_get_includes_map_path(); @@ -293,7 +458,7 @@ function config_load_includes_map($file = null) return $includes_map; } -function config_save_includes_map(array $includes_map, $file = null) +function config_save_includes_map(array $includes_map, ?string $file = null) { $file = $file ? $file : config_get_includes_map_path(); @@ -302,19 +467,19 @@ function config_save_includes_map(array $includes_map, $file = null) class ConfigFetchResult { - public $all = array(); - public $by_id = array(); - public $by_path = array(); - public $by_alias = array(); + public array $all = array(); + public array $by_id = array(); + public array $by_path = array(); + public array $by_alias = array(); } function config_fetch_ex( array $files, - $force_stale = false, - $verbose = false, - $includes_map_file = null, - $max_workers = null -) + bool $force_stale = false, + bool $verbose = false, + ?string $includes_map_file = null, + ?int $max_workers = null +) : ConfigFetchResult { if(!$files) return new ConfigFetchResult(); @@ -363,7 +528,7 @@ function config_fetch_ex( return $result; } -function _config_fetch_cache_ex(array $results_by_job) +function _config_fetch_cache_ex(array $results_by_job) : array { $result = new ConfigFetchResult(); $total_stales = 0; @@ -409,7 +574,7 @@ function _config_fetch_cache_ex(array $results_by_job) return array($result, $total_stales); } -function _config_worker_run_procs(array $jobs, $includes_map_file, $force, $verbose) +function _config_worker_run_procs(array $jobs, string $includes_map_file, bool $force, bool $verbose) : array { $worker_args = array(); foreach($jobs as $idx => $job) @@ -418,7 +583,7 @@ function _config_worker_run_procs(array $jobs, $includes_map_file, $force, $verb return run_background_gamectl_workers('config_worker', $worker_args); } -function _config_worker_func(array $job, array $includes_map, $force, $verbose) +function _config_worker_func(array $job, array $includes_map, bool $force, bool $verbose) : array { global $CONFIG_INIT_WORKER_FUNC; if(is_callable($CONFIG_INIT_WORKER_FUNC)) @@ -454,19 +619,19 @@ function _config_worker_func(array $job, array $includes_map, $force, $verbose) return $results; } -function _config_invalidate_cache($file, $cache_file) : ConfigCacheEntry +function _config_invalidate_cache(string $file, string $cache_file) : ConfigCacheEntry { $cache_payload_file = config_get_cache_payload_path($file); //TODO: pass it from above? $base_dir = config_map_base_dir($file); - list($proto_id, $_) = config_ensure_header($base_dir, $file); - if(!$proto_id) - throw new Exception("Bad proto_id: {$proto_id}"); + list($conf_id, $_) = config_ensure_header($base_dir, $file); + if(!$conf_id) + throw new Exception("Bad conf id: {$conf_id}"); $GLOBALS['CONFIG_CURRENT_FILE'] = $file; - $GLOBALS['CONFIG_CURRENT_PROTO_ID'] = $proto_id; + $GLOBALS['CONFIG_CURRENT_PROTO_ID'] = $conf_id; $GLOBALS['CONFIG_EXTRAS'] = ConfigCacheEntryExtras::create(); $pres = config_parse(config_base_dirs(), $file); @@ -475,7 +640,7 @@ function _config_invalidate_cache($file, $cache_file) : ConfigCacheEntry $includes = config_get_module_includes($pres->jsm_module); - $config = config_load_ex($base_dir, $file, $pres->parsed_arr, $proto_id); + $config = config_load_ex($base_dir, $file, $pres->parsed_arr, $conf_id); $payload_data = config_msgpack_pack($config->export()); $cache_entry = new ConfigCacheEntry(); @@ -497,61 +662,61 @@ function _config_invalidate_cache($file, $cache_file) : ConfigCacheEntry return $cache_entry; } -function config_find_by_alias(ConfigFetchResult $cache_entries, $strid) : ConfigCacheEntry +function config_find_by_alias(ConfigFetchResult $cache_entries, string $strid) : ConfigCacheEntry { if(array_key_exists($strid, $cache_entries->by_alias)) return $cache_entries->by_alias[$strid]; throw new Exception("Failed to find config by alias '$strid'!"); } -function config_find_by_id(ConfigFetchResult $cache_entries, $id) : ConfigCacheEntry +function config_find_by_id(ConfigFetchResult $cache_entries, int $id) : ConfigCacheEntry { if(array_key_exists($id, $cache_entries->by_id)) return $cache_entries->by_id[$id]; throw new Exception("Failed to find config by id '$id'!"); } -function config_find_by_path(ConfigFetchResult $cache_entries, $path) : ConfigCacheEntry +function config_find_by_path(ConfigFetchResult $cache_entries, string $path) : ConfigCacheEntry { if(array_key_exists($path, $cache_entries->by_path)) return $cache_entries->by_path[$path]; throw new Exception("Failed to find config by path '$path'!"); } -function config_fetch_by_path(string $path, $force_stale = false) : ConfigCacheEntry +function config_fetch_by_path(string $path, bool $force_stale = false) : ConfigCacheEntry { $ces = config_fetch_ex(array($path), $force_stale); - if(!$ces) + if(empty($ces->all)) throw new Exception("Config not found at path '$path'"); return $ces->all[0]; } -function config_fetch_all($force_stale = false) +function config_fetch_all(bool $force_stale = false) : ConfigFetchResult { return config_fetch_ex(config_scan_files(), $force_stale); } class ConfigCacheEntryExtras { - private static $klass = ConfigCacheEntryExtras::class; + private static string $klass = ConfigCacheEntryExtras::class; - static function init($project_specific_klass) + static function init(string $project_specific_klass) { self::$klass = $project_specific_klass; } - static function create() + static function create() : object { return new self::$klass(); } - function export() + function export() : array { $as_array = get_object_vars($this); return $as_array; } - function import($as_array) + function import(array $as_array) { foreach($as_array as $field_name => $field_value) $this->$field_name = $field_value; @@ -568,28 +733,28 @@ class ConfigCacheEntry const FMT_LZ4 = 1; const FMT_FILE_REF = 2; - public $class; - public $class_id; - public $id; - public $strid; - public $cache_file; + public string $class; + public int $class_id; + public int $id; + public string $strid; + public string $cache_file; //NOTE: actual payload is stored in a separate file for faster incremental retrievals - public $payload_file; - public $file; - public $includes = array(); - public $refs = array(); - public $extras; + public string $payload_file; + public string $file; + public array $includes = array(); + public array $refs = array(); + public object $extras; public $_config; public $_payload; - static function serialize($ce) + static function serialize(ConfigCacheEntry $ce) : string { $d = $ce->export(); return serialize($d); } - static function unserialize($str) + static function unserialize(string $str) : ?ConfigCacheEntry { $d = @unserialize($str); if(!is_array($d)) @@ -604,7 +769,7 @@ class ConfigCacheEntry $this->extras = ConfigCacheEntryExtras::create(); } - function __get($name) + function __get(string $name) { if($name === "config") { @@ -627,7 +792,7 @@ class ConfigCacheEntry throw new Exception("No such property '$name'"); } - function __set($name, $v) + function __set(string $name, $v) { if($name === "config") $this->_config = $v; @@ -637,7 +802,7 @@ class ConfigCacheEntry throw new Exception("No such property '$name'"); } - function export() + function export() : array { $d = array(); $d[] = $this->class; @@ -674,27 +839,17 @@ class ConfigCacheEntry } } -function config_get_cache_path($file) +function config_get_cache_path(string $file) : string { return config_get_tmp_build_path($file . '.cacheb'); } -function config_get_cache_payload_path($file) +function config_get_cache_payload_path(string $file) : string { return config_get_tmp_build_path($file . '.pdata'); } -function config_get_id($conf_dir, $file_path) -{ - return config_file2id($conf_dir, $file_path); -} - -function config_get_strid($conf_dir, $file_path) -{ - return config_file2strid($conf_dir, $file_path); -} - -function config_extract_refs($src, $as_map = true) +function config_extract_refs(string $src, bool $as_map = true) : array { $refs = array(); if(preg_match_all('~"(@[^"]+)"~', $src, $matches)) @@ -709,7 +864,7 @@ function config_extract_refs($src, $as_map = true) return $as_map ? $refs : array_keys($refs); } -function config_get_header($file, &$proto_id, &$alias) +function config_get_header(string $file, ?int &$conf_id, ?string &$strid) : bool { $h = fopen($file, "r"); $line = fgets($h, 256); @@ -717,33 +872,33 @@ function config_get_header($file, &$proto_id, &$alias) if(preg_match('~\{\s*/\*\s*proto_id\s*=\s*(\d+)\s*;\s*alias\s*=\s*([^\s]+)~', $line, $matches)) { - $proto_id = (int)$matches[1]; - $alias = $matches[2]; + $conf_id = (int)$matches[1]; + $strid = $matches[2]; return true; } else return false; } -function config_set_header($contents, $proto_id, $alias, &$is_success) +function config_set_header(string $contents, int $conf_id, string $strid, bool &$is_success) : string { - $contents = preg_replace('~\s*\{~', "{ /* proto_id = {$proto_id} ; alias = {$alias} */", $contents, 1/*limit*/, $count); + $contents = preg_replace('~\s*\{~', "{ /* proto_id = {$conf_id} ; alias = {$strid} */", $contents, 1/*limit*/, $count); $is_success = $count == 1; return $contents; } -function config_extract_header($contents) +function config_extract_header(string $contents) : string { return preg_replace('~(\s*\{)\s*/\*\s*proto_id\s*=\s*\d+\s*;\s*alias\s*=\s*[^\s]+\s*\*/~', '$1', $contents); } -function config_ensure_header($conf_dir, $file, $force = false) +function config_ensure_header(string $conf_dir, string $file, bool $force = false) : array { if(config_get_header($file, $curr_proto_id, $curr_alias)) { - $alias = config_get_strid($conf_dir, $file); + $alias = config_file2strid($conf_dir, $file); if($force) - $curr_proto_id = config_get_id($conf_dir, $file); + $curr_proto_id = config_file2id($conf_dir, $file); //NOTE: keeping current proto id intact if not forced if($force || $curr_alias !== $alias) @@ -760,34 +915,34 @@ function config_ensure_header($conf_dir, $file, $force = false) } else { - $proto_id = config_get_id($conf_dir, $file); - $alias = config_get_strid($conf_dir, $file); + $conf_id = config_file2id($conf_dir, $file); + $alias = config_file2strid($conf_dir, $file); $lines = file($file); - $lines[0] = config_set_header($lines[0], $proto_id, $alias, $is_success); + $lines[0] = config_set_header($lines[0], $conf_id, $alias, $is_success); if(!$is_success) throw new Exception("Could not set header for '$file' in line: {$lines[0]}"); ensure_write($file, join("", $lines)); - return array($proto_id, $alias); + return array($conf_id, $alias); } } -function config_load($conf_dir, $conf_path) +function config_load(string $conf_dir, string $conf_path) : object { - list($proto_id, $_) = config_ensure_header($conf_dir, $conf_path); - if(!$proto_id) - throw new Exception("Bad proto_id: {$proto_id}"); + list($conf_id, $_) = config_ensure_header($conf_dir, $conf_path); + if(!$conf_id) + throw new Exception("Bad conf id: {$conf_id}"); - $pres = config_parse($conf_dir, $conf_path); + $pres = config_parse(array($conf_dir), $conf_path); if($pres->error !== 0) throw new Exception("Error({$pres->error}) while loading JSON from {$conf_path}:\n" . $pres->error_descr); - return config_load_ex($conf_dir, $conf_path, $pres->parsed_arr, $proto_id); + return config_load_ex($conf_dir, $conf_path, $pres->parsed_arr, $conf_id); } -function conf2json($conf, $json_flags = 0) +function conf2json($conf, int $json_flags = 0) { $arr = $conf->export(true); $arr['class'] = get_class($conf); @@ -800,14 +955,14 @@ function conf2json($conf, $json_flags = 0) class ConfigParseResult { - public $error = 0; - public $error_descr; - public $normalized_jzon = ''; - public $parsed_arr; + public int $error = 0; + public string $error_descr; + public string $normalized_jzon = ''; + public array $parsed_arr; public $jsm_module; } -function config_parse(array $base_dirs, $file) : ConfigParseResult +function config_parse(array $base_dirs, string $file) : ConfigParseResult { $res = new ConfigParseResult(); @@ -841,7 +996,7 @@ function config_parse(array $base_dirs, $file) : ConfigParseResult return $res; } -function config_check_and_decode_jzon($json) +function config_check_and_decode_jzon(string $json) : array { try { @@ -854,7 +1009,7 @@ function config_check_and_decode_jzon($json) } } -function config_load_ex($conf_dir, $file, array $arr, $id = null) +function config_load_ex(string $conf_dir, string $file, array $arr, ?int $id = null) : object { if(!isset($arr['class']) || !isset($arr['class'][0])) throw new Exception("Class is not set in file '$file'."); @@ -887,18 +1042,18 @@ function config_load_ex($conf_dir, $file, array $arr, $id = null) return $cnf; } -function config_is_file($filename) +function config_is_file(string $filename) : bool { return (strrpos($filename, '.conf.js') === (strlen($filename) - 8)); } -function config_file2id($conf_dir, $filename) +function config_file2id(string $conf_dir, string $filename) : int { $nfilename = config_make_path($conf_dir, $filename); return config_crc28($nfilename); } -function config_file2strid($conf_dir, $filename) +function config_file2strid(string $conf_dir, string $filename) : string { $strid = config_make_path($conf_dir, $filename); $fname_idx = strrpos($strid, "/"); @@ -907,7 +1062,7 @@ function config_file2strid($conf_dir, $filename) return "@".$strid; } -function config_make_path($conf_dir, $path) +function config_make_path(string $conf_dir, string $path) : string { return ltrim(str_replace(normalize_path($conf_dir, true/*nix*/), '', @@ -915,19 +1070,12 @@ function config_make_path($conf_dir, $path) '/'); } -function config_str2id($str) -{ - if(strpos($str, '@') === 0) - $str = substr($str, 1) . '.conf.js'; - return config_crc28($str); -} - -function config_crc28($what) +function config_crc28(string $what) : int { return crc32($what) & 0xFFFFFFF; } -function config_get_module_includes(\JSM_Module $cm) +function config_get_module_includes(\JSM_Module $cm) : array { $includes = array(); foreach($cm->getIncludes() as $include => $_) @@ -940,7 +1088,7 @@ function config_get_module_includes(\JSM_Module $cm) return $includes; } -function config_includes_map_find_text_origin(array $map, $file, $text) +function config_includes_map_find_text_origin(array $map, string $file, string $text) : array { if(!isset($map[$file])) return array($file); @@ -959,24 +1107,13 @@ function config_includes_map_find_text_origin(array $map, $file, $text) return $res; } -function config_str_replace_in_files($subj, $repl, array $files) -{ - foreach($files as $file) - { - $contents = ensure_read($file); - $new_contents = str_replace($subj, $repl, $contents); - if($new_contents !== $contents) - ensure_write($file, $new_contents); - } -} - -function config_str_ends_with($haystack, $needle) +function config_str_ends_with(string $haystack, string $needle) : bool { // search forward starting from end minus needle length characters return $needle === "" || (($temp = strlen($haystack) - strlen($needle)) >= 0 && strpos($haystack, $needle, $temp) !== false); } -function config_walk_fields($proto, $callback) +function config_walk_fields($proto, callable $callback) { if(!method_exists($proto, 'CLASS_FIELDS_PROPS')) return; @@ -1001,7 +1138,7 @@ function config_walk_fields($proto, $callback) if(function_exists('msgpack_pack')) { - function config_msgpack_pack($data) + function config_msgpack_pack(array $data) : string { $prev = ini_set('msgpack.use_str8_serialization', '0'); $res = msgpack_pack($data); @@ -1010,14 +1147,14 @@ if(function_exists('msgpack_pack')) return $res; } - function config_msgpack_unpack($data) + function config_msgpack_unpack(string $data) : array { return msgpack_unpack($data); } } else { - function config_msgpack_pack($data) + function config_msgpack_pack(array $data) : string { include_once(__DIR__ . '/msgpack/msgpack_custom.inc.php'); @@ -1025,7 +1162,7 @@ else return $packer->pack($data); } - function config_msgpack_unpack($data) + function config_msgpack_unpack(string $data) : array { return \MessagePack\MessagePack::unpack($data); }