Completed
Push — master ( 0d3b86...8e2193 )
by Max
15:02
created

Parser::closeStream()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 10
c 0
b 0
f 0
cc 3
nc 3
nop 1
1
<?php
2
3
namespace JsonCollectionParser;
4
5
use JsonStreamingParser\Parser as BaseParser;
6
7
class Parser
8
{
9
    /**
10
     * @var array
11
     */
12
    protected $options = [
13
        'line_ending' => "\n",
14
        'emit_whitespace' => false,
15
    ];
16
17
    /**
18
     * @var BaseParser
19
     */
20
    protected $parser;
21
22
    /**
23
     * @var bool
24
     */
25
    protected $gzipSupported;
26
27
    /**
28
     * @var resource
29
     */
30
    protected $stream;
31
32
    public function __construct()
33
    {
34
        $this->gzipSupported = extension_loaded('zlib');
35
    }
36
37
    /**
38
     * @param string|resource $input File path or resource
39
     * @param callback|callable $itemCallback Callback
40
     * @param bool $assoc Parse as associative arrays
41
     *
42
     * @throws \Exception
43
     */
44
    public function parse($input, $itemCallback, $assoc = true)
45
    {
46
        $this->checkCallback($itemCallback);
47
48
        $stream = $this->openStream($input);
49
50
        try {
51
            $listener = new Listener($itemCallback, $assoc);
52
            $this->parser = new BaseParser(
53
                $stream,
54
                $listener,
55
                $this->getOption('line_ending'),
56
                $this->getOption('emit_whitespace')
57
            );
58
            $this->parser->parse();
59
        } catch (\Exception $e) {
60
            $this->closeStream($stream);
61
            throw $e;
62
        }
63
64
        $this->closeStream($stream);
65
    }
66
67
    /**
68
     * @param string|resource $input File path or resource
69
     * @param callback|callable $itemCallback Callback
70
     *
71
     * @throws \Exception
72
     */
73
    public function parseAsObjects($input, $itemCallback)
74
    {
75
        $this->parse($input, $itemCallback, false);
76
    }
77
78
    /**
79
     *
80
     */
81
    public function stop()
82
    {
83
        $this->parser->stop();
84
    }
85
86
    /**
87
     * @param callback|callable $callback
88
     *
89
     * @throws \Exception
90
     */
91
    protected function checkCallback($callback)
92
    {
93
        if (!is_callable($callback)) {
94
            throw new \Exception("Callback should be callable");
95
        }
96
    }
97
98
    /**
99
     * @param string|resource $input File path or resource
100
     *
101
     * @return resource
102
     * @throws \Exception
103
     */
104
    protected function openStream($input)
105
    {
106
        if (is_resource($input)) {
107
            return $input;
108
        }
109
110
        if (!is_file($input)) {
111
            throw new \Exception('File does not exist: ' . $input);
112
        }
113
114
        $stream = $this->gzipSupported ? @gzopen($input, 'r') : @fopen($input, 'r');
115
        if (false === $stream) {
116
            throw new \Exception('Unable to open file for read: ' . $input);
117
        }
118
119
        return $stream;
120
    }
121
122
    /**
123
     * @param resource $stream
124
     */
125
    protected function closeStream($stream)
126
    {
127
        if (!is_resource($stream)) {
128
            return;
129
        }
130
131
        $this->gzipSupported ? gzclose($stream) : fclose($stream);
132
    }
133
134
    /**
135
     * @param string $name
136
     * @param mixed $value
137
     */
138
    public function setOption($name, $value)
139
    {
140
        $this->options[$name] = $value;
141
    }
142
143
    /**
144
     * @param string $name
145
     *
146
     * @return mixed
147
     */
148
    public function getOption($name)
149
    {
150
        if (isset($this->options[$name])) {
151
            return $this->options[$name];
152
        } else {
153
            return null;
154
        }
155
    }
156
}
157