BufferedReader   A
last analyzed

Complexity

Total Complexity 21

Size/Duplication

Total Lines 155
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 21
eloc 47
dl 0
loc 155
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A close() 0 3 1
A readChar() 0 25 5
A eof() 0 3 1
A reset() 0 3 1
A read() 0 28 5
A skip() 0 3 1
A __construct() 0 4 1
A getResource() 0 3 1
A readLine() 0 18 5
1
<?php
2
3
/**
4
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
5
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
6
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
7
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
8
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
10
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
11
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
12
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
14
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15
 *
16
 * This software consists of voluntary contributions made by many individuals
17
 * and is licensed under the LGPL. For more information please see
18
 * <http://phing.info>.
19
 */
20
21
namespace Phing\Io;
22
23
/**
24
 * Convenience class for reading files.
25
 *
26
 * @author <a href="mailto:[email protected]">Yannick Lecaillez</a>
27
 *
28
 * @see FilterReader
29
 */
30
class BufferedReader extends Reader
31
{
32
    private $bufferSize = 0;
33
    private $buffer;
34
    private $bufferPos = 0;
35
36
    /**
37
     * The Reader we are buffering for.
38
     *
39
     * @var InputStreamReader
40
     */
41
    private $in;
42
43
    /**
44
     * @param Reader $reader   The reader (e.g. FileReader).
45
     * @param int               $buffsize The size of the buffer we should use for reading files.
46
     *                                    A large buffer ensures that most files (all scripts?)
47
     *                                    are parsed in 1 buffer.
48
     */
49
    public function __construct(Reader $reader, $buffsize = 65536)
50
    {
51
        $this->in = $reader;
0 ignored issues
show
Documentation Bug introduced by
$reader is of type Phing\Io\Reader, but the property $in was declared to be of type Phing\Io\InputStreamReader. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
52
        $this->bufferSize = $buffsize;
53
    }
54
55
    /**
56
     * Reads and returns a chunk of data.
57
     *
58
     * @param int $len Number of bytes to read.  Default is to read configured buffer size number of bytes.
59
     *
60
     * @return mixed buffer or -1 if EOF
61
     */
62
    public function read($len = null)
63
    {
64
        // if $len is specified, we'll use that; otherwise, use the configured buffer size.
65
        if (null === $len) {
66
            $len = $this->bufferSize;
67
        }
68
69
        if (($data = $this->in->read($len)) !== -1) {
70
            // not all files end with a newline character, so we also need to check EOF
71
            if (!$this->in->eof()) {
72
                $notValidPart = strrchr($data, "\n");
73
                $notValidPartSize = strlen($notValidPart);
74
75
                if ($notValidPartSize > 1) {
76
                    // Block doesn't finish on a EOL
77
                    // Find the last EOL and forget all following stuff
78
                    $dataSize = strlen($data);
79
                    $validSize = $dataSize - $notValidPartSize + 1;
80
81
                    $data = substr($data, 0, $validSize);
82
83
                    // Rewind to the beginning of the forgotten stuff.
84
                    $this->in->skip(-$notValidPartSize + 1);
85
                }
86
            } // if !EOF
87
        }
88
89
        return $data;
90
    }
91
92
    /**
93
     * @param int $n
94
     *
95
     * @return int
96
     */
97
    public function skip($n)
98
    {
99
        return $this->in->skip($n);
100
    }
101
102
    public function reset()
103
    {
104
        $this->in->reset();
105
    }
106
107
    public function close()
108
    {
109
        $this->in->close();
110
    }
111
112
    /**
113
     * Read a line from input stream.
114
     */
115
    public function readLine()
116
    {
117
        $line = null;
118
        while (($ch = $this->readChar()) !== -1) {
119
            if ("\n" === $ch) {
120
                $line = rtrim((string) $line);
121
122
                break;
123
            }
124
            $line .= $ch;
125
        }
126
127
        // Warning : Not considering an empty line as an EOF
128
        if (null === $line && -1 !== $ch) {
129
            return '';
130
        }
131
132
        return $line;
133
    }
134
135
    /**
136
     * Reads a single char from the reader.
137
     *
138
     * @return string single char or -1 if EOF
139
     */
140
    public function readChar()
141
    {
142
        if (null === $this->buffer) {
143
            // Buffer is empty, fill it ...
144
            $read = $this->in->read($this->bufferSize);
145
            if (-1 === $read) {
146
                $ch = -1;
147
            } else {
148
                $this->buffer = $read;
149
150
                return $this->readChar(); // recurse
151
            }
152
        } else {
153
            // Get next buffered char ...
154
            // handle case where buffer is read-in, but is empty.  The next readChar() will return -1 EOF,
155
            // so we just return empty string (char) at this point.  (Probably could also return -1 ...?)
156
            $ch = ('' !== $this->buffer) ? $this->buffer[$this->bufferPos] : '';
157
            ++$this->bufferPos;
158
            if ($this->bufferPos >= strlen($this->buffer)) {
159
                $this->buffer = null;
160
                $this->bufferPos = 0;
161
            }
162
        }
163
164
        return $ch;
165
    }
166
167
    /**
168
     * Returns whether eof has been reached in stream.
169
     * This is important, because filters may want to know if the end of the file (and not just buffer)
170
     * has been reached.
171
     *
172
     * @return bool
173
     */
174
    public function eof()
175
    {
176
        return $this->in->eof();
177
    }
178
179
    /**
180
     * @return string
181
     */
182
    public function getResource()
183
    {
184
        return $this->in->getResource();
185
    }
186
}
187