FileOutputStream::write()   B
last analyzed

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\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...
6
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...
7
8
/**
9
 * FileOutputStream
10
 * @author Ryuichi TANAKA.
11
 * @since 2016/02/24
12
 * @version 0.7
13
 */
14
class FileOutputStream extends OutputStream
15
{
16
    /**
17
     * @var File ファイルオブジェクト
18
     */
19
    protected File $file;
20
21
    /**
22
     * constructor
23
     * @param mixed $file ファイルオブジェクトまたはファイルパス
24
     * @param bool $isAppend 追記フラグ
25
     * @throws InvalidArgumentException
26
     * @throws IOException
27
     */
28 12
    public function __construct($file, bool $isAppend = false)
29
    {
30
        $filepath = null;
31 12
        if ($file instanceof File) {
32 2
            $this->file = $file;
33 2
            $filepath = $this->file->getFilePath();
34 10
        } elseif (is_string($file)) {
35 9
            if (!file_exists($file)) {
36 9
                $dirname = dirname($file);
37 9
                $dir = new File($dirname);
38 9
                if (!$dir->isWritable()) {
39
                    throw new IOException("Cannot writable: " . $dirname);
40
                }
41
            }
42 9
            $this->file = new File($file);
43 9
            $filepath = $this->file->getFilePath();
44
        } else {
45 1
            throw new InvalidArgumentException("Invalid argument type: " . $file);
46
        }
47
48 11
        $mode = $isAppend ? 'ab' : 'wb';
49 11
        $stream = fopen($filepath, $mode);
50
51 11
        if (!is_resource($stream) || $stream === false) {
52
            throw new IOException("Unable open " . $this->file->getFilePath());
53
        }
54
55 11
        if (!flock($stream, LOCK_EX | LOCK_NB)) {
56 1
            throw new IOException("Cannot lock file: " . $this->file->getFilePath());
57
        }
58
59 11
        parent::__construct($stream);
60
    }
61
62
    /**
63
     * {@inheritdoc}
64
     */
65 11
    public function write($buf, int $off = null, int $len = null)
66
    {
67
        $data = null;
68 11
        if ($off === null && $len === null) {
69 11
            $data = $buf;
70 3
        } elseif ($off !== null && $len === null) {
71 1
            $data = substr($buf, $off);
72 2
        } elseif ($off === null && $len !== null) {
73 1
            $data = substr($buf, 0, $len);
74
        } else {
75 1
            $data = substr($buf, $off, $len);
76
        }
77
78 11
        if (@fwrite($this->stream, $data) === false) {
79
            throw new IOException("Failed to write stream.");
80
        }
81
    }
82
83
    /**
84
     * {@inheritdoc}
85
     * @throws IOException
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
     * @throws IOException
108
     */
109 11
    public function flush()
110
    {
111 11
        if (@fflush($this->stream) === false) {
112 1
            throw new IOException("Failed to flush.");
113
        }
114
    }
115
}
116