FileInputStream::skip()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 25
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 4.0119

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 12
c 1
b 0
f 0
nc 4
nop 1
dl 0
loc 25
ccs 10
cts 11
cp 0.9091
crap 4.0119
rs 9.8666
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 $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 27
    public function read(int $length = 0)
66
    {
67 27
        if ($this->stream === null) {
68 1
            return null;
69
        }
70
71 26
        if ($this->eof()) {
72 13
            return null;
73
        }
74
75
        $out = null;
76 26
        if ($length === 0) {
77 11
            if (($out = @fread($this->stream, 1)) === false) {
78
                throw new IOException("Failed to read stream.");
79
            }
80
        } else {
81
            // ポインタ位置が負になった場合、警告が出てfalseを返す
82
            // ポインタの終端を越えた場合、読み込みを終了する
83
            // すでに終端位置の場合、空文字を返す
84 15
            if (($out = @fread($this->stream, $length)) === false) {
85
                throw new IOException("Failed to read stream.");
86
            }
87
        }
88
89 26
        return $out;
90
    }
91
92
    /**
93
     * 入力ストリームから行単位でデータを読み込む
94
     * 末尾に改行コードは含まない
95
     * @return string 読み込みデータ
96
     */
97 1
    public function readLine()
98
    {
99 1
        if ($this->stream === null) {
100
            return null;
101
        }
102
103 1
        if ($this->eof()) {
104
            return null;
105
        }
106
107 1
        $out = fgets($this->stream);
108 1
        if ($out === false) {
109 1
            return null;
110
        }
111
112 1
        $this->cursorPosition = ftell($this->stream);
113
114 1
        return trim($out);
115
    }
116
117
    /**
118
     * {@inheritdoc}
119
     */
120 13
    public function skip(int $pos)
121
    {
122 13
        if ($this->stream === null) {
123
            return -1;
124
        }
125
126
        // 現在のポインタ位置から$posだけ後方へ移動
127
        // シークに対応していないファイルシステムの場合、-1を返す
128 13
        if (fseek($this->stream, $pos, SEEK_CUR) === -1) {
129 2
            return -1;
130
        }
131
132 11
        $start = $this->cursorPosition;
133 11
        $this->cursorPosition = ftell($this->stream);
134
135
        $skipNum = 0;
136 11
        if ($start > $this->cursorPosition) {
137
            // 後方へ移動
138 1
            $skipNum = $start - $this->cursorPosition;
139
        } else {
140
            // 前方へ移動
141 11
            $skipNum = $this->cursorPosition - $start;
142
        }
143
144 11
        return $skipNum;
145
    }
146
147
    /**
148
     * {@inheritdoc}
149
     */
150 2
    public function reset()
151
    {
152 2
        if (!$this->isMarkSupported()) {
153
            throw new IOException(get_class($this) . " does not support mark and reset.");
154
        }
155
156 2
        if ($this->stream === null) {
157
            return;
158
        }
159
160
        // ポインタ位置をmark位置に移動
161 2
        fseek($this->stream, $this->markedPosition, SEEK_SET);
162
        // mark位置を初期値に戻す
163 2
        $this->cursorPosition = $this->markedPosition;
164 2
        $this->markedPosition = 0;
165
    }
166
167
    /**
168
     * {@inheritdoc}
169
     */
170 27
    public function eof()
171
    {
172 27
        return feof($this->stream);
173
    }
174
175
    /**
176
     * {@inheritdoc}
177
     */
178 2
    public function isMarkSupported()
179
    {
180 2
        return true;
181
    }
182
}
183