Completed
Push — master ( 04ea00...5840b0 )
by Frederik
02:29
created

Base64EncodedStream::getMetadata()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
declare(strict_types=1);
3
4
namespace Genkgo\Mail\Stream;
5
6
use Genkgo\Mail\StreamInterface;
7
8
final class Base64EncodedStream implements StreamInterface
9
{
10
    /**
11
     * @var StreamInterface
12
     */
13
    private $decoratedStream;
14
    /**
15
     * @var int
16
     */
17
    private $lineLength;
18
    /**
19
     * @var resource
20
     */
21
    private $filter;
22
    /**
23
     * @var string
24
     */
25
    private $lineBreak;
26
27
    /**
28
     * Base64EncodedStream constructor.
29
     * @param resource $resource
30
     * @param int $lineLength
31
     * @param string $lineBreak
32
     */
33 47
    public function __construct($resource, int $lineLength = 76, string $lineBreak = "\r\n")
34
    {
35 47
        $this->decoratedStream = new ResourceStream($resource);
36 47
        $this->lineLength = $lineLength;
37 47
        $this->lineBreak = $lineBreak;
38
39 47
        $this->applyFilter();
40 47
    }
41
42
    /**
43
     * @param string $string
44
     * @param int $lineLength
45
     * @param string $lineBreak
46
     * @return Base64EncodedStream
47
     */
48 23
    public static function fromString(string $string, int $lineLength = 76, string $lineBreak = "\r\n"): Base64EncodedStream
49
    {
50 23
        $resource = fopen('php://memory', 'r+');
51 23
        fwrite($resource, $string);
52 23
        return new self($resource, $lineLength, $lineBreak);
53
    }
54
55
    /**
56
     *
57
     */
58 47
    private function applyFilter(): void
59
    {
60 47
        $this->filter = stream_filter_prepend(
61 47
            $this->decoratedStream->detach(),
62 47
            'convert.base64-encode',
63 47
            STREAM_FILTER_READ,
64
            [
65 47
                'line-length' => $this->lineLength,
66 47
                'line-break-chars' => $this->lineBreak
67
            ]
68
        );
69 47
    }
70
71 12
    private function removeFilter(): void
72
    {
73 12
        if ($this->filter !== null) {
74 12
            stream_filter_remove($this->filter);
75
        }
76 12
    }
77
78
    /**
79
     * @return string
80
     */
81 11
    public function __toString(): string
82
    {
83 11
        $this->rewind();
84 11
        return $this->decoratedStream->__toString();
85
    }
86
87
    /**
88
     *
89
     */
90
    public function close(): void
91
    {
92
        $this->decoratedStream->close();
93
    }
94
95
    /**
96
     * @return mixed
97
     */
98
    public function detach()
99
    {
100
        return $this->decoratedStream->detach();
101
    }
102
103
    /**
104
     * @return int|null
105
     */
106 3
    public function getSize(): ?int
107
    {
108 3
        return (int) ceil($this->decoratedStream->getSize() / 3) * 4;
109
    }
110
111
    /**
112
     * @return int
113
     * @throws \RuntimeException
114
     */
115 1
    public function tell(): int
116
    {
117 1
        return $this->decoratedStream->tell();
118
    }
119
120
    /**
121
     * @return bool
122
     */
123 1
    public function eof(): bool
124
    {
125 1
        return $this->decoratedStream->eof();
126
    }
127
128
    /**
129
     * @return bool
130
     */
131
    public function isSeekable(): bool
132
    {
133
        return false;
134
    }
135
136
    /**
137
     * @param int $offset
138
     * @param int $whence
139
     * @return int
140
     */
141 1
    public function seek(int $offset, int $whence = SEEK_SET): int
142
    {
143 1
        return -1;
144
    }
145
146
    /**
147
     * @return bool
148
     */
149 12
    public function rewind(): bool
150
    {
151 12
        $this->removeFilter();
152 12
        if (!$this->decoratedStream->rewind()) {
153
            return false;
154
        }
155
156 12
        $this->applyFilter();
157 12
        return true;
158
    }
159
160
    /**
161
     * @return bool
162
     */
163 1
    public function isWritable(): bool
164
    {
165 1
        return false;
166
    }
167
168
    /**
169
     * @param $string
170
     * @return int
171
     */
172 1
    public function write($string): int
173
    {
174 1
        throw new \RuntimeException('Cannot write to stream');
175
    }
176
177
    /**
178
     * @return bool
179
     */
180
    public function isReadable(): bool
181
    {
182
        return true;
183
    }
184
185
    /**
186
     * @param int $length
187
     * @return string
188
     */
189 2
    public function read(int $length): string
190
    {
191 2
        return $this->decoratedStream->read($length);
192
    }
193
194
    /**
195
     * @return string
196
     */
197 2
    public function getContents(): string
198
    {
199 2
        return $this->decoratedStream->getContents();
200
    }
201
202
    /**
203
     * @param array $keys
204
     * @return array
205
     */
206 16
    public function getMetadata(array $keys = []): array
207
    {
208 16
        return $this->decoratedStream->getMetadata();
209
    }
210
}