Passed
Pull Request — master (#26)
by Nate
07:26
created

JsonEncodeWriter::topIsObjectStart()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8

Duplication

Lines 8
Ratio 100 %

Code Coverage

Tests 4
CRAP Score 3

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 8
loc 8
ccs 4
cts 4
cp 1
rs 10
cc 3
nc 3
nop 0
crap 3
1
<?php
2
/*
3
 * Copyright (c) Nate Brunette.
4
 * Distributed under the MIT License (http://opensource.org/licenses/MIT)
5
 */
6
7
declare(strict_types=1);
8
9
namespace Tebru\Gson\Internal;
10
11
use LogicException;
12
use stdClass;
13
use Tebru\Gson\JsonWritable;
14
15
/**
16
 * Class JsonEncodeWriter
17
 *
18
 * @author Nate Brunette <[email protected]>
19
 */
20
final class JsonEncodeWriter implements JsonWritable
21
{
22
    /**
23
     * True if we should serialize nulls
24
     *
25
     * @var bool
26
     */
27
    private $serializeNull = false;
28
29
    /**
30
     * Stack of values to be written
31
     *
32
     * @var array
33
     */
34
    private $stack = [];
35
36
    /**
37
     * Size of the stack array
38
     *
39
     * @var int
40
     */
41
    private $stackSize = 0;
42
43
    /**
44
     * A cache of the parsing state corresponding to the stack
45
     *
46
     * @var int[]
47
     */
48
    private $stackStates = [];
49
50
    /**
51
     * When serializing an object, store the name that should be serialized
52
     *
53
     * @var
54
     */
55
    private $pendingName;
56
57
    /**
58
     * The final result that will be json encoded
59
     *
60
     * @var mixed
61
     */
62
    private $result;
63
    
64
    /**
65
     * Begin writing array
66
     *
67
     * @return JsonWritable
68
     * @throws \LogicException
69
     */
70 6 View Code Duplication
    public function beginArray(): JsonWritable
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
71
    {
72 6
        if ($this->stackSize > 0 && $this->stackStates[$this->stackSize - 1] === self::STATE_OBJECT_NAME) {
73 1
            throw new LogicException('Cannot call beginArray() before name() during object serialization');
74
        }
75
76 5
        $array = [];
77 5
        $this->push($array);
78 5
        $this->stack[$this->stackSize] = &$array;
79 5
        $this->stackStates[$this->stackSize] = self::STATE_ARRAY;
80 5
        $this->stackSize++;
81
82 5
        return $this;
83
    }
84
85
    /**
86
     * End writing array
87
     *
88
     * @return JsonWritable
89
     * @throws \LogicException
90
     */
91 4 View Code Duplication
    public function endArray(): JsonWritable
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
92
    {
93 4
        if ($this->stackSize === 0 || $this->stackStates[$this->stackSize - 1] !== self::STATE_ARRAY) {
94 2
            throw new LogicException('Cannot call endArray() if not serializing array');
95
        }
96
97 2
        \array_pop($this->stack);
98 2
        $this->stackSize--;
99
100 2
        return $this;
101
    }
102
103
    /**
104
     * Begin writing object
105
     *
106
     * @return JsonWritable
107
     * @throws \LogicException
108
     */
109 16 View Code Duplication
    public function beginObject(): JsonWritable
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
110
    {
111 16
        if ($this->stackSize > 0 && $this->stackStates[$this->stackSize - 1] === self::STATE_OBJECT_NAME) {
112 1
            throw new LogicException('Cannot call beginObject() before name() during object serialization');
113
        }
114
115 16
        $class = new stdClass();
116 16
        $this->push($class);
117 16
        $this->stack[$this->stackSize] = $class;
118 16
        $this->stackStates[$this->stackSize] = self::STATE_OBJECT_NAME;
119 16
        $this->stackSize++;
120
121 16
        return $this;
122
    }
123
124
    /**
125
     * End writing object
126
     *
127
     * @return JsonWritable
128
     * @throws \LogicException
129
     */
130 6 View Code Duplication
    public function endObject(): JsonWritable
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
131
    {
132 6
        if ($this->stackSize === 0 || $this->stackStates[$this->stackSize - 1] !== self::STATE_OBJECT_NAME) {
133 2
            throw new LogicException('Cannot call endObject() if not serializing object');
134
        }
135
136 4
        \array_pop($this->stack);
137 4
        $this->stackSize--;
138
139 4
        return $this;
140
    }
141
142
    /**
143
     * Writes a property name
144
     *
145
     * @param string $name
146
     * @return JsonWritable
147
     * @throws \LogicException
148
     */
149 5 View Code Duplication
    public function name(string $name): JsonWritable
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
150
    {
151 5
        if ($this->stackStates[$this->stackSize - 1] !== self::STATE_OBJECT_NAME) {
152 1
            throw new LogicException('Cannot call name() at this point.  Either name() has already been called or object serialization has not been started');
153
        }
154
155 5
        $this->pendingName = $name;
156 5
        $this->stackStates[$this->stackSize - 1] = self::STATE_OBJECT_VALUE;
157
158 5
        return $this;
159
    }
160
161
    /**
162
     * Write an integer value
163
     *
164
     * @param int $value
165
     * @return JsonWritable
166
     * @throws \LogicException
167
     */
168 4 View Code Duplication
    public function writeInteger(int $value): JsonWritable
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
169
    {
170 4
        if ($this->stackSize > 0 && $this->stackStates[$this->stackSize - 1] === self::STATE_OBJECT_NAME) {
171 1
            throw new LogicException('Cannot call writeInteger() before name() during object serialization');
172
        }
173
174 3
        return $this->push($value);
175
    }
176
177
    /**
178
     * Write a float value
179
     *
180
     * @param float $value
181
     * @return JsonWritable
182
     * @throws \LogicException
183
     */
184 3 View Code Duplication
    public function writeFloat(float $value): JsonWritable
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
185
    {
186 3
        if ($this->stackSize > 0 && $this->stackStates[$this->stackSize - 1] === self::STATE_OBJECT_NAME) {
187 1
            throw new LogicException('Cannot call writeFloat() before name() during object serialization');
188
        }
189
190 2
        return $this->push($value);
191
    }
192
193
    /**
194
     * Write a string value
195
     *
196
     * @param string $value
197
     * @return JsonWritable
198
     * @throws \LogicException
199
     */
200 4 View Code Duplication
    public function writeString(string $value): JsonWritable
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
201
    {
202 4
        if ($this->stackSize > 0 && $this->stackStates[$this->stackSize - 1] === self::STATE_OBJECT_NAME) {
203 1
            throw new LogicException('Cannot call writeString() before name() during object serialization');
204
        }
205
206 3
        return $this->push($value);
207
    }
208
209
    /**
210
     * Write a boolean value
211
     *
212
     * @param boolean $value
213
     * @return JsonWritable
214
     * @throws \LogicException
215
     */
216 3 View Code Duplication
    public function writeBoolean(bool $value): JsonWritable
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
217
    {
218 3
        if ($this->stackSize > 0 && $this->stackStates[$this->stackSize - 1] === self::STATE_OBJECT_NAME) {
219 1
            throw new LogicException('Cannot call writeBoolean() before name() during object serialization');
220
        }
221
222 2
        return $this->push($value);
223
    }
224
225
    /**
226
     * Write a null value if we are serializing nulls, otherwise
227
     * skip the value.  If this is a property value, that property
228
     * should be skipped as well.
229
     *
230
     * @return JsonWritable
231
     * @throws \LogicException
232
     */
233 5 View Code Duplication
    public function writeNull(): JsonWritable
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
234
    {
235 5
        if ($this->stackSize > 0 && $this->stackStates[$this->stackSize - 1] === self::STATE_OBJECT_NAME) {
236 1
            throw new LogicException('Cannot call writeNull() before name() during object serialization');
237
        }
238
239 4
        if ($this->serializeNull) {
240 2
            $null = null;
241 2
            return $this->push($null);
242
        }
243
244
        // if we're not serializing nulls
245 2
        if (null !== $this->pendingName) {
246 1
            $this->stackStates[$this->stackSize - 1] = self::STATE_OBJECT_NAME;
247 1
            $this->pendingName = null;
248
        }
249
250 2
        return $this;
251
    }
252
253
    /**
254
     * Sets whether nulls are serialized
255
     *
256
     * @param bool $serializeNull
257
     * @return void
258
     */
259 2
    public function setSerializeNull(bool $serializeNull): void
260
    {
261 2
        $this->serializeNull = $serializeNull;
262 2
    }
263
264
    /**
265
     * Convert the writer to json
266
     *
267
     * @return string
268
     */
269 17
    public function __toString(): string
270
    {
271 17
        return \json_encode($this->result);
272
    }
273
274
    /**
275
     * Push a value to the result or current array/object
276
     *
277
     * @param mixed $value
278
     * @return JsonWritable
279
     * @throws \LogicException
280
     */
281 28
    private function push(&$value): JsonWritable
282
    {
283 28 View Code Duplication
        if (0 === $this->stackSize) {
284 28
            if (null !== $this->result) {
285 2
                throw new LogicException('Attempting to write two different types');
286
            }
287
288 28
            $this->result = &$value;
289
290 28
            return $this;
291
        }
292
293 5
        switch ($this->stackStates[$this->stackSize - 1]) {
294 5 View Code Duplication
            case self::STATE_OBJECT_VALUE:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
295 3
                $this->stack[$this->stackSize - 1]->{$this->pendingName} = &$value;
296 3
                $this->stackStates[$this->stackSize - 1] = self::STATE_OBJECT_NAME;
297 3
                $this->pendingName = null;
298 3
                break;
299 2 View Code Duplication
            case self::STATE_ARRAY:
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
300 2
                $this->stack[$this->stackSize - 1][] = &$value;
301 2
                $this->stackStates[$this->stackSize - 1] = self::STATE_ARRAY;
302 2
                break;
303
304
        }
305
306 5
        return $this;
307
    }
308
}
309