Completed
Push — master ( 0a5b37...5c1aea )
by Luke
02:18
created

IsReadable::readLine()   C

Complexity

Conditions 7
Paths 8

Size

Total Lines 24
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 7

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 24
ccs 17
cts 17
cp 1
rs 6.7272
cc 7
eloc 16
nc 8
nop 2
crap 7
1
<?php
2
/**
3
 * CSVelte: Slender, elegant CSV for PHP.
4
 *
5
 * Inspired by Python's CSV module and Frictionless Data and the W3C's CSV
6
 * standardization efforts, CSVelte was written in an effort to take all the
7
 * suck out of working with CSV.
8
 *
9
 * @version   v0.2
10
 * @copyright Copyright (c) 2016 Luke Visinoni <[email protected]>
11
 * @author    Luke Visinoni <[email protected]>
12
 * @license   https://github.com/deni-zen/csvelte/blob/master/LICENSE The MIT License (MIT)
13
 */
14
namespace CSVelte\Traits;
15
16
use CSVelte\Exception\IOException;
17
18
/**
19
 * IO IsReadable Trait.
20
 *
21
 * Read methods shared between CSVelte\IO classes.
22
 *
23
 * @package    CSVelte
24
 * @subpackage CSVelte\Traits
25
 * @copyright  (c) 2016, Luke Visinoni <[email protected]>
26
 * @author     Luke Visinoni <[email protected]>
27
 * @since      v0.2
28
 */
29
trait IsReadable
30
{
31
    /**
32
     * Read single line.
33
     * Read the next line from the file (moving the internal pointer down a line).
34
     * Returns multiple lines if newline character(s) fall within a quoted string.
35
     *
36
     * @param string|array A string or array of strings to be used as EOL char/sequence
37
     * @param int Maximum number of bytes to return (line will be truncated to this -1 if set)
38
     * @return string A single line read from the file.
39
     * @throws CSVelte\Exception\IOException
40
     * @todo Should this add a newline if maxlength is reached?
41
     * @todo I could actually buffer this by reading x chars at a time and doing
42
     *     the same thing with looping char by char if this is too IO intensive.
43
     */
44 25
    public function readLine($eol = PHP_EOL, $maxLength = null)
45
    {
46 25
        $size = 0;
47 25
        $buffer = false;
48 25
        if (!is_array($eol)) $eol = array($eol);
49 25
        while (!$this->eof()) {
50
            // Using a loose equality here to match on '' and false.
51 25
            if (null == ($byte = $this->read(1))) {
52 3
                return $buffer;
53
            }
54 25
            $buffer .= $byte;
55
            // Break when a new line is found or the max length - 1 is reached
56 25
            if (array_reduce($eol, function($carry, $eol) use ($buffer) {
57 25
                if (!$carry) {
58 25
                    $eollen = 0 - strlen($eol);
59 25
                    return (substr($buffer, $eollen) === $eol);
60
                }
61 1
                return true;
62 25
            }, false) || ++$size === $maxLength - 1) {
63 24
                break;
64
            }
65 25
        }
66 25
        return $buffer;
67
    }
68
69
    /**
70
     * Assert that this file/stream object is readable.
71
     *
72
     * @return void
73
     * @throws CSVelte\Exception\IOException if stream isn't readable
74
     */
75 42
    protected function assertIsReadable()
76
    {
77 42
        if (!$this->isReadable()) {
78 2
            throw new IOException("Stream not readable: " . $this->getName(), IOException::ERR_NOT_READABLE);
79
        }
80 40
    }
81
82
    abstract public function getName();
83
84
    abstract public function isReadable();
85
86
    abstract public function read($length);
87
88
    abstract public function eof();
89
90
}
91