Completed
Push — master ( 6b6f0c...23d46a )
by Pol
02:54
created

File::truncate()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 4
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 7
ccs 5
cts 5
cp 1
crap 2
rs 10
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace drupol\phpvfs\Node;
6
7
use drupol\phpvfs\Utils\Path;
8
9
/**
10
 * Class File.
11
 */
12
class File extends FilesystemNode implements FileInterface
13
{
14
    /**
15
     * File constructor.
16
     *
17
     * @param array $attributes
18
     */
19 13
    public function __construct(
20
        array $attributes = []
21
    ) {
22
        $attributes += [
23 13
            'content' => '',
24
            'position' => 0,
25
        ];
26
27 13
        parent::__construct($attributes, null);
28 13
    }
29
30
    /**
31
     * @return bool
32
     */
33 1
    public function atEof()
34
    {
35 1
        return $this->getPosition() >= \strlen($this->getAttribute('content'));
36
    }
37
38
    /**
39
     * @param string $id
40
     * @param string $content
41
     * @param array $attributes
42
     *
43
     * @throws \Exception
44
     *
45
     * @return \drupol\phpvfs\Node\File
46
     */
47 12
    public static function create(string $id, string $content = '', array $attributes = [])
48
    {
49 12
        $path = Path::fromString($id);
50
51 12
        $dirname = $path->dirname();
52
53 12
        $basedir = null;
54 12
        if (!empty($dirname) && '.' !== $dirname) {
55 11
            $basedir = Directory::create($dirname);
56
        }
57
58
        $attributes = [
59 12
            'id' => $path->basename(),
60 12
            'content' => $content,
61 12
        ] + $attributes;
62
63 12
        $file = new self($attributes);
64
65 12
        if (null !== $basedir) {
66 11
            $basedir->add($file);
67
        }
68
69 12
        return $file;
70
    }
71
72
    /**
73
     * @return int
74
     */
75 7
    public function getPosition(): int
76
    {
77 7
        return $this->getAttribute('position');
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getAttribute('position') could return the type null which is incompatible with the type-hinted return integer. Consider adding an additional type-check to rule them out.
Loading history...
78
    }
79
80
    /**
81
     * @param int $bytes
82
     *
83
     * @return string
84
     */
85 3
    public function read(int $bytes): string
86
    {
87 3
        $data = \substr(
88 3
            $this->getAttribute('content'),
89 3
            $this->getPosition(),
90 3
            $bytes
91
        );
92
93 3
        $this->offsetPosition($bytes);
94
95 3
        return $data;
96
    }
97
98
    /**
99
     * {@inheritdoc}
100
     */
101 1
    public function seekToEnd()
102
    {
103 1
        return $this->setPosition(
104 1
            \strlen($this->getAttribute('content'))
105
        );
106
    }
107
108
    /**
109
     * @param int $position
110
     *
111
     * @return $this
112
     */
113 7
    public function setPosition(int $position): FileInterface
114
    {
115 7
        $this->setAttribute('position', $position);
116
117 7
        return $this;
118
    }
119
120
    /**
121
     * @return int
122
     */
123 7
    public function size(): int
124
    {
125 7
        return \strlen($this->getAttribute('content'));
126
    }
127
128
    /**
129
     * @param int $bytes
130
     */
131 5
    public function truncate(int $bytes = 0)
132
    {
133 5
        $this->setPosition(0);
134 5
        $newData = \substr($this->getAttribute('content'), 0, $bytes);
135
136 5
        if (\is_string($newData)) {
0 ignored issues
show
introduced by
The condition is_string($newData) is always true.
Loading history...
137 5
            $this->setAttribute('content', $newData);
138
        }
139 5
    }
140
141
    /**
142
     * @param string $data
143
     *
144
     * @return int
145
     */
146 6
    public function write(string $data): int
147
    {
148 6
        $content = $this->getAttribute('content');
149 6
        $content = \substr($content, 0, $this->getPosition());
150
151 6
        $content .= $data;
152 6
        $this->setAttribute('content', $content);
153
154 6
        $written = \strlen($data);
155 6
        $this->offsetPosition($written);
156
157 6
        return $written;
158
    }
159
160
    /**
161
     * @param int $offset
162
     *
163
     * @return int
164
     */
165 7
    protected function offsetPosition($offset): int
166
    {
167 7
        $contentSize = $this->size();
168 7
        $newPosition = $this->getPosition() + $offset;
169
170 7
        $newPosition = $contentSize < $newPosition ?
171 3
            $contentSize :
172 7
            $newPosition;
173
174 7
        $this->setPosition($newPosition);
175
176 7
        return $newPosition;
177
    }
178
}
179