Completed
Push — master ( 94c184...82d741 )
by Michele
08:22 queued 03:02
created

FileReader::setPosition()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.0625

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 6
ccs 3
cts 4
cp 0.75
rs 9.4285
cc 2
eloc 3
nc 2
nop 1
crap 2.0625
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 4
    public function __construct($filename)
41
    {
42 4
        $this->filename = $filename;
43 4
        if (!is_file($this->filename)) {
44
            throw new Exception('File not found: '.$this->filename);
45
        }
46 4
        if (!is_readable($this->filename)) {
47
            throw new Exception('File not readable: '.$this->filename);
48
        }
49 4
        $this->length = @filesize($this->filename);
50 4
        if ($this->length === false || $this->length < 0) {
51
            throw new Exception('Failed to retrieve the size of the file '.$this->filename);
52
        }
53 4
        $this->fd = @fopen($this->filename, 'rb');
54 4
        if ($this->fd === false) {
55
            $this->fd = null;
56
            throw new Exception('Failed to open file '.$this->filename);
57
        }
58 4
    }
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 29
    public function setPosition($position)
77
    {
78 29
        if (@fseek($this->fd, $position, SEEK_SET) !== 0) {
79
            throw new Exception('Failed to seek file to to position '.$position);
80
        }
81 29
    }
82
83
    /**
84
     * {@inheritdoc}
85
     *
86
     * @see Reader::getPosition()
87
     */
88 4
    public function getPosition()
89
    {
90 4
        $result = @ftell($this->fd);
91 4
        if ($result === false) {
92
            throw new Exception('Failed to get the current file position');
93
        }
94
95 4
        return $result;
96
    }
97
98
    /**
99
     * {@inheritdoc}
100
     *
101
     * @see Reader::getLength()
102
     */
103 4
    public function getLength()
104
    {
105 4
        return $this->length;
106
    }
107
108
    /**
109
     * {@inheritdoc}
110
     *
111
     * @see Reader::readString()
112
     */
113 29
    public function readString($length)
114
    {
115 29
        if ($length === 0) {
116
            $result = '';
117
        } else {
118 29
            $result = @fread($this->fd, $length);
119 29
            if ($result === false || strlen($result) !== $length) {
120
                throw new Exception('Read after end-of-file');
121
            }
122
        }
123
124 29
        return $result;
125
    }
126
}
127