1<?php declare(strict_types = 1); 2/* 3** Zabbix 4** Copyright (C) 2001-2021 Zabbix SIA 5** 6** This program is free software; you can redistribute it and/or modify 7** it under the terms of the GNU General Public License as published by 8** the Free Software Foundation; either version 2 of the License, or 9** (at your option) any later version. 10** 11** This program is distributed in the hope that it will be useful, 12** but WITHOUT ANY WARRANTY; without even the implied warranty of 13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14** GNU General Public License for more details. 15** 16** You should have received a copy of the GNU General Public License 17** along with this program; if not, write to the Free Software 18** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19**/ 20 21 22/** 23 * A parser for numbers with optional time or byte suffix. 24 */ 25class CNumberParser extends CParser { 26 27 /** 28 * Parser options. 29 * 30 * @var array 31 */ 32 private $options = [ 33 'with_minus' => true, 34 'with_suffix' => false 35 ]; 36 37 /** 38 * Parsed number without time or byte suffix. 39 * 40 * @var string 41 */ 42 private $number; 43 44 /** 45 * Parsed time or byte suffix, or null, if wasn't found. 46 * 47 * @var string|null 48 */ 49 private $suffix; 50 51 /** 52 * Acceptable time and byte suffixes. 53 * 54 * @var string 55 */ 56 private static $suffixes = ZBX_TIME_SUFFIXES.ZBX_BYTE_SUFFIXES; 57 58 /** 59 * Suffix multiplier table for value calculation. 60 * 61 * @var array 62 */ 63 private static $suffix_multipliers = ZBX_BYTE_SUFFIX_MULTIPLIERS + ZBX_TIME_SUFFIX_MULTIPLIERS; 64 65 public function __construct(array $options = []) { 66 $this->options = array_replace($this->options, array_intersect_key($options, $this->options)); 67 } 68 69 /** 70 * Parse number with optional time or byte suffix. 71 * 72 * !!! Don't forget sync code with C !!! 73 * 74 * @param string $source string to parse 75 * @param int $pos position to start from 76 * 77 * @return int 78 */ 79 public function parse($source, $pos = 0): int { 80 $this->length = 0; 81 $this->match = ''; 82 $this->number = null; 83 $this->suffix = null; 84 85 $fragment = substr($source, $pos); 86 87 $pattern = $this->options['with_suffix'] 88 ? '/^'.ZBX_PREG_NUMBER.'(?<suffix>['.self::$suffixes.'])?/' 89 : '/^'.ZBX_PREG_NUMBER.'/'; 90 91 if (!preg_match($pattern, $fragment, $matches)) { 92 return self::PARSE_FAIL; 93 } 94 95 if ($matches['number'][0] === '-' && !$this->options['with_minus']) { 96 return self::PARSE_FAIL; 97 } 98 99 $this->length = strlen($matches[0]); 100 $this->match = $matches[0]; 101 102 $this->number = $matches['number']; 103 $this->suffix = array_key_exists('suffix', $matches) ? $matches['suffix'] : null; 104 105 return ($pos + $this->length < strlen($source)) ? self::PARSE_SUCCESS_CONT : self::PARSE_SUCCESS; 106 } 107 108 /** 109 * Calculate value of parsed number in a decimal notation. 110 * 111 * @return float 112 */ 113 public function calcValue(): float { 114 $number = (float) $this->number; 115 116 if ($this->suffix !== null) { 117 $number *= self::$suffix_multipliers[$this->suffix]; 118 } 119 120 return $number; 121 } 122 123 /** 124 * Get suffix of parsed number. 125 * 126 * @return string|null 127 */ 128 public function getSuffix(): ?string { 129 return $this->suffix; 130 } 131} 132