Completed
Push — master ( 7341fe...eb5914 )
by Dominik
02:44
created

SimpleStream::seek()   B

Complexity

Conditions 5
Paths 7

Size

Total Lines 18
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 18
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 12
nc 7
nop 2
1
<?php
2
3
namespace Saxulum\HttpMessage;
4
5
use Psr\Http\Message\StreamInterface;
6
7
final class SimpleStream implements StreamInterface
8
{
9
    /**
10
     * @var string
11
     */
12
    private $stream = '';
13
14
    /**
15
     * @var int
16
     */
17
    private $pointer = 0;
18
19
    /**
20
     * {@inheritdoc}
21
     */
22
    public function __toString(): string
23
    {
24
        return $this->stream;
25
    }
26
27
    /**
28
     * {@inheritdoc}
29
     */
30
    public function close()
31
    {
32
    }
33
34
    /**
35
     * {@inheritdoc}
36
     */
37
    public function detach()
38
    {
39
    }
40
41
    /**
42
     * {@inheritdoc}
43
     */
44
    public function getSize(): int
45
    {
46
        return strlen($this->stream);
47
    }
48
49
    /**
50
     * {@inheritdoc}
51
     */
52
    public function tell(): int
53
    {
54
        return $this->pointer;
55
    }
56
57
    /**
58
     * {@inheritdoc}
59
     */
60
    public function eof(): bool
61
    {
62
        return $this->pointer + 1 === $this->getSize();
63
    }
64
65
    /**
66
     * {@inheritdoc}
67
     */
68
    public function isSeekable(): bool
69
    {
70
        return true;
71
    }
72
73
    /**
74
     * {@inheritdoc}
75
     */
76
    public function seek($offset, $whence = SEEK_SET)
77
    {
78
        if (SEEK_SET === $whence) {
79
            $newPointerPosition = $offset;
80
        } elseif (SEEK_CUR === $whence) {
81
            $newPointerPosition = $this->pointer + $offset;
82
        } elseif (SEEK_END === $whence) {
83
            $newPointerPosition = $this->getSize() - 1 + $offset;
84
        } else {
85
            throw new \RuntimeException(sprintf('Unsupported whence %s', $whence));
86
        }
87
88
        if ($newPointerPosition > $this->getSize() - 1) {
89
            throw new \RuntimeException(
90
                sprintf('Invalid offset %d, max allowed %d', $newPointerPosition, $this->getSize() - 1)
91
            );
92
        }
93
    }
94
95
    /**
96
     * {@inheritdoc}
97
     */
98
    public function rewind()
99
    {
100
        $this->pointer = 0;
101
    }
102
103
    /**
104
     * {@inheritdoc}
105
     */
106
    public function isWritable(): bool
107
    {
108
        return true;
109
    }
110
111
    /**
112
     * {@inheritdoc}
113
     */
114
    public function write($string): int
115
    {
116
        $stringLength = strlen($string);
117
        for ($i = 0; $i < $stringLength; ++$i) {
118
            $this->stream[$this->pointer] = $string[$i];
119
            ++$this->pointer;
120
        }
121
122
        return $stringLength;
123
    }
124
125
    /**
126
     * {@inheritdoc}
127
     */
128
    public function isReadable(): bool
129
    {
130
        return !$this->eof();
131
    }
132
133
    /**
134
     * {@inheritdoc}
135
     */
136
    public function read($length): string
137
    {
138
        $read = '';
139
        for ($i = 0; $i < $length; ++$i) {
140
            if (isset($this->stream[$this->pointer])) {
141
                $read .= $this->stream[$this->pointer];
142
                ++$this->pointer;
143
            }
144
        }
145
146
        return $read;
147
    }
148
149
    /**
150
     * {@inheritdoc}
151
     */
152
    public function getContents(): string
153
    {
154
        $contents = '';
155
        $size = $this->getSize();
156
157
        while ($this->pointer < $size) {
158
            $contents .= $this->stream[$this->pointer];
159
            ++$this->pointer;
160
        }
161
162
        return $contents;
163
    }
164
165
    /**
166
     * {@inheritdoc}
167
     */
168
    public function getMetadata($key = null)
169
    {
170
        $metadata = [
171
            'timed_out' => false,
172
            'blocked' => false,
173
            'eof' => $this->eof(),
174
            'unread_bytes' => $this->getSize() - $this->pointer - 1,
175
            'mode' => 'rw',
176
            'seekable' => true,
177
        ];
178
179
        if (null !== $key) {
180
            return $metadata[$key] ?? null;
181
        }
182
183
        return $metadata;
184
    }
185
}
186