Passed
Push — master ( 35a69c...54bf96 )
by Ryuichi
01:46
created

FileOutputStream::write()   B

Complexity

Conditions 8
Paths 8

Size

Total Lines 15
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 8.064

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 8
eloc 11
c 1
b 0
f 0
nc 8
nop 3
dl 0
loc 15
ccs 9
cts 10
cp 0.9
crap 8.064
rs 8.4444
1
<?php
2
3
namespace WebStream\IO;
4
5
use WebStream\IO\OutputStream;
6
use WebStream\Exception\Extend\InvalidArgumentException;
0 ignored issues
show
Bug introduced by
The type WebStream\Exception\Exte...nvalidArgumentException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
use WebStream\Exception\Extend\IOException;
0 ignored issues
show
Bug introduced by
The type WebStream\Exception\Extend\IOException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
9
/**
10
 * FileOutputStream
11
 * @author Ryuichi TANAKA.
12
 * @since 2016/02/24
13
 * @version 0.7
14
 */
15
class FileOutputStream extends OutputStream
16
{
17
    /**
18
     * @var File ファイルオブジェクト
19
     */
20
    protected $file;
21
22
    /**
23
     * constructor
24
     * @param mixed $file ファイルオブジェクトまたはファイルパス
25
     * @param bool $isAppend 追記フラグ
26
     * @throws InvalidArgumentException
27
     * @throws IOException
28
     */
29 12
    public function __construct($file, bool $isAppend = false)
30
    {
31
        $filepath = null;
32 12
        if ($file instanceof File) {
33 2
            $this->file = $file;
34 2
            $filepath = $this->file->getFilePath();
35 10
        } elseif (is_string($file)) {
36 9
            if (!file_exists($file)) {
37 9
                $dirname = dirname($file);
38 9
                $dir = new File($dirname);
39 9
                if (!$dir->isWritable()) {
40
                    throw new IOException("Cannot writable: " . $dirname);
41
                }
42
            }
43 9
            $this->file = new File($file);
44 9
            $filepath = $this->file->getFilePath();
45
        } else {
46 1
            throw new InvalidArgumentException("Invalid argument type: " . $file);
47
        }
48
49 11
        $mode = $isAppend ? 'ab' : 'wb';
50 11
        $stream = fopen($filepath, $mode);
51
52 11
        if (!is_resource($stream) || $stream === false) {
53
            throw new IOException("Unable open " . $this->file->getFilePath());
54
        }
55
56 11
        if (!flock($stream, LOCK_EX | LOCK_NB)) {
57 1
            throw new IOException("Cannot lock file: " . $this->file->getFilePath());
58
        }
59
60 11
        parent::__construct($stream);
61
    }
62
63
    /**
64
     * {@inheritdoc}
65
     */
66 11
    public function write($buf, int $off = null, int $len = null)
67
    {
68
        $data = null;
69 11
        if ($off === null && $len === null) {
70 11
            $data = $buf;
71 3
        } elseif ($off !== null && $len === null) {
72 1
            $data = substr($buf, $off);
73 2
        } elseif ($off === null && $len !== null) {
74 1
            $data = substr($buf, 0, $len);
75
        } else {
76 1
            $data = substr($buf, $off, $len);
77
        }
78
79 11
        if (@fwrite($this->stream, $data) === false) {
80
            throw new IOException("Failed to write stream.");
81
        }
82
    }
83
84
    /**
85
     * {@inheritdoc}
86
     */
87 11
    public function close()
88
    {
89 11
        if ($this->stream === null) {
90 11
            return;
91
        }
92
93 11
        $this->flush();
94
95
        // PHP5.3.2以降はfcloseではロック解放されなくなり、明示的に開放する必要がある
96 11
        flock($this->stream, LOCK_UN);
97
98 11
        if (get_resource_type($this->stream) !== 'Unknown' && fclose($this->stream) === false) {
99
            throw new IOException("Cannot close output stream.");
100
        }
101
102 11
        $this->stream = null;
103
    }
104
105
    /**
106
     * {@inheritdoc}
107
     */
108 11
    public function flush()
109
    {
110 11
        if (@fflush($this->stream) === false) {
111 1
            throw new IOException("Failed to flush.");
112
        }
113
    }
114
}
115