FileReader   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 127
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 58.97%

Importance

Changes 0
Metric Value
wmc 18
lcom 1
cbo 1
dl 0
loc 127
ccs 23
cts 39
cp 0.5897
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 19 6
A __destruct() 0 7 2
A getFilename() 0 4 1
A setPosition() 0 6 2
A getPosition() 0 9 2
A getLength() 0 4 1
A readString() 0 13 4
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
     * Get the file name.
73
     *
74
     * @return string
75
     */
76
    public function getFilename()
77
    {
78
        return $this->filename;
79
    }
80
81
    /**
82
     * {@inheritdoc}
83
     *
84
     * @see \CHMLib\Reader\Reader::setPosition()
85
     */
86 29
    public function setPosition($position)
87
    {
88 29
        if (@fseek($this->fd, $position, SEEK_SET) !== 0) {
89
            throw new Exception('Failed to seek file to to position '.$position);
90
        }
91 29
    }
92
93
    /**
94
     * {@inheritdoc}
95
     *
96
     * @see \CHMLib\Reader\Reader::getPosition()
97
     */
98 4
    public function getPosition()
99
    {
100 4
        $result = @ftell($this->fd);
101 4
        if ($result === false) {
102
            throw new Exception('Failed to get the current file position');
103
        }
104
105 4
        return $result;
106
    }
107
108
    /**
109
     * {@inheritdoc}
110
     *
111
     * @see \CHMLib\Reader\Reader::getLength()
112
     */
113 4
    public function getLength()
114
    {
115 4
        return $this->length;
116
    }
117
118
    /**
119
     * {@inheritdoc}
120
     *
121
     * @see \CHMLib\Reader\Reader::readString()
122
     */
123 29
    public function readString($length)
124
    {
125 29
        if ($length === 0) {
126
            $result = '';
127
        } else {
128 29
            $result = @fread($this->fd, $length);
129 29
            if ($result === false || strlen($result) !== $length) {
130
                throw new Exception('Read after end-of-file');
131
            }
132
        }
133
134 29
        return $result;
135
    }
136
}
137