Encoding::init()   B
last analyzed

Complexity

Conditions 7
Paths 10

Size

Total Lines 38
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 7

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 7
eloc 20
c 2
b 0
f 0
nc 10
nop 0
dl 0
loc 38
ccs 21
cts 21
cp 1
crap 7
rs 8.6666
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;
34
35
use Smalot\PdfParser\Element\ElementNumeric;
36
use Smalot\PdfParser\Encoding\EncodingLocator;
37
use Smalot\PdfParser\Encoding\PostScriptGlyphs;
38
use Smalot\PdfParser\Exception\EncodingNotFoundException;
39
40
/**
41
 * Class Encoding
42
 */
43
class Encoding extends PDFObject
44
{
45
    /**
46
     * @var array
47
     */
48
    protected $encoding;
49
50
    /**
51
     * @var array
52
     */
53
    protected $differences;
54
55
    /**
56
     * @var array
57
     */
58
    protected $mapping;
59
60 15
    public function init()
61
    {
62 15
        $this->mapping = [];
63 15
        $this->differences = [];
64 15
        $this->encoding = [];
65
66 15
        if ($this->has('BaseEncoding')) {
67 6
            $this->encoding = EncodingLocator::getEncoding($this->getEncodingClass())->getTranslations();
68
69
            // Build table including differences.
70 5
            $differences = $this->get('Differences')->getContent();
71 5
            $code = 0;
72
73 5
            if (!\is_array($differences)) {
74 3
                return;
75
            }
76
77 2
            foreach ($differences as $difference) {
78
                /** @var ElementNumeric $difference */
79 2
                if ($difference instanceof ElementNumeric) {
80 2
                    $code = $difference->getContent();
81 2
                    continue;
82
                }
83
84
                // ElementName
85 2
                $this->differences[$code] = $difference;
86 2
                if (\is_object($difference)) {
87 2
                    $this->differences[$code] = $difference->getContent();
88
                }
89
90
                // For the next char.
91 2
                ++$code;
92
            }
93
94 2
            $this->mapping = $this->encoding;
95 2
            foreach ($this->differences as $code => $difference) {
96
                /* @var string $difference */
97 2
                $this->mapping[$code] = $difference;
98
            }
99
        }
100
    }
101
102
    public function getDetails(bool $deep = true): array
103
    {
104
        $details = [];
105
106
        $details['BaseEncoding'] = ($this->has('BaseEncoding') ? (string) $this->get('BaseEncoding') : 'Ansi');
107
        $details['Differences'] = ($this->has('Differences') ? (string) $this->get('Differences') : '');
108
109
        $details += parent::getDetails($deep);
110
111
        return $details;
112
    }
113
114 5
    public function translateChar($dec): ?int
115
    {
116 5
        if (isset($this->mapping[$dec])) {
117 2
            $dec = $this->mapping[$dec];
118
        }
119
120 5
        return PostScriptGlyphs::getCodePoint($dec);
121
    }
122
123
    /**
124
     * Returns encoding class name if available or empty string (only prior PHP 7.4).
125
     *
126
     * @throws \Exception On PHP 7.4+ an exception is thrown if encoding class doesn't exist.
127
     */
128 4
    public function __toString(): string
129
    {
130
        try {
131 4
            return $this->getEncodingClass();
132 1
        } catch (\Exception $e) {
133
            // prior to PHP 7.4 toString has to return an empty string.
134 1
            if (version_compare(\PHP_VERSION, '7.4.0', '<')) {
135
                return '';
136
            }
137 1
            throw $e;
138
        }
139
    }
140
141
    /**
142
     * @throws EncodingNotFoundException
143
     */
144 8
    protected function getEncodingClass(): string
145
    {
146
        // Load reference table charset.
147 8
        $baseEncoding = preg_replace('/[^A-Z0-9]/is', '', $this->get('BaseEncoding')->getContent());
148
149
        // Check for empty BaseEncoding field value
150 8
        if (!\is_string($baseEncoding) || 0 == \strlen($baseEncoding)) {
151 1
            $baseEncoding = 'StandardEncoding';
152
        }
153
154 8
        $className = '\\Smalot\\PdfParser\\Encoding\\'.$baseEncoding;
155
156 8
        if (!class_exists($className)) {
157 2
            throw new EncodingNotFoundException('Missing encoding data for: "'.$baseEncoding.'".');
158
        }
159
160 6
        return $className;
161
    }
162
}
163