Completed
Push — master ( 25b1b2...842723 )
by Michele
07:20 queued 04:28
created

FileReader   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 117
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 58.97%

Importance

Changes 2
Bugs 1 Features 0
Metric Value
wmc 17
c 2
b 1
f 0
lcom 1
cbo 1
dl 0
loc 117
ccs 23
cts 39
cp 0.5897
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
B __construct() 0 19 6
A setPosition() 0 6 2
A getPosition() 0 9 2
A getLength() 0 4 1
A __destruct() 0 7 2
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 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