Completed
Push — master ( 0d072d...b4f77a )
by Sam
01:59
created

Normaliser::handleMultiline()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 26
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 5

Importance

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