Passed
Branch master (c5c3fa)
by Nate
03:35
created

JsonElementReader::nextString()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 16
Code Lines 8

Duplication

Lines 16
Ratio 100 %

Code Coverage

Tests 8
CRAP Score 2

Importance

Changes 0
Metric Value
dl 16
loc 16
ccs 8
cts 8
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 8
nc 2
nop 0
crap 2
1
<?php
2
/*
3
 * Copyright (c) Nate Brunette.
4
 * Distributed under the MIT License (http://opensource.org/licenses/MIT)
5
 */
6
7
namespace Tebru\Gson\Internal;
8
9
use ArrayIterator;
10
use Iterator;
11
use Tebru\Gson\Element\JsonArray;
12
use Tebru\Gson\Element\JsonElement;
13
use Tebru\Gson\Element\JsonNull;
14
use Tebru\Gson\Element\JsonObject;
15
use Tebru\Gson\Element\JsonPrimitive;
16
use Tebru\Gson\JsonToken;
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
     */
30 69
    public function __construct(JsonElement $jsonElement)
31
    {
32 69
        $this->push($jsonElement);
33 69
    }
34
35
    /**
36
     * Consumes the next token and asserts it's the beginning of a new array
37
     *
38
     * @return void
39
     * @throws \Tebru\Gson\Exception\UnexpectedJsonTokenException If the next token is not BEGIN_ARRAY
40
     */
41 15 View Code Duplication
    public function beginArray(): void
1 ignored issue
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...
42
    {
43 15
        $this->expect(JsonToken::BEGIN_ARRAY);
44
45
        /** @var JsonArray $jsonArray */
46 14
        $jsonArray = $this->pop();
47 14
        $this->push($jsonArray->getIterator(), ArrayIterator::class);
48 14
        $this->pathIndices[$this->stackSize - 1] = 0;
49 14
    }
50
51
    /**
52
     * Consumes the next token and asserts it's the beginning of a new object
53
     *
54
     * @return void
55
     * @throws \Tebru\Gson\Exception\UnexpectedJsonTokenException If the next token is not BEGIN_OBJECT
56
     */
57 17
    public function beginObject(): void
58
    {
59 17
        $this->expect(JsonToken::BEGIN_OBJECT);
60
61
        /** @var JsonObject $jsonObject */
62 16
        $jsonObject = $this->pop();
63
64 16
        $this->push(new JsonObjectIterator($jsonObject), JsonObjectIterator::class);
65 16
    }
66
67
    /**
68
     * Consumes the value of the next token, asserts it's a boolean and returns it
69
     *
70
     * @return bool
71
     * @throws \Tebru\Gson\Exception\UnexpectedJsonTokenException If the next token is not BOOLEAN
72
     */
73 6
    public function nextBoolean(): bool
74
    {
75 6
        $this->expect(JsonToken::BOOLEAN);
76
77
        /** @var JsonPrimitive $primitive */
78 5
        $primitive = $this->pop();
79
80 5
        $this->incrementPathIndex();
81
82 5
        return $primitive->asBoolean();
83
    }
84
85
    /**
86
     * Consumes the value of the next token, asserts it's a double and returns it
87
     *
88
     * @return double
89
     * @throws \Tebru\Gson\Exception\UnexpectedJsonTokenException If the next token is not NUMBER
90
     */
91 3
    public function nextDouble(): float
92
    {
93 3
        $this->expect(JsonToken::NUMBER);
94
95
        /** @var JsonPrimitive $primitive */
96 2
        $primitive = $this->pop();
97
98 2
        $this->incrementPathIndex();
99
100 2
        return $primitive->asFloat();
101
    }
102
103
    /**
104
     * Consumes the value of the next token, asserts it's an int and returns it
105
     *
106
     * @return int
107
     * @throws \Tebru\Gson\Exception\UnexpectedJsonTokenException If the next token is not NUMBER
108
     */
109 6
    public function nextInteger(): int
110
    {
111 6
        $this->expect(JsonToken::NUMBER);
112
113
        /** @var JsonPrimitive $primitive */
114 5
        $primitive = $this->pop();
115
116 5
        $this->incrementPathIndex();
117
118 5
        return $primitive->asInteger();
119
    }
