Passed
Push — master ( 95373b...dd07b4 )
by Nate
43s
created

JsonEncodeWriter::setSerializeNull()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
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 stdClass;
12
use Tebru\Gson\JsonWritable;
13
14
/**
15
 * Class JsonEncodeWriter
16
 *
17
 * @author Nate Brunette <[email protected]>
18
 */
19
final class JsonEncodeWriter extends JsonWriter
20
{
21
    /**
22
     * Begin writing array
23
     *
24
     * @return JsonWritable
25
     * @throws \LogicException
26
     */
27 20
    public function beginArray(): JsonWritable
28
    {
29 20
        if ($this->stackSize > 0 && $this->stackStates[$this->stackSize - 1] === self::STATE_OBJECT_NAME) {
30 1
            $this->assertionFailed('Cannot call beginArray() before name() during object serialization');
31
        }
32
33 19
        $array = [];
34 19
        $this->push($array);
35 19
        $this->stack[$this->stackSize] = &$array;
36 19
        $this->stackStates[$this->stackSize] = self::STATE_ARRAY;
37 19
        $this->stackSize++;
38 19
        $this->pathIndices[$this->pathIndex++]++;
39 19
        $this->pathIndices[$this->pathIndex] = -1;
40
41 19
        return $this;
42
    }
43
44
    /**
45
     * End writing array
46
     *
47
     * @return JsonWritable
48
     * @throws \LogicException
49
     */
50 7
    public function endArray(): JsonWritable
51
    {
52 7
        if ($this->stackSize === 0 || $this->stackStates[$this->stackSize - 1] !== self::STATE_ARRAY) {
53 3
            $this->assertionFailed('Cannot call endArray() if not serializing array');
54
        }
55
56 5
        \array_pop($this->stack);
57 5
        $this->stackSize--;
58 5
        $this->pathIndex--;
59
60 5
        return $this;
61
    }
62
63
    /**
64
     * Begin writing object
65
     *
66
     * @return JsonWritable
67
     * @throws \LogicException
68
     */
69 31
    public function beginObject(): JsonWritable
70
    {
71 31
        if ($this->stackSize > 0 && $this->stackStates[$this->stackSize - 1] === self::STATE_OBJECT_NAME) {
72 1
            $this->assertionFailed('Cannot call beginObject() before name() during object serialization');
73
        }
74
75 31
        $class = new stdClass();
76 31
        $this->push($class);
77 31
        $this->stack[$this->stackSize] = $class;
78 31
        $this->stackStates[$this->stackSize] = self::STATE_OBJECT_NAME;
79 31
        $this->stackSize++;
80 31
        $this->pathIndices[$this->pathIndex++]++;
81 31
        $this->pathIndices[$this->pathIndex] = -1;
82
83 31
        return $this;
84
    }
85
86
    /**
87
     * End writing object
88
     *
89
     * @return JsonWritable
90
     * @throws \LogicException
91
     */
92 9
    public function endObject(): JsonWritable
93
    {
94 9
        if ($this->stackSize === 0 || $this->stackStates[$this->stackSize - 1] !== self::STATE_OBJECT_NAME) {
95 2
            $this->assertionFailed('Cannot call endObject() if not serializing object');
96
        }
97
98 7
        \array_pop($this->stack);
99 7
        $this->stackSize--;
100 7
        $this->pathNames[$this->pathIndex--] = null;
101
102 7
        return $this;
103
    }
104
105
    /**
106
     * Write an integer value
107
     *
108
     * @param int $value
109
     * @return JsonWritable
110
     * @throws \LogicException
111
     */
112 16
    public function writeInteger(int $value): JsonWritable
113
    {
114 16
        if ($this->stackSize > 0 && $this->stackStates[$this->stackSize - 1] === self::STATE_OBJECT_NAME) {
115 1
            $this->assertionFailed('Cannot call writeInteger() before name() during object serialization');
116
        }
117
118 15
        $this->pathIndices[$this->pathIndex]++;
119
120 15
        return $this->push($value);
121
    }
122
123
    /**
124
     * Write a float value
125
     *
126
     * @param float $value
127
     * @return JsonWritable
128
     * @throws \LogicException
129
     */
130 4
    public function writeFloat(float $value): JsonWritable
131
    {
132 4
        if ($this->stackSize > 0 && $this->stackStates[$this->stackSize - 1] === self::STATE_OBJECT_NAME) {
133 1
            $this->assertionFailed('Cannot call writeFloat() before name() during object serialization');
134
        }
135
136 3
        $this->pathIndices[$this->pathIndex]++;
137
138 3
        return $this->push($value);
139
    }
140
141
    /**
142
     * Write a string value
143
     *
144
     * @param string $value
145
     * @return JsonWritable
146
     * @throws \LogicException
147
     */
148 8
    public function writeString(string $value): JsonWritable
149
    {
150 8
        if ($this->stackSize > 0 && $this->stackStates[$this->stackSize - 1] === self::STATE_OBJECT_NAME) {
151 1
            $this->assertionFailed('Cannot call writeString() before name() during object serialization');
152
        }
153
154 7
        $this->pathIndices[$this->pathIndex]++;
155
156 7
        return $this->push($value);
157
    }
158
159
    /**
160
     * Write a boolean value
161
     *
162
     * @param boolean $value
163
     * @return JsonWritable
164
     * @throws \LogicException
165
     */
166 5
    public function writeBoolean(bool $value): JsonWritable
167
    {
168 5
        if ($this->stackSize > 0 && $this->stackStates[$this->stackSize - 1] === self::STATE_OBJECT_NAME) {
169 1
            $this->assertionFailed('Cannot call writeBoolean() before name() during object serialization');
170
        }
171
172 4
        $this->pathIndices[$this->pathIndex]++;
173
174 4
        return $this->push($value);
175
    }
176
177
    /**
178
     * Write a null value if we are serializing nulls, otherwise
179
     * skip the value.  If this is a property value, that property
180
     * should be skipped as well.
181
     *
182
     * @return JsonWritable
183
     * @throws \LogicException
184
     */
185 9
    public function writeNull(): JsonWritable
186
    {
187 9
        if ($this->stackSize > 0 && $this->stackStates[$this->stackSize - 1] === self::STATE_OBJECT_NAME) {
188 1
            $this->assertionFailed('Cannot call writeNull() before name() during object serialization');
189
        }
190
191 8
        if ($this->serializeNull) {
192 4
            $this->pathIndices[$this->pathIndex]++;
193 4
            $null = null;
194 4
            return $this->push($null);
195
        }
196
197
        // if we're not serializing nulls
198 4
        if (null !== $this->pendingName) {
199 2
            $this->stackStates[$this->stackSize - 1] = self::STATE_OBJECT_NAME;
200 2
            $this->pendingName = null;
201
        }
202
203 4
        return $this;
204
    }
205
206
    /**
207
     * Convert the writer to json
208
     *
209
     * @return string
210
     */
211 17
    public function __toString(): string
212
    {
213 17
        return \json_encode($this->result);
214
    }
215
216
    /**
217
     * Push a value to the result or current array/object
218
     *
219
     * @param mixed $value
220
     * @return JsonWritable
221
     * @throws \LogicException
222
     */
223 55
    private function push(&$value): JsonWritable
224
    {
225 55
        if (0 === $this->stackSize) {
226 55
            if (null !== $this->result) {
227 2
                $this->assertionFailed('Attempting to write two different types');
228
            }
229
230 55
            $this->result = &$value;
231
232 55
            return $this;
233
        }
234
235 25
        switch ($this->stackStates[$this->stackSize - 1]) {
236 25
            case self::STATE_OBJECT_VALUE:
237 14
                $this->stack[$this->stackSize - 1]->{$this->pendingName} = &$value;
238 14
                $this->stackStates[$this->stackSize - 1] = self::STATE_OBJECT_NAME;
239 14
                $this->pendingName = null;
240 14
                break;
241 14
            case self::STATE_ARRAY:
242 14
                $this->stack[$this->stackSize - 1][] = &$value;
243 14
                $this->stackStates[$this->stackSize - 1] = self::STATE_ARRAY;
244 14
                break;
245
        }
246
247 25
        return $this;
248
    }
249
}
250