1<?php
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
22class CSetParser extends CParser {
23
24	/**
25	 * Array of string to search for with strings as keys.
26	 *
27	 * @var array
28	 */
29	private $needles = [];
30
31	/**
32	 * Array of chars that are used in the given strings with chars as keys.
33	 *
34	 * @var array
35	 */
36	private $chars = [];
37
38	/**
39	 * Array of strings to search for.
40	 *
41	 * @param array $needles
42	 */
43	public function __construct(array $needles) {
44		$this->needles = array_flip($needles);
45		$this->chars = array_flip(str_split(implode($needles)));
46	}
47
48	/**
49	 * Find one of the given strings at the given position.
50	 *
51	 * The parser implements a greedy algorithm, i.e., looks for the longest match.
52	 */
53	public function parse($source, $pos = 0) {
54		$this->length = 0;
55		$this->match = '';
56
57		$length = 0;
58		$match = null;
59
60		$token = '';
61		for ($p = $pos; isset($source[$p]) && isset($this->chars[$source[$p]]); $p++) {
62			$token .= $source[$p];
63
64			// when we found a match, keep looking to see of there may be a longer match
65			if (isset($this->needles[$token])) {
66				$length = $p - $pos + 1;
67				$match = $token;
68			}
69		}
70
71		if ($match === null) {
72			return self::PARSE_FAIL;
73		}
74
75		$this->length = $length;
76		$this->match = $match;
77
78		return (isset($source[$pos + $this->length]) ? self::PARSE_SUCCESS_CONT : self::PARSE_SUCCESS);
79	}
80}
81