Normaliser   A
last analyzed

Complexity

Total Complexity 23

Size/Duplication

Total Lines 158
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 23
eloc 50
dl 0
loc 158
ccs 59
cts 59
cp 1
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A process() 0 12 2
A removeWhitespace() 0 11 3
A handleTxt() 0 23 6
A handleComment() 0 8 4
A handleMultiline() 0 26 5
A normalise() 0 3 1
A append() 0 4 1
A __construct() 0 6 1
1
<?php
2
3
/*
4
 * This file is part of Badcow DNS Library.
5
 *
6
 * (c) Samuel Williams <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Badcow\DNS\Parser;
13
14
class Normaliser
15
{
16
    /**
17
     * @var StringIterator
18
     */
19
    private $string;
20
21
    /**
22
     * @var string
23
     */
24
    private $normalisedString = '';
25
26
    /**
27
     * Normaliser constructor.
28
     *
29
     * @param string $zone
30
     */
31 12
    public function __construct(string $zone)
32
    {
33
        //Remove Windows line feeds and tabs
34 12
        $zone = str_replace([Tokens::CARRIAGE_RETURN, Tokens::TAB], ['', Tokens::SPACE], $zone);
35
36 12
        $this->string = new StringIterator($zone);
37 12
    }
38
39
    /**
40
     * @param string $zone
41
     *
42
     * @return string
43
     *
44
     * @throws ParseException
45
     */
46 12
    public static function normalise(string $zone): string
47
    {
48 12
        return (new self($zone))->process();
49
    }
50
51
    /**
52
     * @return string
53
     *
54
     * @throws ParseException
55
     */
56 12
    public function process(): string
57
    {
58 12
        while ($this->string->valid()) {
59 12
            $this->handleTxt();
60 12
            $this->handleComment();
61 12
            $this->handleMultiline();
62 12
            $this->append();
63
        }
64
65 9
        $this->removeWhitespace();
66
67 9
        return $this->normalisedString;
68
    }
69
70
    /**
71
     * Ignores the comment section.
72
     */
73 12
    private function handleComment(): void
74
    {
75 12
        if ($this->string->isNot(Tokens::SEMICOLON)) {
76 12
            return;
77
        }
78
79 8
        while ($this->string->isNot(Tokens::LINE_FEED) && $this->string->valid()) {
80 8
            $this->string->next();
81
        }
82 8
    }
83
84
    /**
85
     * Handle text inside of double quotations. When this function is called, the String pointer MUST be at the
86
     * double quotation mark.
87
     *
88
     * @throws ParseException
89
     */
90 12
    private function handleTxt(): void
91
    {
92 12
        if ($this->string->isNot(Tokens::DOUBLE_QUOTES)) {
93 12
            return;
94
        }
95
96 7
        $this->append();
97
98 7
        while ($this->string->isNot(Tokens::DOUBLE_QUOTES)) {
99 7
            if (!$this->string->valid()) {
100 1
                throw new ParseException('Unbalanced double quotation marks. End of file reached.');
101
            }
102
103
            //If escape character
104 7
            if ($this->string->is(Tokens::BACKSLASH)) {
105 5
                $this->append();
106
            }
107
108 7
            if ($this->string->is(Tokens::LINE_FEED)) {
109 1
                throw new ParseException('Line Feed found within double quotation marks context.', $this->string);
110
            }
111
112 7
            $this->append();
113
        }
114 5
    }
115
116
    /**
117
     * Move multi-line records onto single line.
118
     *
119
     * @throws ParseException
120
     */
121 12
    private function handleMultiline(): void
122
    {
123 12
        if ($this->string->isNot(Tokens::OPEN_BRACKET)) {
124 12
            return;
125
        }
126
127 6
        $this->string->next();
128 6
        while ($this->string->valid()) {
129 6
            $this->handleTxt();
130 6
            $this->handleComment();
131
132 6
            if ($this->string->is(Tokens::LINE_FEED)) {
133 6
                $this->string->next();
134 6
                continue;
135
            }
136
137 6
            if ($this->string->is(Tokens::CLOSE_BRACKET)) {
138 5
                $this->string->next();
139
140 5
                return;
141
            }
142
143 6
            $this->append();
144
        }
145
146 1
        throw new ParseException('End of file reached. Unclosed bracket.');
147
    }
148
149
    /**
150
     * Remove superfluous whitespace characters from string.
151
     */
152 9
    private function removeWhitespace(): void
153
    {
154 9
        $string = preg_replace('/ {2,}/', Tokens::SPACE, $this->normalisedString);
155 9
        $lines = [];
156
157 9
        foreach (explode(Tokens::LINE_FEED, $string) as $line) {
158 9
            if ('' !== $line = trim($line)) {
159 9
                $lines[] = $line;
160
            }
161
        }
162 9
        $this->normalisedString = implode(Tokens::LINE_FEED, $lines);
163 9
    }
164
165
    /**
166
     * Add current entry to normalisedString and moves iterator to next entry.
167
     */
168 12
    private function append()
169
    {
170 12
        $this->normalisedString .= $this->string->current();
171 12
        $this->string->next();
172 12
    }
173
}
174