Completed
Push — master ( 830536...b920b4 )
by Christopher
02:09
created

StringDecoder::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 5
cts 5
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 3
crap 1
1
<?php
2
namespace Networkteam\JsonSeq;
3
4
class StringDecoder
5
{
6
7
    const RS = "\x1E";
8
9
    /**
10
     * @var bool
11
     */
12
    private $jsonDecodeAssoc;
13
14
    /**
15
     * @var int
16
     */
17
    private $jsonDecodeDepth;
18
19
    /**
20
     * @var int
21
     */
22
    private $jsonDecodeOptions;
23
24 6
    public function __construct(bool $assoc = false, int $depth = 512, int $options = 0)
25
    {
26 6
        $this->jsonDecodeAssoc = $assoc;
27 6
        $this->jsonDecodeDepth = $depth;
28 6
        $this->jsonDecodeOptions = $options;
29 6
    }
30
31 6
    public function decode(string $content): iterable
32
    {
33 6
        $lastPos = 0;
34 6
        $length = strlen($content);
35 6
        while ($lastPos < $length && ($nextPos = strpos($content, self::RS, $lastPos)) !== false) {
36 5
            $lastPos = strpos($content, self::RS, $nextPos + 1);
37 5
            if ($lastPos === false) {
38 5
                $lastPos = $length;
39
            }
40
41
            // RFC7464 2.1 states that "Multiple consecutive RS octets do not denote empty sequence elements
42
            // between them and can be ignored."
43 5
            if ($lastPos === $nextPos + 1) {
44 1
                continue;
45
            }
46 5
            $jsonText = substr($content, $nextPos + 1, $lastPos - 1);
47 5
            $data = $this->jsonDecode($jsonText);
48 5
            yield $data;
49
        }
50 6
    }
51
52
    /**
53
     * @param string $jsonText
54
     * @return mixed|ParseError
55
     */
56 5
    private function jsonDecode(string $jsonText)
57
    {
58 5
        $data = json_decode($jsonText, $this->jsonDecodeAssoc, $this->jsonDecodeDepth, $this->jsonDecodeOptions);
59 5
        if ($data === null && ($jsonLastError = json_last_error()) !== JSON_ERROR_NONE) {
60
            // RFC7464 2.1 states that the parser should continue, so we return a ParseError here
61 2
            $data = new ParseError($jsonLastError, json_last_error_msg());
62
        }
63 5
        return $data;
64
    }
65
}
66