Completed
Push — feature/0.7.0 ( 2f2cdf...d06a69 )
by Ryuichi
02:51
created

StringInputStream::readLine()   B

Complexity

Conditions 4
Paths 5

Size

Total Lines 26
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 26
rs 8.5806
cc 4
eloc 15
nc 5
nop 0
1
<?php
2
namespace WebStream\IO;
3
4
use WebStream\Exception\Extend\IOException;
5
6
/**
7
 * StringInputStream
8
 * @author Ryuichi TANAKA.
9
 * @since 2016/02/07
10
 * @version 0.7
11
 */
12
class StringInputStream extends InputStream
13
{
14
    /**
15
     * @var int 文字列長
16
     */
17
    private $length;
18
19
    /**
20
     * @var bool 終端かどうか
21
     */
22
    private $isEOF = false;
23
24
    /**
25
     * construct
26
     * @param string $str 文字列
27
     */
28
    public function __construct($str)
29
    {
30
        parent::__construct($str);
31
        $this->length = strlen($str);
32
    }
33
34
    /**
35
     * 入力ストリームを閉じる
36
     */
37
    public function close()
38
    {
39
        $this->stream = null;
40
    }
41
42
    /**
43
     * {@inheritdoc}
44
     */
45
    public function read($length = null)
46
    {
47
        if ($this->eof()) {
48
            return null;
49
        }
50
51
        // SkipでポインタをずらしただけではEOFにはならない、FileInputStream実装に合わせる
52
        // Skipでずらしたあとreadすると空文字を返し、もう一度readするとEOFを認識する
53
        // ファイルの終端より先にポインタをすすめることは「可能」=書き込みと同じ
54
        // なので、現在の終端位置より先に進めてもEOF自体にはならない。進めた位置はEOFのひとつ前
55
        // だからもう一回readするとEOFに到達する。なのでskipを使ってもEOF到達できない
56
        if ($this->cursorPosition > $this->length - 1) {
57
            $this->isEOF = true;
58
59
            return "";
60
        }
61
62
        $out = "";
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...
63
        if ($length === null) {
64
            $length = 1;
0 ignored issues
show
Unused Code introduced by
$length 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...
65
            $out = substr($this->stream, $this->cursorPosition, 1);
66
            $this->cursorPosition += 1;
67
        } else {
68
            if (!is_int($length)) {
69
                throw new InvalidArgumentException("Stream read must be a numeric value.");
70
            }
71
72
            // $lengthがファイル終端を越えないようにする
73
            if (($this->cursorPosition + $length) > $this->length) {
74
                $length = $this->length - $this->cursorPosition;
75
            }
76
77
            $out = substr($this->stream, $this->cursorPosition, $length);
78
            $this->cursorPosition += $length;
79
        }
80
81
        return $out;
82
    }
83
84
    public function readLine()
85
    {
86
        if ($this->eof()) {
87
            return null;
88
        }
89
90
        // 処理対象の残りのバイト数
91
        $targetLength = $this->length - $this->cursorPosition;
92
93
        // 処理対象の文字列
94
        $text = substr($this->stream, $this->cursorPosition, $targetLength);
95
        $lengthEOL = strlen(PHP_EOL);
96
        $notLinePart = strstr($text, PHP_EOL);
97
98
        $notLinePartLength = 0;
99
        if ($notLinePart !== false) {
100
            $notLinePartLength = strlen($notLinePart);
101
        }
102
103
        $offset = $targetLength - $notLinePartLength;
104
        $out = substr($text, 0, $offset);
105
        $out = $out === false ? null : $out;
106
        $this->skip($offset + $lengthEOL);
107
108
        return $out;
109
    }
110
111
    /**
112
     * {@inheritdoc}
113
     */
114
    public function skip(int $pos)
115
    {
116
        // ファイル終端到達後、skipを実行すると後方にポインタが移動する
117
        // このときEOFだったものがEOFでなくなる
118
        $start = $this->cursorPosition;
119
120
        // 現在位置が負になった場合は-1を返して終了
121
        if ($this->cursorPosition + $pos < 0) {
122
            return -1;
123
        }
124
125
        $this->cursorPosition += $pos;
126
        $this->isEOF = false;
127
128
        // skipした実際のバイト数
129
        $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...
130 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...
131
            // 後方へ移動
132
            $skipNum = $start - $this->cursorPosition;
133
        } else {
134
            // 前方へ移動
135
            $skipNum = $this->cursorPosition - $start;
136
        }
137
138
        return $skipNum;
139
    }
140
141
    /**
142
     * {@inheritdoc}
143
     */
144
    public function eof()
145
    {
146
        return $this->isEOF;
147
    }
148
149
    /**
150
     * {@inheritdoc}
151
     */
152
    public function isMarkSupported()
153
    {
154
        return true;
155
    }
156
}
157