StreamSource   A
last analyzed

Complexity

Total Complexity 15

Size/Duplication

Total Lines 62
Duplicated Lines 0 %

Test Coverage

Coverage 80.65%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 30
c 1
b 0
f 0
dl 0
loc 62
ccs 25
cts 31
cp 0.8065
rs 10
wmc 15

4 Methods

Rating   Name   Duplication   Size   Complexity  
A isEof() 0 3 1
A __construct() 0 6 2
A read() 0 13 4
B rewind() 0 24 8
1
<?php
2
declare(strict_types=1);
3
4
namespace JsonDecodeStream\Source;
5
6
use JsonDecodeStream\Exception\SourceException;
7
8
class StreamSource implements SourceInterface
9
{
10
    /** @var resource */
11
    protected $stream;
12
13
    /**
14
     * StreamSource constructor.
15
     * @param $stream
16
     * @throws SourceException
17
     */
18 60
    public function __construct($stream)
19
    {
20 60
        if (!is_resource($stream)) {
21 1
            throw new SourceException('Argument is not a resource');
22
        }
23 59
        $this->stream = $stream;
24 59
    }
25
26 58
    public function isEof(): bool
27
    {
28 58
        return feof($this->stream);
29
    }
30
31 62
    public function read(int $bytes): string
32
    {
33
        try {
34 62
            $read = fread($this->stream, $bytes);
35 62
            if ($read === false) {
36
                $error = error_get_last();
37 62
                throw new \RuntimeException($error ? $error['message'] : 'fread error');
38
            }
39
        } catch (\Throwable $e) {
40
            throw new SourceException('Cound not read from stream', 0, $e);
41
        }
42
43 62
        return $read;
44
    }
45
46 57
    public function rewind(): void
47
    {
48
        try {
49 57
            $tell = ftell($this->stream);
50 57
            if ($tell === false) {
51
                $error = error_get_last();
52
                throw new \RuntimeException($error ? $error['message'] : 'ftell error');
53
            }
54 57
            if ($tell === 0) {
55 55
                return;
56
            }
57
58 3
            $streamMetaData = stream_get_meta_data($this->stream);
59 3
            if (!$streamMetaData['seekable']) {
60 1
                throw new SourceException('This stream is not seekable, can not rewind after data was read');
61
            }
62
63 2
            $seek = fseek($this->stream, 0, SEEK_SET);
64 2
            if ($seek === -1) {
65
                $error = error_get_last();
66 2
                throw new \RuntimeException($error ? $error['message'] : 'fseek error');
67
            }
68 1
        } catch (\Throwable $e) {
69 1
            throw new SourceException('Cound not seek the stream', 0, $e);
70
        }
71 2
    }
72
}
73