Completed
Push — master ( c9812e...73d93a )
by Ryuichi
02:42
created

FileInputStream::skip()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 26
Code Lines 13

Duplication

Lines 7
Ratio 26.92 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 7
loc 26
rs 8.5806
cc 4
eloc 13
nc 4
nop 1
1
<?php
2
namespace WebStream\IO;
3
4
use WebStream\Exception\Extend\InvalidArgumentException;
5
use WebStream\Exception\Extend\IOException;
6
7
/**
8
 * FileInputStream
9
 * @author Ryuichi TANAKA.
10
 * @since 2016/02/05
11
 * @version 0.7
12
 */
13
class FileInputStream extends InputStream
14
{
15
    /**
16
     * @var File ファイルオブジェクト
17
     */
18
    protected $file;
19
20
    /**
21
     * constructor
22
     * @param mixed $file ファイルオブジェクトまたはファイルパス
23
     * @throws InvalidArgumentException
24
     * @throws IOException
25
     */
26
    public function __construct($file)
27
    {
28
        if ($file instanceof File) {
29
            $this->file = $file;
30
        } elseif (is_string($file)) {
31
            $this->file = new File($file);
32
        } else {
33
            throw new InvalidArgumentException("Unable to open file: " . $file);
34
        }
35
36
        // 読み込みはロックを掛けずダーティーリード
37
        $stream = fopen($this->file->getAbsoluteFilePath(), 'r');
38
        if (!is_resource($stream) || $stream === false) {
39
            throw new IOException("Unable open " . $this->file->getAbsoluteFilePath());
40
        }
41
42
        parent::__construct($stream);
43
    }
44
45
    /**
46
     * 入力ストリームを閉じる
47
     */
48
    public function close()
49
    {
50
        if ($this->stream === null) {
51
            return;
52
        }
53
54 View Code Duplication
        if (get_resource_type($this->stream) !== 'Unknown' && fclose($this->stream) === false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
55
            throw new IOException("Cannot close input stream.");
56
        }
57
58
        $this->stream = null;
59
    }
60
61
    /**
62
     * {@inheritdoc}
63
     */
64
    public function read($length = null)
65
    {
66
        if ($this->stream === null) {
67
            return null;
68
        }
69
70
        if ($this->eof()) {
71
            return null;
72
        }
73
74
        $out = null;
0 ignored issues
show
Unused Code introduced by
$out is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
75
        if ($length === null) {
76 View Code Duplication
            if (($out = @fread($this->stream, 1)) === false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
77
                throw new IOException("Failed to read stream.");
78
            }
79
        } else {
80
            if (!is_int($length)) {
81
                throw new InvalidArgumentException("Stream read must be a numeric value.");
82
            }
83
            // ポインタ位置が負になった場合、警告が出てfalseを返す
84
            // ポインタの終端を越えた場合、読み込みを終了する
85
            // すでに終端位置の場合、空文字を返す
86 View Code Duplication
            if (($out = @fread($this->stream, $length)) === false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
87
                throw new IOException("Failed to read stream.");
88
            }
89
        }
90
91
        return $out;
92
    }
93
94
    /**
95
     * 入力ストリームから行単位でデータを読み込む
96
     * 末尾に改行コードは含まない
97
     * @return string 読み込みデータ
98
     */
99
    public function readLine()
100
    {
101
        if ($this->stream === null) {
102
            return null;
103
        }
104
105
        if ($this->eof()) {
106
            return null;
107
        }
108
109
        $out = fgets($this->stream);
110
        if ($out === false) {
111
            return null;
112
        }
113
114
        $this->cursorPosition = ftell($this->stream);
115
116
        return trim($out);
117
    }
118
119
    /**
120
     * {@inheritdoc}
121
     */
122
    public function skip(int $pos)
123
    {
124
        if ($this->stream === null) {
125
            return -1;
126
        }
127
128
        // 現在のポインタ位置から$posだけ後方へ移動
129
        // シークに対応していないファイルシステムの場合、-1を返す
130
        if (fseek($this->stream, $pos, SEEK_CUR) === -1) {
131
            return -1;
132
        }
133
134
        $start = $this->cursorPosition;
135
        $this->cursorPosition = ftell($this->stream);
136
137
        $skipNum = 0;
0 ignored issues
show
Unused Code introduced by
$skipNum is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
138 View Code Duplication
        if ($start > $this->cursorPosition) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
139
            // 後方へ移動
140
            $skipNum = $start - $this->cursorPosition;
141
        } else {
142
            // 前方へ移動
143
            $skipNum = $this->cursorPosition - $start;
144
        }
145
146
        return $skipNum;
147
    }
148
149
    /**
150
     * {@inheritdoc}
151
     */
152
    public function reset()
153
    {
154
        if (!$this->isMarkSupported()) {
155
            throw new IOException(get_class($this) . " does not support mark and reset.");
156
        }
157
158
        if ($this->stream === null) {
159
            return;
160
        }
161
162
        // ポインタ位置をmark位置に移動
163
        fseek($this->stream, $this->markedPosition, SEEK_SET);
164
        // mark位置を初期値に戻す
165
        $this->cursorPosition = $this->markedPosition;
166
        $this->markedPosition = 0;
167
    }
168
169
    /**
170
     * {@inheritdoc}
171
     */
172
    public function eof()
173
    {
174
        return feof($this->stream);
175
    }
176
177
    /**
178
     * {@inheritdoc}
179
     */
180
    public function isMarkSupported()
181
    {
182
        return true;
183
    }
184
}
185