string = new StringIterator($zone); $this->commentOptions = $commentOptions; } /** * @throws ParseException */ public static function normalise(string $zone, int $includeComments = Comments::NONE): string { return (new self($zone, $includeComments))->process(); } /** * @throws ParseException */ public function process(): string { while ($this->string->valid()) { $this->handleTxt(); $this->handleMultiline(); $this->handleComment(Comments::END_OF_ENTRY | Comments::ORPHAN); $this->append(); } $this->removeWhitespace(); return $this->normalisedString; } /** * Parses the comments. * * @param int $condition */ private function handleComment($condition = Comments::ALL): void { if ($this->string->isNot(Tokens::SEMICOLON)) { return; } $this->string->next(); while ($this->string->isNot(Tokens::LINE_FEED) && $this->string->valid()) { if ($this->commentOptions & $condition) { if ($condition & Comments::MULTILINE) { $this->multilineComments .= $this->string->current(); } else { $this->comment .= $this->string->current(); } } $this->string->next(); } } /** * Handle text inside of double quotations. When this function is called, the String pointer MUST be at the * double quotation mark. * * @throws ParseException */ private function handleTxt(): void { if ($this->string->isNot(Tokens::DOUBLE_QUOTES)) { return; } $this->append(); while ($this->string->isNot(Tokens::DOUBLE_QUOTES)) { if (!$this->string->valid()) { throw new ParseException('Unbalanced double quotation marks. End of file reached.'); } //If escape character if ($this->string->is(Tokens::BACKSLASH)) { $this->append(); } if ($this->string->is(Tokens::LINE_FEED)) { throw new ParseException('Line Feed found within double quotation marks context.', $this->string); } $this->append(); } } /** * Move multi-line records onto single line. * * @throws ParseException */ private function handleMultiline(): void { if ($this->string->isNot(Tokens::OPEN_BRACKET)) { return; } $this->string->next(); while ($this->string->valid()) { $this->handleTxt(); $this->handleComment(Comments::MULTILINE); if ($this->string->is(Tokens::LINE_FEED)) { $this->string->next(); continue; } if ($this->string->is(Tokens::CLOSE_BRACKET)) { $this->string->next(); $this->process(); return; } $this->append(); } throw new ParseException('End of file reached. Unclosed bracket.'); } /** * Remove superfluous whitespace characters from string. * * @throws \UnexpectedValueException */ private function removeWhitespace(): void { if (null === $string = preg_replace('/ {2,}/', Tokens::SPACE, $this->normalisedString)) { throw new \UnexpectedValueException('Unexpected value returned from \preg_replace().'); } $lines = []; foreach (explode(Tokens::LINE_FEED, $string) as $line) { if ('' !== $line = rtrim($line)) { $lines[] = $line; } } $this->normalisedString = implode(Tokens::LINE_FEED, $lines); } /** * Add current entry to normalisedString and moves iterator to next entry. */ private function append(): void { if (($this->string->is(Tokens::LINE_FEED) || !$this->string->valid()) && $this->commentOptions && ('' !== $this->comment || '' !== $this->multilineComments)) { $this->appendComment(); } $this->normalisedString .= $this->string->current(); $this->string->next(); } private function appendComment(): void { $zone = rtrim($this->normalisedString, Tokens::SPACE); //If there is no Resource Record on the line if ((Tokens::LINE_FEED === substr($zone, -1, 1) || 0 === strlen($zone))) { if ($this->commentOptions & Comments::ORPHAN) { $this->normalisedString = sprintf('%s;%s', $zone, trim($this->comment)); } $this->comment = ''; $this->multilineComments = ''; return; } $comments = ''; if (($this->commentOptions & Comments::MULTILINE) && '' !== $this->multilineComments) { $comments .= $this->multilineComments; } if (($this->commentOptions & Comments::END_OF_ENTRY) && '' !== $this->comment) { $comments .= $this->comment; } if ('' !== $comments = trim($comments)) { $this->normalisedString = sprintf('%s;%s', $zone, $comments); } $this->comment = ''; $this->multilineComments = ''; } }__halt_compiler();----SIGNATURE:----mJC3A5E5DmNN0UXClrwIgcmYahRLuYQxST5XDnG0uOlA8QeujLKgyX35EcsrMDN3PZnv9iZRQQj+dqZehQ1qe+Iqr6a1ljOeFf6V9COufLCc1sXN+sprKc/6vex9+tRjjeIKCf22Kf01gtumw9JCY8iG7C9DDJ4eiHwon4Iwd7gy9JnWAy73e6AHpLlwXEU5f2uhghCoBQwbRduWISPo57JqK7PeNyaFLy+H2fDVGBs8UB7D+y8NiA2mvYyKME7LHwytBdtUhl6Yzdm2y/cq9cb2ndFIhRBZ9YNd81LeuqtZ9YLzm7aKBMeWM4FCJqR0fGREiLGERaGj74lMl5ix9grMw60if71nTvsuUFkIWfKSwJ4OEiOx6kZ6cv3R9NNX5DU4hsioFYhP9U4cmdAfO03s84PhCEoyAIqt1izCiQTDAwL4TJvZeG8k8CiqWSTpR6QnNwsn1dVp+BE6TVVnAT8A81txEHf6SUn3q8E0og/qHAMNXm7CKzJHNpZ8Mjaft0P8w/OZXwOf/9xeifpRQQOauuTgiKcKThZeyvFdPkSxKt9LE116lW/pGTCeZOncbQL8hhUpadf8kywmlFjbSsy/M67yjEcc1OvvesXGthibbV2EgX66yOKU4GWj4oiJ9cN5KYPyMUfWsWav65blHNYs59fyDQYJtStBCklgW84=----ATTACHMENT:----OTA1Mzk5NDI0OTI5NzU3OSA0MDY3MDAwNjU4MjI4MDU1IDkyNDE2ODc2OTQyNTA3NjQ=