Passed
Branch master (f07ed3)
by Nate
02:39
created

JsonElementReader::updateStack()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 24
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 22
CRAP Score 6

Importance

Changes 0
Metric Value
cc 6
eloc 22
nc 6
nop 1
dl 0
loc 24
ccs 22
cts 22
cp 1
crap 6
rs 8.9457
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 Tebru\Gson\Element\JsonArray;
12
use Tebru\Gson\Element\JsonElement;
13
use Tebru\Gson\Element\JsonObject;
14
use Tebru\Gson\Element\JsonPrimitive;
15
use Tebru\Gson\JsonToken;
16
use Tebru\Gson\ReaderContext;
17
18
/**
19
 * Class JsonElementReader
20
 *
21
 * @author Nate Brunette <[email protected]>
22
 */
23
final class JsonElementReader extends JsonReader
24
{
25
    /**
26
     * Constructor
27
     *
28
     * @param JsonElement $jsonElement
29
     * @param ReaderContext $context
30
     */
31 73
    public function __construct(JsonElement $jsonElement, ReaderContext $context)
32
    {
33 73
        $this->payload = $jsonElement;
34 73
        $this->context = $context;
35 73
        $this->updateStack($jsonElement);
36 73
    }
37
38
    /**
39
     * Update internal stack and stack types, appending values
40
     *
41
     * @param JsonElement $jsonElement
42
     */
43 73
    private function updateStack(JsonElement $jsonElement): void
44
    {
45 73
        if ($jsonElement->isJsonObject()) {
46 24
            $this->stack[$this->stackSize] = null;
47 24
            $this->stackTypes[$this->stackSize++] = JsonToken::END_OBJECT;
48 24
            $this->stack[$this->stackSize] = $jsonElement;
49 24
            $this->stackTypes[$this->stackSize++] = JsonToken::BEGIN_OBJECT;
50 67
        } elseif ($jsonElement->isJsonArray()) {
51 16
            $this->stack[$this->stackSize] = null;
52 16
            $this->stackTypes[$this->stackSize++] = JsonToken::END_ARRAY;
53 16
            $this->stack[$this->stackSize] = $jsonElement;
54 16
            $this->stackTypes[$this->stackSize++] = JsonToken::BEGIN_ARRAY;
55 58
        } elseif ($jsonElement->isNumber()) {
56 23
            $this->stack[$this->stackSize] = $jsonElement;
57 23
            $this->stackTypes[$this->stackSize++] = JsonToken::NUMBER;
58 36
        } elseif ($jsonElement->isString()) {
59 27
            $this->stack[$this->stackSize] = $jsonElement;
60 27
            $this->stackTypes[$this->stackSize++] = JsonToken::STRING;
61 11
        } elseif ($jsonElement->isBoolean()) {
62 9
            $this->stack[$this->stackSize] = $jsonElement;
63 9
            $this->stackTypes[$this->stackSize++] = JsonToken::BOOLEAN;
64
        } else {
65 2
            $this->stack[$this->stackSize] = null;
66 2
            $this->stackTypes[$this->stackSize++] = JsonToken::NULL;
67
        }
68 73
    }
69
70
    /**
71
     * Consumes the next token and asserts it's the beginning of a new array
72
     *
73
     * @return void
74
     */
75 15
    public function beginArray(): void
76
    {
77 15
        $this->pathIndices[$this->pathIndex++]++;
78 15
        $this->pathIndices[$this->pathIndex] = -1;
79
80 15
        if ($this->stackTypes[$this->stackSize - 1] !== JsonToken::BEGIN_ARRAY) {
81 1
            $this->assertionFailed(JsonToken::BEGIN_ARRAY);
82
        }
83
84
        /** @var JsonArray $jsonArray */
85 14
        $jsonArray = $this->stack[--$this->stackSize];
86 14
        $size = \count($jsonArray);
87 14
        for ($i = $size - 1; $i >= 0; $i--) {
88 10
            $this->updateStack($jsonArray->get($i));
89
        }
90 14
    }
91
92
    /**
93
     * Consumes the next token and asserts it's the beginning of a new object
94
     *
95
     * @return void
96
     */
97 20
    public function beginObject(): void
98
    {
99 20
        $this->pathIndices[$this->pathIndex++]++;
100 20
        $this->pathIndices[$this->pathIndex] = -1;
101
102 20
        if ($this->stackTypes[$this->stackSize - 1] !== JsonToken::BEGIN_OBJECT) {
103 1
            $this->assertionFailed(JsonToken::BEGIN_OBJECT);
104
        }
105
106
        /** @var JsonObject $jsonObject */
107 19
        $jsonObject = $this->stack[--$this->stackSize];
108 19
        $vars = \array_reverse($jsonObject->getProperties(), true);
109 19
        foreach ($vars as $key => $value) {
110 16
            $this->updateStack($value);
111 16
            $this->stack[$this->stackSize] = $key;
112 16
            $this->stackTypes[$this->stackSize++] = JsonToken::NAME;
113
        }
114 19
    }
115
116
    /**
117
     * Consumes the value of the next token, asserts it's a boolean and returns it
118
     *
119
     * @return bool
120
     */
121 6
    public function nextBoolean(): bool
122
    {
123 6
        $this->pathIndices[$this->pathIndex]++;
124
125 6
        if ($this->stackTypes[$this->stackSize - 1] !== JsonToken::BOOLEAN) {
126 1
            $this->assertionFailed(JsonToken::BOOLEAN);
127
        }
128
129
        /** @var JsonPrimitive $primitive */
130 5
        $primitive = $this->stack[--$this->stackSize];
131
132 5
        return $primitive->asBoolean();
133
    }
134
135
    /**
136
     * Consumes the value of the next token, asserts it's a double and returns it
137
     *
138
     * @return double
139
     */
140 3
    public function nextDouble(): float
141
    {
142 3
        $this->pathIndices[$this->pathIndex]++;
143
144 3
        if ($this->stackTypes[$this->stackSize - 1] !== JsonToken::NUMBER) {
145 1
            $this->assertionFailed(JsonToken::NUMBER);
146
        }
147
148
        /** @var JsonPrimitive $primitive */
149 2
        $primitive = $this->stack[--$this->stackSize];
150
151 2
        return $primitive->asFloat();
152
    }
153
154
    /**
155
     * Consumes the value of the next token, asserts it's an int and returns it
156
     *
157
     * @return int
158
     */
159 6
    public function nextInteger(): int
160
    {
161 6
        $this->pathIndices[$this->pathIndex]++;
162
163 6
        if ($this->stackTypes[$this->stackSize - 1] !== JsonToken::NUMBER) {
164 1
            $this->assertionFailed(JsonToken::NUMBER);
165
        }
166
167
        /** @var JsonPrimitive $primitive */
168 5
        $primitive = $this->stack[--$this->stackSize];
169
170 5
        return $primitive->asInteger();
171
    }
172
173
    /**
174
     * Consumes the value of the next token, asserts it's a string and returns it
175
     *
176
     * @return string
177
     */
178 15
    public function nextString(): string
179
    {
180 15
        $this->pathIndices[$this->pathIndex]++;
181
182 15
        if ($this->stackTypes[$this->stackSize - 1] !== JsonToken::STRING) {
183 2
            if ($this->stackTypes[$this->stackSize - 1] === JsonToken::NAME) {
184 1
                return $this->nextName();
185
            }
186
187 1
            $this->assertionFailed(JsonToken::STRING);
188
        }
189
190
        /** @var JsonPrimitive $primitive */
191 13
        $primitive = $this->stack[--$this->stackSize];
192
193 13
        return $primitive->asString();
194
    }
195
}
196