Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
 
3
/**
4
 * This file is part of FPDI
5
 *
6
 * @package   setasign\Fpdi
7
 * @copyright Copyright (c) 2023 Setasign GmbH & Co. KG (https://www.setasign.com)
8
 * @license   http://opensource.org/licenses/mit-license The MIT License
9
 */
10
 
11
namespace setasign\Fpdi\PdfParser\Type;
12
 
13
use setasign\Fpdi\PdfParser\StreamReader;
14
 
15
/**
16
 * Class representing a PDF string object
17
 */
18
class PdfString extends PdfType
19
{
20
    /**
21
     * Parses a string object from the stream reader.
22
     *
23
     * @param StreamReader $streamReader
24
     * @return self
25
     */
26
    public static function parse(StreamReader $streamReader)
27
    {
28
        $pos = $startPos = $streamReader->getOffset();
29
        $openBrackets = 1;
30
        do {
31
            $buffer = $streamReader->getBuffer(false);
32
            for ($length = \strlen($buffer); $openBrackets !== 0 && $pos < $length; $pos++) {
33
                switch ($buffer[$pos]) {
34
                    case '(':
35
                        $openBrackets++;
36
                        break;
37
                    case ')':
38
                        $openBrackets--;
39
                        break;
40
                    case '\\':
41
                        $pos++;
42
                }
43
            }
44
        } while ($openBrackets !== 0 && $streamReader->increaseLength());
45
 
46
        $result = \substr($buffer, $startPos, $openBrackets + $pos - $startPos - 1);
47
        $streamReader->setOffset($pos);
48
 
49
        $v = new self();
50
        $v->value = $result;
51
 
52
        return $v;
53
    }
54
 
55
    /**
56
     * Helper method to create an instance.
57
     *
58
     * @param string $value The string needs to be escaped accordingly.
59
     * @return self
60
     */
61
    public static function create($value)
62
    {
63
        $v = new self();
64
        $v->value = $value;
65
 
66
        return $v;
67
    }
68
 
69
    /**
70
     * Ensures that the passed value is a PdfString instance.
71
     *
72
     * @param mixed $string
73
     * @return self
74
     * @throws PdfTypeException
75
     */
76
    public static function ensure($string)
77
    {
78
        return PdfType::ensureType(self::class, $string, 'String value expected.');
79
    }
80
 
81
    /**
82
     * Escapes sequences in a string according to the PDF specification.
83
     *
84
     * @param string $s
85
     * @return string
86
     */
87
    public static function escape($s)
88
    {
89
        // Still a bit faster, than direct replacing
90
        if (
91
            \strpos($s, '\\') !== false ||
92
            \strpos($s, ')')  !== false ||
93
            \strpos($s, '(')  !== false ||
94
            \strpos($s, "\x0D") !== false ||
95
            \strpos($s, "\x0A") !== false ||
96
            \strpos($s, "\x09") !== false ||
97
            \strpos($s, "\x08") !== false ||
98
            \strpos($s, "\x0C") !== false
99
        ) {
100
            // is faster than strtr(...)
101
            return \str_replace(
102
                ['\\',   ')',   '(',   "\x0D", "\x0A", "\x09", "\x08", "\x0C"],
103
                ['\\\\', '\\)', '\\(', '\r',   '\n',   '\t',   '\b',   '\f'],
104
                $s
105
            );
106
        }
107
 
108
        return $s;
109
    }
110
 
111
    /**
112
     * Unescapes escaped sequences in a PDF string according to the PDF specification.
113
     *
114
     * @param string $s
115
     * @return string
116
     */
117
    public static function unescape($s)
118
    {
119
        $out = '';
120
        /** @noinspection ForeachInvariantsInspection */
121
        for ($count = 0, $n = \strlen($s); $count < $n; $count++) {
122
            if ($s[$count] !== '\\') {
123
                $out .= $s[$count];
124
            } else {
125
                // A backslash at the end of the string - ignore it
126
                if ($count === ($n - 1)) {
127
                    break;
128
                }
129
 
130
                switch ($s[++$count]) {
131
                    case ')':
132
                    case '(':
133
                    case '\\':
134
                        $out .= $s[$count];
135
                        break;
136
 
137
                    case 'f':
138
                        $out .= "\x0C";
139
                        break;
140
 
141
                    case 'b':
142
                        $out .= "\x08";
143
                        break;
144
 
145
                    case 't':
146
                        $out .= "\x09";
147
                        break;
148
 
149
                    case 'r':
150
                        $out .= "\x0D";
151
                        break;
152
 
153
                    case 'n':
154
                        $out .= "\x0A";
155
                        break;
156
 
157
                    case "\r":
158
                        if ($count !== $n - 1 && $s[$count + 1] === "\n") {
159
                            $count++;
160
                        }
161
                        break;
162
 
163
                    case "\n":
164
                        break;
165
 
166
                    default:
167
                        $actualChar = \ord($s[$count]);
168
                        // ascii 48 = number 0
169
                        // ascii 57 = number 9
170
                        if ($actualChar >= 48 && $actualChar <= 57) {
171
                            $oct = '' . $s[$count];
172
 
173
                            /** @noinspection NotOptimalIfConditionsInspection */
174
                            if (
175
                                $count + 1 < $n
176
                                && \ord($s[$count + 1]) >= 48
177
                                && \ord($s[$count + 1]) <= 57
178
                            ) {
179
                                $count++;
180
                                $oct .= $s[$count];
181
 
182
                                /** @noinspection NotOptimalIfConditionsInspection */
183
                                if (
184
                                    $count + 1 < $n
185
                                    && \ord($s[$count + 1]) >= 48
186
                                    && \ord($s[$count + 1]) <= 57
187
                                ) {
188
                                    $oct .= $s[++$count];
189
                                }
190
                            }
191
 
192
                            $out .= \chr(\octdec($oct));
193
                        } else {
194
                            // If the character is not one of those defined, the backslash is ignored
195
                            $out .= $s[$count];
196
                        }
197
                }
198
            }
199
        }
200
        return $out;
201
    }
202
}