Completed
Push — feature/0.7.0 ( c0c2ef...83eb72 )
by Ryuichi
02:50
created

InputStream::isMarkSupported()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
namespace WebStream\IO;
3
4
use WebStream\Exception\Extend\IOException;
5
use WebStream\Exception\Extend\InvalidArgumentException;
6
7
/**
8
 * InputStream
9
 * @author Ryuichi TANAKA.
10
 * @since 2016/02/05
11
 * @version 0.7
12
 */
13
class InputStream
14
{
15
    /**
16
     * @var resource 入力ストリーム
17
     */
18
    protected $stream;
19
20
    /**
21
     * @var int 現在のポインタ位置
22
     */
23
    protected $cursorPosition;
24
25
    /**
26
     * @var int markしたポインタ位置
27
     */
28
    protected $markedPosition;
29
30
    /**
31
     * constructor
32
     * @param resource $stream 入力ストリーム
33
     */
34
    public function __construct($stream)
35
    {
36
        if (!is_resource($stream)) {
37
            throw new IOException("Input stream must be type of Resource.");
38
        }
39
40
        $this->stream = $stream;
41
        $this->cursorPosition = 0;
42
        $this->markedPosition = 0;
43
    }
44
45
    /**
46
     * destructor
47
     */
48
    public function __destruct()
49
    {
50
        $this->close();
51
    }
52
53
    /**
54
     * 入力ストリームを閉じる
55
     */
56
    public function close()
57
    {
58
        if ($this->stream === null) {
59
            return;
60
        }
61
62 View Code Duplication
        if (@flose($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...
63
            throw new IOException("Cannot close " . $this->file->getAbsoluteFilePath() . " cause by " . $php_errormsg);
0 ignored issues
show
Bug introduced by
The property file does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
64
        }
65
66
        $this->stream = null;
67
    }
68
69
    /**
70
     * 入力ストリームからデータを読み込む
71
     * 引数に数値を指定した場合、指定数値バイトだけ読み込む
72
     * @param int length 読み込みバイト数
73
     * @return string 読み込みデータ
74
     * @throws InvalidArgumentException
75
     */
76
    public function read($length = null)
77
    {
78
        if ($this->eof()) {
79
            return -1;
80
        }
81
82
        $out = "";
83
        if ($length === null) {
84
            while (!$this->eof()) {
85
                // InputStreamでは固定値でしか読み込ませない
86
                $out .= fread($this->stream, 8192);
87
                $this->cursorPosition = ftell($this->stream);
88
            }
89
        } else {
90
            if (!is_int($length)) {
91
                throw new InvalidArgumentException("Stream read must be a numeric value.");
92
            }
93
94
            // $lengthだけ指定して読み込む
95
            $out = fread($this->stream, $length);
96
            $this->cursorPosition = ftell($this->stream);
97
        }
98
99
        return $out;
100
    }
101
102
    /**
103
     * 入力ストリームから指定バイト数後方へポインタを移動する
104
     * @param int $pos 後方への移動バイト数(負数の場合は前方へ移動)
105
     * @return int $skipNum 移動したバイト数、移動に失敗した場合-1
106
     */
107
    public function skip(int $pos)
108
    {
109
        // 現在のポインタ位置から$posだけ後方へ移動
110
        // シークに対応していないファイルシステムの場合、-1を返す
111
        if (fseek($this->stream, $pos, SEEK_CUR) === -1) {
112
            return -1;
113
        }
114
115
        $start = $this->cursorPosition;
116
        $this->cursorPosition = ftell($this->stream);
117
118
        $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...
119 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...
120
            // 前方へ移動
121
            $skipNum = $start - $this->cursorPosition;
122
        } else {
123
            // 後方へ移動
124
            $skipNum = $this->cursorPosition - $start;
125
        }
126
127
        return $skipNum;
128
    }
129
130
    /**
131
     * 入力ストリームの現在位置にmarkを設定する
132
     * @throws IOException
133
     */
134
    public function mark()
135
    {
136
        if (!$this->isMarkSupported()) {
137
            throw new IOException(get_class($this) . " does not support mark.");
138
        }
139
140
        $this->markedPosition = $this->cursorPosition;
141
    }
142
143
    /**
144
     * 最後にmarkされた位置に再配置する
145
     * @throws IOException
146
     */
147
    public function reset()
148
    {
149
        if (!$this->isMarkSupported()) {
150
            throw new IOException(get_class($this) . " does not support mark and reset.");
151
        }
152
153
        // ポインタ位置をmark位置に移動
154
        fseek($this->stream, SEEK_SET, $this->markedPosition);
155
        // mark位置を初期値に戻す
156
        $this->markedPosition = 0;
157
    }
158
159
    /**
160
     * EOFかどうか返却する
161
     * @return bool EOFならtrue
162
     */
163
    public function eof()
164
    {
165
        return feof($this->stream);
166
    }
167
168
    /**
169
     * mark機能をサポートしているかどうか
170
     * @return boolean マークをサポートしていればtrue
171
     */
172
    public function isMarkSupported()
173
    {
174
        return false;
175
    }
176
}
177