Completed
Push — master ( 368df1...25b1b2 )
by Michele
05:24 queued 02:41
created

FileReader::getPosition()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2.032

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 9
ccs 4
cts 5
cp 0.8
rs 9.6666
cc 2
eloc 5
nc 2
nop 0
crap 2.032
1
<?php
2
3
namespace CHMLib\Reader;
4
5
use Exception;
6
7
/**
8
 * Read data from a file.
9
 */
10
class FileReader extends Reader
11
{
12
    /**
13
     * The file name.
14
     *
15
     * @var string
16
     */
17
    protected $filename;
18
19
    /**
20
     * The file size.
21
     *
22
     * @var int
23
     */
24
    protected $length;
25
26
    /**
27
     * The open file descriptor.
28
     *
29
     * @var resource
30
     */
31
    protected $fd;
32
33
    /**
34
     * Initializes the instance.
35
     *
36
     * @param string $filename The file name to be read.
37
     *
38
     * @throws Exception Throws an Exception in case of errors.
39
     */
40 1
    public function __construct($filename)
41
    {
42 1
        $this->filename = $filename;
43 1
        if (!is_file($this->filename)) {
44
            throw new Exception('File not found: '.$this->filename);
45
        }
46 1
        if (!is_readable($this->filename)) {
47
            throw new Exception('File not readable: '.$this->filename);
48
        }
49 1
        $this->length = @filesize($this->filename);
50 1
        if ($this->length === false || $this->length < 0) {
51
            throw new Exception('Failed to retrieve the size of the file '.$this->filename);
52
        }
53 1
        $this->fd = @fopen($this->filename, 'rb');
54 1
        if ($this->fd === false) {
55
            $this->fd = null;
56
            throw new Exception('Failed to open file '.$this->filename);
57
        }
58 1
    }
59
60
    /**
61
     * Destruct the instance.
62
     */
63
    public function __destruct()
64
    {
65
        if (isset($this->fd)) {
66
            @fclose($this->fd);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
67
            $this->fd = null;
68
        }
69
    }
70
71
    /**
72
     * {@inheritdoc}
73
     *
74
     * @see Reader::setPosition()
75
     */
76 24
    public function setPosition($position)
77
    {
78 24
        if (@fseek($this->fd, $position, SEEK_SET) !== 0) {
79
            throw new Exception('Failed to seek file to to position '.$position);
80
        }
81 24
    }
82
83
    /**
84
     * {@inheritdoc}
85
     *
86
     * @see Reader::getPosition()
87
     */
88 1
    public function getPosition()
89
    {
90 1
        $result = @ftell($this->fd);
91 1
        if ($result === false) {
92
            throw new Exception('Failed to get the current file position');
93
        }
94
95 1
        return $result;
96
    }
97
98
    /**
99
     * {@inheritdoc}
100
     *
101
     * @see Reader::getLength()
102
     */
103 1
    public function getLength()
104
    {
105 1
        return $this->length;
106
    }
107
108
    /**
109
     * {@inheritdoc}
110
     *
111
     * @see Reader::readString()
112
     */
113 24
    public function readString($length)
114
    {
115 24
        if ($length === 0) {
116
            $result = '';
117
        } else {
118 24
            $result = @fread($this->fd, $length);
119 24
            if ($result === false || strlen($result) !== $length) {
120
                throw new Exception('Read after end-of-file');
121
            }
122
        }
123
124 24
        return $result;
125
    }
126
}
127