Completed
Push — master ( a43f74...38a66f )
by Ben
02:27
created

ObjectWriter   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 205
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 24
c 1
b 0
f 0
lcom 1
cbo 1
dl 0
loc 205
rs 10

14 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A writeRawLine() 0 9 2
A startDictionary() 0 5 1
A endDictionary() 0 5 1
A startArray() 0 5 1
A endArray() 0 5 1
A writeNull() 0 5 1
A writeBoolean() 0 5 2
A writeNumber() 0 16 3
A writeName() 0 5 1
A writeLiteralString() 0 9 1
A writeHexadecimalString() 0 5 1
A close() 0 4 1
C writeData() 0 24 7
1
<?php
2
/**
3
 * BaconPdf
4
 *
5
 * @link      http://github.com/Bacon/BaconPdf For the canonical source repository
6
 * @copyright 2015 Ben Scholzen (DASPRiD)
7
 * @license   http://opensource.org/licenses/BSD-2-Clause Simplified BSD License
8
 */
9
10
namespace Bacon\Pdf\Writer;
11
12
use Bacon\Pdf\Exception\InvalidArgumentException;
13
use SplFileObject;
14
15
class ObjectWriter
16
{
17
    /**
18
     * @var SplFileObject|null
19
     */
20
    private $fileObject;
21
22
    /**
23
     * @var int
24
     */
25
    private $currentLineLength = 0;
26
27
    /**
28
     * @var bool
29
     */
30
    private $requiresWhitespace = false;
31
32
    /**
33
     * @param SplFileObject $fileObject
34
     */
35
    public function __construct(SplFileObject $fileObject)
36
    {
37
        $this->fileObject = $fileObject;
38
    }
39
40
    /**
41
     * Writes raw data line to the stream.
42
     *
43
     * This method does not obey the normal line length limit, so you have to take care of that yourself. Note that the
44
     * writer may still be on an active line, so take that into account as well.
45
     *
46
     * @param string $data
47
     */
48
    public function writeRawLine($data)
49
    {
50
        if (null === $this->fileObject) {
51
            throw new WriterClosedException('The writer object was closed');
52
        }
53
54
        $this->fileObject->fwrite($data. "\n");
55
        $this->currentLineLength = 0;
56
    }
57
58
    /**
59
     * Starts a dictionary.
60
     */
61
    public function startDictionary()
62
    {
63
        $this->writeData('<<', false);
64
        $this->requiresWhitespace = false;
65
    }
66
67
    /**
68
     * Ends a dictionary.
69
     */
70
    public function endDictionary()
71
    {
72
        $this->writeData('>>', false);
73
        $this->requiresWhitespace = false;
74
    }
75
76
    /**
77
     * Starts an array.
78
     */
79
    public function startArray()
80
    {
81
        $this->writeData('[', false);
82
        $this->requiresWhitespace = false;
83
    }
84
85
    /**
86
     * Ends an array.
87
     */
88
    public function endArray()
89
    {
90
        $this->writeData(']', false);
91
        $this->requiresWhitespace = false;
92
    }
93
94
    /**
95
     * Writes a null value.
96
     */
97
    public function writeNull()
98
    {
99
        $this->writeData('null', true);
100
        $this->requiresWhitespace = true;
101
    }
102
103
    /**
104
     * Writes a boolean.
105
     *
106
     * @param bool $boolean
107
     */
108
    public function writeBoolean($boolean)
109
    {
110
        $this->writeData($boolean ? 'true' : 'false', true);
111
        $this->requiresWhitespace = true;
112
    }
113
114
    /**
115
     * Writes a number.
116
     *
117
     * @param  int|float $number
118
     * @throws InvalidArgumentException
119
     */
120
    public function writeNumber($number)
121
    {
122
        if (is_int($number)) {
123
            $value = (string) $number;
124
        } elseif (is_float($number)) {
125
            $value = sprintf('%F', $number);
126
        } else {
127
            throw new InvalidArgumentException(sprintf(
128
                'Expected int or float, got %s',
129
                gettype($number)
130
            ));
131
        }
132
133
        $this->writeData($value, true);
134
        $this->requiresWhitespace = true;
135
    }
136
137
    /**
138
     * Writes a name.
139
     *
140
     * @param string $name
141
     */
142
    public function writeName($name)
143
    {
144
        $this->writeData('/' . $name, false);
145
        $this->requiresWhitespace = true;
146
    }
147
148
    /**
149
     * Writes a literal string.
150
     *
151
     * The string itself is splitted into multiple lines after 248 characters. We chose that specific limit to avoid
152
     * splitting mutli-byte characters in half.
153
     *
154
     * @param string $string
155
     */
156
    public function writeLiteralString($string)
157
    {
158
        $this->writeData('(' . chunk_split(strtr($string, [
159
            '(' => '\\(',
160
            ')' => '\\)',
161
            '\\' => '\\\\',
162
        ]), 248, "\\\n") . ')', false, "\\\n");
0 ignored issues
show
Unused Code introduced by
The call to ObjectWriter::writeData() has too many arguments starting with '\\ '.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
163
        $this->requiresWhitespace = false;
164
    }
165
166
    /**
167
     * Writes a hexadecimal string.
168
     *
169
     * @param string $string
170
     */
171
    public function writeHexadecimalString($string)
172
    {
173
        $this->writeData('<' . chunk_split(bin2hex($string), 248, "\n") . '>', false, "\n");
0 ignored issues
show
Unused Code introduced by
The call to ObjectWriter::writeData() has too many arguments starting with ' '.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
174
        $this->requiresWhitespace = false;
175
    }
176
177
    /**
178
     * Unsets the file object so it can release the file pointer.
179
     */
180
    public function close()
181
    {
182
        $this->fileObject = null;
183
    }
184
185
    /**
186
     * Writes data to the stream while obeying the maximum line length of 255 characters.
187
     *
188
     * If $this->requiresWhitespace is true, it means that the last token requires a whitespace character in case the
189
     * next token begins with an alphanumeric character. If that is the case, the callee should set $prependWhitespace
190
     * to true, so that a whitespace is appended in that case, which may either be a space or a newline.
191
     *
192
     * @param string $data
193
     * @param bool   $prependWhitespace
194
     */
195
    private function writeData($data, $prependWhitespace)
196
    {
197
        if (null === $this->fileObject) {
198
            throw new WriterClosedException('The writer object was closed');
199
        }
200
201
        $dataSize = strlen($data);
202
203
        if ($this->requiresWhitespace && $prependWhitespace) {
204
            $dataSize += 1;
205
        }
206
207
        if ($this->currentLineLength + $dataSize >= 255) {
208
            $this->fileObject->fwrite("\n");
209
            $this->currentLineLength = 0;
210
            $this->requiresWhitespace = false;
211
            $dataSize -= 1;
212
        } elseif ($this->requiresWhitespace && $prependWhitespace) {
213
            $this->fileObject->fwrite(' ');
214
        }
215
216
        $this->fileObject->fwrite($data);
217
        $this->currentLineLength += $dataSize;
218
    }
219
}
220