120
121
    /**
122
     * Consumes the value of the next token, asserts it's a string and returns it
123
     *
124
     * @return string
125
     * @throws \Tebru\Gson\Exception\UnexpectedJsonTokenException If the next token is not NAME or STRING
126
     */
127 14 View Code Duplication
    public function nextString(): string
1 ignored issue
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...
128
    {
129 14
        $peek = $this->peek();
130 14
        if ($peek === JsonToken::NAME) {
131 1
            return $this->nextName();
132
        }
133
134 13
        $this->expect(JsonToken::STRING);
135
136
        /** @var JsonPrimitive $primitive */
137 12
        $primitive = $this->pop();
138
139 12
        $this->incrementPathIndex();
140
141 12
        return $primitive->asString();
142
    }
143
144
    /**
145
     * Returns an enum representing the type of the next token without consuming it
146
     *
147
     * @return string
148
     */
149 69
    public function peek(): string
150
    {
151 69
        if (null !== $this->currentToken) {
152 23
            return $this->currentToken;
153
        }
154
155 69
        if (0 === $this->stackSize) {
156 1
            $this->currentToken = JsonToken::END_DOCUMENT;
157
158 1
            return $this->currentToken;
159
        }
160
161 69
        $token = null;
162 69
        $element = $this->stack[$this->stackSize - 1];
163
164 69
        switch ($this->stackTypes[$this->stackSize - 1]) {
165 69
            case JsonArray::class:
166 16
                $token = JsonToken::BEGIN_ARRAY;
167 16
                break;
168 66
            case JsonNull::class:
169 2
                $token = JsonToken::NULL;
170 2
                break;
171 64
            case JsonObject::class:
172 20
                $token = JsonToken::BEGIN_OBJECT;
173 20
                break;
174 61
            case JsonPrimitive::class:
175
                /** @var JsonPrimitive $element */
176 45
                if ($element->isString()) {
177 18
                    $token = JsonToken::STRING;
178 28
                } elseif ($element->isBoolean()) {
179 8
                    $token = JsonToken::BOOLEAN;
180 21
                } elseif ($element->isNumber()) {
181 21
                    $token = JsonToken::NUMBER;
182
                }
183
184 45
                break;
185 27
            case JsonObjectIterator::class:
186
                /** @var JsonObjectIterator $element */
187 15
                $token = $element->valid() ? JsonToken::NAME : JsonToken::END_OBJECT;
188
189 15
                break;
190 13 View Code Duplication
            case ArrayIterator::class:
1 ignored issue
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...
191
                /** @var ArrayIterator $element */
192 13
                if ($element->valid()) {
193 9
                    $this->push($element->current());
194 9
                    $element->next();
195
196 9
                    $token = $this->peek();
197
                } else {
198 7
                    $token = JsonToken::END_ARRAY;
199
                }
200
201 13
                break;
202
        }
203
204 69
        $this->currentToken = $token;
205
206 69
        return $this->currentToken;
207
    }
208
209
    /**
210
     * Get the current read path in json xpath format
211
     *
212
     * @return string
213
     */
214 10 View Code Duplication
    public function getPath(): string
1 ignored issue
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...
215
    {
216 10
        $result = '$';
217 10
        foreach ($this->stack as $index => $item) {
218 10
            if ($item instanceof ArrayIterator && isset($this->pathIndices[$index])) {
219 1
                $result .= '['.$this->pathIndices[$index].']';
220
            }
221
222 10
            if ($item instanceof JsonObjectIterator && isset($this->pathNames[$index])) {
223 10
                $result .= '.'.$this->pathNames[$index];
224
            }
225
        }
226
227 10
        return $result;
228
    }
229
230
    /**
231
     * Push an element onto the stack
232
     *
233
     * @param JsonElement|Iterator $element
234
     * @param string $type
0 ignored issues
show
Documentation introduced by
Should the type for parameter $type not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
235
     */
236 69 View Code Duplication
    protected function push($element, $type = null): void
1 ignored issue
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...
237
    {
238 69
        if (null === $type) {
239 69
            $type = get_class($element);
240
        }
241
242 69
        $this->stack[$this->stackSize] = $element;
243 69
        $this->stackTypes[$this->stackSize] = $type;
244 69
        $this->stackSize++;
245 69
        $this->currentToken = null;
246 69
    }
247
}
248