Passed
Push — master ( 35a69c...54bf96 )
by Ryuichi
01:46
created

FileInputStream::readLine()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4.128

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 9
c 1
b 0
f 0
nc 4
nop 0
dl 0
loc 18
ccs 8
cts 10
cp 0.8
crap 4.128
rs 9.9666
1
<?php
2
3
namespace WebStream\IO;
4
5
use WebStream\Exception\Extend\InvalidArgumentException;
0 ignored issues
show
Bug introduced by
The type WebStream\Exception\Exte...nvalidArgumentException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use WebStream\Exception\Extend\IOException;
0 ignored issues
show
Bug introduced by
The type WebStream\Exception\Extend\IOException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
8
/**
9
 * FileInputStream
10
 * @author Ryuichi TANAKA.
11
 * @since 2016/02/05
12
 * @version 0.7
13
 */
14
class FileInputStream extends InputStream
15
{
16
    /**
17
     * @var File ファイルオブジェクト
18
     */
19
    protected $file;
20
21
    /**
22
     * constructor
23
     * @param mixed $file ファイルオブジェクトまたはファイルパス
24
     * @throws InvalidArgumentException
25
     * @throws IOException
26
     */
27 11
    public function __construct($file)
28
    {
29 11
        if ($file instanceof File) {
30 1
            $this->file = $file;
31 10
        } elseif (is_string($file)) {
32 10
            $this->file = new File($file);
33
        } else {
34
            throw new InvalidArgumentException("Unable to open file: " . $file);
35
        }
36
37
        // 読み込みはロックを掛けずダーティーリード
38 11
        $stream = fopen($this->file->getAbsoluteFilePath(), 'r');
39 11
        if (!is_resource($stream) || $stream === false) {
40
            throw new IOException("Unable open " . $this->file->getAbsoluteFilePath());
41
        }
42
43 11
        parent::__construct($stream);
44
    }
45
46
    /**
47
     * 入力ストリームを閉じる
48
     */
49 31
    public function close()
50
    {
51 31
        if ($this->stream === null) {
52 12
            return;
53
        }
54
55 31
        if (get_resource_type($this->stream) !== 'Unknown' && fclose($this->stream) === false) {
56
            throw new IOException("Cannot close input stream.");
57
        }
58
59 31
        $this->stream = null;
60
    }
61
62
    /**
63
     * {@inheritdoc}
64
     */
65 28
    public function read($length = null)
66
    {
67 28
        if ($this->stream === null) {
68 1
            return null;
69
        }
70
71 27
        if ($this->eof()) {
72 13
            return null;
73
        }
74
75
        $out = null;
76 27
        if ($length === null) {
77 11
            if (($out = @fread($this->stream, 1)) === false) {
78
                throw new IOException("Failed to read stream.");
79
            }
80
        } else {
81 16
            if (!is_int($length)) {
82 1
                throw new InvalidArgumentException("Stream read must be a numeric value.");
83
            }
84
            // ポインタ位置が負になった場合、警告が出てfalseを返す
85
            // ポインタの終端を越えた場合、読み込みを終了する
86
            // すでに終端位置の場合、空文字を返す
87 15
            if (($out = @fread($this->stream, $length)) === false) {
88
                throw new IOException("Failed to read stream.");
89
            }
90
        }
91
92 26
        return $out;
93
    }
94
95
    /**
96
     * 入力ストリームから行単位でデータを読み込む
97
     * 末尾に改行コードは含まない
98
     * @return string 読み込みデータ
99
     */
100 1
    public function readLine()
101
    {
102 1
        if ($this->stream === null) {
103
            return null;
104
        }
105
106 1
        if ($this->eof()) {
107
            return null;
108
        }
109
110 1
        $out = fgets($this->stream);
111 1
        if ($out === false) {
112 1
            return null;
113
        }
114
115 1
        $this->cursorPosition = ftell($this->stream);
116
117 1
        return trim($out);
118
    }
119
120
    /**
121
     * {@inheritdoc}
122
     */
123 13
    public function skip(int $pos)
124
    {
125 13
        if ($this->stream === null) {
126
            return -1;
127
        }
128
129
        // 現在のポインタ位置から$posだけ後方へ移動
130
        // シークに対応していないファイルシステムの場合、-1を返す
131 13
        if (fseek($this->stream, $pos, SEEK_CUR) === -1) {
132 2
            return -1;
133
        }
134
135 11
        $start = $this->cursorPosition;
136 11
        $this->cursorPosition = ftell($this->stream);
137
138
        $skipNum = 0;
139 11
        if ($start > $this->cursorPosition) {
140
            // 後方へ移動
141 1
            $skipNum = $start - $this->cursorPosition;
142
        } else {
143
            // 前方へ移動
144 11
            $skipNum = $this->cursorPosition - $start;
145
        }
146
147 11
        return $skipNum;
148
    }
149
150
    /**
151
     * {@inheritdoc}
152
     */
153 2
    public function reset()
154
    {
155 2
        if (!$this->isMarkSupported()) {
156
            throw new IOException(get_class($this) . " does not support mark and reset.");
157
        }
158
159 2
        if ($this->stream === null) {
160
            return;
161
        }
162
163
        // ポインタ位置をmark位置に移動
164 2
        fseek($this->stream, $this->markedPosition, SEEK_SET);
165
        // mark位置を初期値に戻す
166 2
        $this->cursorPosition = $this->markedPosition;
167 2
        $this->markedPosition = 0;
168
    }
169
170
    /**
171
     * {@inheritdoc}
172
     */
173 28
    public function eof()
174
    {
175 28
        return feof($this->stream);
176
    }
177
178
    /**
179
     * {@inheritdoc}
180
     */
181 2
    public function isMarkSupported()
182
    {
183 2
        return true;
184
    }
185
}
186