Completed
Push — master ( e58835...7cb891 )
by Frederik
02:40
created

QuotedPrintableDecodedStream::getSize()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

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
nc 1
nop 0
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 QuotedPrintableDecodedStream implements StreamInterface
9
{
10
    /**
11
     * @var StreamInterface
12
     */
13
    private $decoratedStream;
14
15
    /**
16
     * @var resource
17
     */
18
    private $filter;
19
20
    /**
21
     * @param resource $resource
22
     */
23 9
    public function __construct($resource)
24
    {
25 9
        $this->decoratedStream = new ResourceStream($resource);
26
27 9
        $this->applyFilter();
28 9
    }
29
30
    /**
31
     * @param string $string
32
     * @return QuotedPrintableDecodedStream
33
     */
34 9
    public static function fromString(string $string): QuotedPrintableDecodedStream
35
    {
36 9
        $resource = \fopen('php://memory', 'r+');
37 9
        if ($resource === false) {
38
            throw new \UnexpectedValueException('Cannot open php://memory for writing');
39
        }
40
41 9
        \fwrite($resource, $string);
42 9
        return new self($resource);
43
    }
44
    
45 9
    private function applyFilter(): void
46
    {
47 9
        $filter = \stream_filter_prepend(
48 9
            $this->decoratedStream->detach(),
49 9
            'convert.quoted-printable-decode',
50 9
            STREAM_FILTER_READ
51
        );
52
53 9
        if ($filter === false) {
54
            throw new \UnexpectedValueException('Cannot append filter to stream');
55
        }
56
57 9
        $this->filter = $filter;
58 9
    }
59
    
60 4
    private function removeFilter(): void
61
    {
62 4
        if ($this->filter !== null) {
63 4
            \stream_filter_remove($this->filter);
64
        }
65 4
    }
66
67
    /**
68
     * @return string
69
     */
70 3
    public function __toString(): string
71
    {
72 3
        $this->rewind();
73 3
        return $this->decoratedStream->__toString();
74
    }
75
    
76
    public function close(): void
77
    {
78
        $this->decoratedStream->close();
79
    }
80
81
    /**
82
     * @return mixed
83
     */
84
    public function detach()
85
    {
86
        return $this->decoratedStream->detach();
87
    }
88
89
    /**
90
     * @return int|null
91
     */
92 1
    public function getSize(): ?int
93
    {
94 1
        return null;
95
    }
96
97
    /**
98
     * @return int
99
     * @throws \RuntimeException
100
     */
101 1
    public function tell(): int
102
    {
103 1
        return $this->decoratedStream->tell();
104
    }
105
106
    /**
107
     * @return bool
108
     */
109
    public function eof(): bool
110
    {
111
        return $this->decoratedStream->eof();
112
    }
113
114
    /**
115
     * @return bool
116
     */
117
    public function isSeekable(): bool
118
    {
119
        return false;
120
    }
121
122
    /**
123
     * @param int $offset
124
     * @param int $whence
125
     * @return int
126
     */
127 1
    public function seek(int $offset, int $whence = SEEK_SET): int
128
    {
129 1
        return -1;
130
    }
131
132
    /**
133
     * @return bool
134
     */
135 4
    public function rewind(): bool
136
    {
137 4
        $this->removeFilter();
138 4
        if (!$this->decoratedStream->rewind()) {
139
            return false;
140
        }
141
142 4
        $this->applyFilter();
143 4
        return true;
144
    }
145
146
    /**
147
     * @return bool
148
     */
149 1
    public function isWritable(): bool
150
    {
151 1
        return false;
152
    }
153
154
    /**
155
     * @param string $string
156
     * @return int
157
     */
158 1
    public function write($string): int
159
    {
160 1
        throw new \RuntimeException('Cannot write to stream');
161
    }
162
163
    /**
164
     * @return bool
165
     */
166
    public function isReadable(): bool
167
    {
168
        return true;
169
    }
170
171
    /**
172
     * @param int $length
173
     * @return string
174
     */
175 2
    public function read(int $length): string
176
    {
177 2
        return $this->decoratedStream->read($length);
178
    }
179
180
    /**
181
     * @return string
182
     */
183 3
    public function getContents(): string
184
    {
185 3
        return $this->decoratedStream->getContents();
186
    }
187
188
    /**
189
     * @param array<int, string> $keys
190
     * @return array<string, mixed>
0 ignored issues
show
Documentation introduced by
The doc-type array<string, could not be parsed: Expected ">" at position 5, but found "end of type". (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
191
     */
192
    public function getMetadata(array $keys = []): array
193
    {
194
        return $this->decoratedStream->getMetadata();
195
    }
196
}
197