Passed
Push — master ( 582175...a293a3 )
by X
01:11
created

Source::next()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Input for parser
4
 */
5
namespace xKerman\Restricted;
6
7
/**
8
 * Parser Input
9
 */
10
class Source
11
{
12
    /** @var string $str given string to deserialize */
13
    private $str;
14
15
    /** @var int $length given string length */
16
    private $length;
17
18
    /** @var int $current current position of parser */
19
    private $current;
20
21
    /**
22
     * constructor
23
     *
24
     * @param string $str parser input
25
     * @throws \InvalidArgumentException
26
     */
27 45
    public function __construct($str)
28
    {
29 45
        if (!is_string($str)) {
30 1
            throw new \InvalidArgumentException('expected string, but got: ' . gettype($str));
31
        }
32 44
        $this->str = $str;
33 44
        $this->length = strlen($str);
34 44
        $this->current = 0;
35 44
    }
36
37
    /**
38
     * throw error with currnt position
39
     *
40
     * @return void
41
     * @throws UnserializeFailedException
42
     */
43 1
    public function triggerError()
44
    {
45 1
        $bytes = strlen($this->str);
46 1
        throw new UnserializeFailedException("unserialize(): Error at offset {$this->current} of {$bytes} bytes");
47
    }
48
49
    /**
50
     * return current character
51
     *
52
     * @return string
53
     */
54 43
    public function peek()
55
    {
56 43
        return substr($this->str, $this->current, 1);
57
    }
58
59
    /**
60
     * consume given string if it is as expected
61
     *
62
     * @param string  $expected expected string
63
     * @param integer $length   length of $expected
64
     * @return void
65
     * @throws UnserializeFailedException
66
     */
67 22
    public function consume($expected, $length)
68
    {
69 22
        if (strpos($this->str, $expected, $this->current) !== $this->current) {
70 1
            return $this->triggerError();
71
        }
72 21
        $this->current += $length;
73 21
    }
74
75
    /**
76
     * read givin length substring
77
     *
78
     * @param integer $length length to read
79
     * @return string
80
     * @throws UnserializeFailedException
81
     */
82 19
    public function read($length)
83
    {
84 19
        if ($length < 0) {
85 1
            return $this->triggerError();
86
        }
87 18
        if ($this->current + $length > $this->length) {
88 1
            return $this->triggerError();
89
        }
90
91 17
        $this->current += $length;
92 17
        return substr($this->str, $this->current - $length, $length);
93
    }
94
95
    /**
96
     * return matching string for given regexp
97
     *
98
     * @param string $regexp Regular Expression for expected substring
99
     * @return string
100
     */
101 43
    public function match($regexp)
102
    {
103 43
        $matched = preg_match($regexp, $this->str, $matches, 0, $this->current);
104 43
        if ($matched === 0 || $matched === false) {
105 1
            return $this->triggerError();
106
        }
107
108 42
        $this->current += strlen($matches[0]);
109 42
        return isset($matches[1]) ? $matches[1] : $matches[0];
110
    }
111
}
112