Passed
Pull Request — master (#716)
by Konrad
03:03
created

ElementString::parse()   B

Complexity

Conditions 7
Paths 6

Size

Total Lines 48
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 33
CRAP Score 7

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 7
eloc 35
nc 6
nop 3
dl 0
loc 48
rs 8.4266
c 2
b 0
f 0
ccs 33
cts 33
cp 1
crap 7
1
<?php
2
3
/**
4
 * @file
5
 *          This file is part of the PdfParser library.
6
 *
7
 * @author  Sébastien MALOT <[email protected]>
8
 *
9
 * @date    2017-01-03
10
 *
11
 * @license LGPLv3
12
 *
13
 * @url     <https://github.com/smalot/pdfparser>
14
 *
15
 *  PdfParser is a pdf library written in PHP, extraction oriented.
16
 *  Copyright (C) 2017 - Sébastien MALOT <[email protected]>
17
 *
18
 *  This program is free software: you can redistribute it and/or modify
19
 *  it under the terms of the GNU Lesser General Public License as published by
20
 *  the Free Software Foundation, either version 3 of the License, or
21
 *  (at your option) any later version.
22
 *
23
 *  This program is distributed in the hope that it will be useful,
24
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
25
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26
 *  GNU Lesser General Public License for more details.
27
 *
28
 *  You should have received a copy of the GNU Lesser General Public License
29
 *  along with this program.
30
 *  If not, see <http://www.pdfparser.org/sites/default/LICENSE.txt>.
31
 */
32
33
namespace Smalot\PdfParser\Element;
34
35
use Smalot\PdfParser\Document;
36
use Smalot\PdfParser\Element;
37
use Smalot\PdfParser\Font;
38
39
/**
40
 * Class ElementString
41
 */
42
class ElementString extends Element
43
{
44 80
    public function __construct($value)
45
    {
46 80
        parent::__construct($value, null);
47
    }
48
49 2
    public function equals($value): bool
50
    {
51 2
        return $value == $this->value;
52
    }
53
54
    /**
55
     * Part of parsing process to handle escaped characters.
56
     * Note, most parameters are passed by reference.
57
     *
58
     * Further information in PDF specification (page 53):
59
     * https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/pdfreference1.7old.pdf
60
     */
61 34
    private static function handleEscapedCharacters(string &$name, int &$position, string &$processedName, string $char): void
62
    {
63
        // escaped chars
64 34
        $nextChar = substr($name, 0, 1);
65
        switch ($nextChar) {
66
            // end-of-line markers (CR, LF, CRLF) should be ignored
67 34
            case "\r":
68 32
            case "\n":
69 3
                preg_match('/^\\r?\\n?/', $name, $matches);
70 3
                $name = substr($name, \strlen($matches[0]));
71 3
                $position += \strlen($matches[0]);
72 3
                break;
73
                // process LF, CR, HT, BS, FF
74 31
            case 'n':
75 31
            case 't':
76 31
            case 'r':
77 30
            case 'b':
78 30
            case 'f':
79 1
                $processedName .= stripcslashes('\\'.$nextChar);
80 1
                $name = substr($name, 1);
81 1
                ++$position;
82 1
                break;
83
                // decode escaped parentheses and backslash
84 30
            case '(':
85 30
            case ')':
86 20
            case '\\':
87 19
            case ' ': // TODO: this should probably be removed - kept for compatibility
88 14
                $processedName .= $nextChar;
89 14
                $name = substr($name, 1);
90 14
                ++$position;
91 14
                break;
92
                // TODO: process octal encoding (but it is also processed later)
93
                // keep backslash in other cases
94
            default:
95 19
                $processedName .= $char;
96
        }
97
    }
98
99
    /**
100
     * @return bool|ElementString
101
     */
102 72
    public static function parse(string $content, ?Document $document = null, int &$offset = 0)
0 ignored issues
show
Unused Code introduced by
The parameter $document is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

102
    public static function parse(string $content, /** @scrutinizer ignore-unused */ ?Document $document = null, int &$offset = 0)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
103
    {
104 72
        if (preg_match('/^\s*\((?P<name>.*)/s', $content, $match)) {
105 69
            $name = $match['name'];
106
107 69
            $delimiterCount = 0;
108 69
            $position = 0;
109 69
            $processedName = '';
110
            do {
111 69
                $char = substr($name, 0, 1);
112 69
                $name = substr($name, 1);
113 69
                ++$position;
114
                switch ($char) {
115
                    // matched delimiters should be treated as part of string
116 69
                    case '(':
117 4
                        $processedName .= $char;
118 4
                        ++$delimiterCount;
119 4
                        break;
120 69
                    case ')':
121 69
                        if (0 === $delimiterCount) {
122 69
                            $name = substr($name, 1);
0 ignored issues
show
Unused Code introduced by
The assignment to $name is dead and can be removed.
Loading history...
123 69
                            break 2;
124
                        }
125 4
                        $processedName .= $char;
126 4
                        --$delimiterCount;
127 4
                        break;
128 69
                    case '\\':
129 34
                        self::handleEscapedCharacters($name, $position, $processedName, $char);
130 34
                        break;
131
                    default:
132 69
                        $processedName .= $char;
133
                }
134 69
            } while ('' !== $name);
135
136 69
            $offset += strpos($content, '(') + 1 + $position;
137
138 69
            $name = $processedName;
139
140
            // Decode string.
141 69
            $name = Font::decodeOctal($name);
142 69
            $name = Font::decodeEntities($name);
143 69
            $name = Font::decodeHexadecimal($name, false);
144 69
            $name = Font::decodeUnicode($name);
145
146 69
            return new self($name);
147
        }
148
149 21
        return false;
150
    }
151
}
152