BufferStream   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 164
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 33
c 1
b 0
f 0
dl 0
loc 164
rs 10
wmc 20

16 Methods

Rating   Name   Duplication   Size   Complexity  
A seek() 0 3 1
A getMetadata() 0 6 3
A __toString() 0 3 1
A eof() 0 3 1
A close() 0 3 1
A isWritable() 0 3 1
A detach() 0 3 1
A write() 0 8 2
A tell() 0 3 1
A rewind() 0 3 1
A getSize() 0 3 1
A isReadable() 0 3 1
A getContents() 0 5 1
A __construct() 0 3 1
A read() 0 13 2
A isSeekable() 0 3 1
1
<?php declare(strict_types=1);
2
3
namespace One\Http;
4
5
use Psr\Http\Message\StreamInterface;
6
7
/**
8
 * Provides a buffer stream that can be written to to fill a buffer, and read
9
 * from to remove bytes from the buffer.
10
 *
11
 * This stream returns a "hwm" metadata value that tells upstream consumers
12
 * what the configured high water mark of the stream is, or the maximum
13
 * preferred size of the buffer.
14
 * @property mixed $hwm
15
 * @property mixed $buffer
16
 */
17
class BufferStream implements StreamInterface
18
{
19
    /**
20
     * High water mark
21
     * @var int
22
     */
23
    private $hwm;
24
25
    /**
26
     * buffer
27
     * @var string
28
     */
29
    private $buffer = '';
30
31
    /**
32
     * @param int $hwm High water mark, representing the preferred maximum
33
     *                 buffer size. If the size of the buffer exceeds the high
34
     *                 water mark, then calls to write will continue to succeed
35
     *                 but will return false to inform writers to slow down
36
     *                 until the buffer has been drained by reading from it.
37
     */
38
    public function __construct(int $hwm = 16384)
39
    {
40
        $this->hwm = $hwm;
41
    }
42
43
    /**
44
     * @inheritdoc
45
     */
46
    public function __toString()
47
    {
48
        return $this->getContents();
49
    }
50
51
    /**
52
     * @inheritdoc
53
     */
54
    public function getContents()
55
    {
56
        $buffer = $this->buffer;
57
        $this->buffer = '';
58
        return $buffer;
59
    }
60
61
    /**
62
     * @inheritdoc
63
     */
64
    public function close(): void
65
    {
66
        $this->buffer = '';
67
    }
68
69
    /**
70
     * @inheritdoc
71
     */
72
    public function detach(): void
73
    {
74
        $this->close();
75
    }
76
77
    /**
78
     * @inheritdoc
79
     */
80
    public function getSize()
81
    {
82
        return strlen($this->buffer);
83
    }
84
85
    /**
86
     * @inheritdoc
87
     */
88
    public function isReadable()
89
    {
90
        return true;
91
    }
92
93
    /**
94
     * @inheritdoc
95
     */
96
    public function isWritable()
97
    {
98
        return true;
99
    }
100
101
    /**
102
     * @inheritdoc
103
     */
104
    public function isSeekable()
105
    {
106
        return false;
107
    }
108
109
    /**
110
     * @inheritdoc
111
     */
112
    public function rewind(): void
113
    {
114
        $this->seek(0);
115
    }
116
117
    /**
118
     * @inheritdoc
119
     */
120
    public function seek($offset, $whence = SEEK_SET): void
121
    {
122
        throw new \RuntimeException('Cannot seek a BufferStream');
123
    }
124
125
    /**
126
     * @inheritdoc
127
     */
128
    public function eof()
129
    {
130
        return strlen($this->buffer) === 0;
131
    }
132
133
    /**
134
     * @inheritdoc
135
     */
136
    public function tell(): void
137
    {
138
        throw new \RuntimeException('Cannot determine the position of a BufferStream');
139
    }
140
141
    /**
142
     * @inheritdoc
143
     */
144
    public function read($length)
145
    {
146
        $currentLength = strlen($this->buffer);
147
        if ($length >= $currentLength) {
148
            // No need to slice the buffer because we don't have enough data.
149
            $result = $this->buffer;
150
            $this->buffer = '';
151
        } else {
152
            // Slice up the result to provide a subset of the buffer.
153
            $result = substr($this->buffer, 0, $length);
154
            $this->buffer = substr($this->buffer, $length);
155
        }
156
        return $result;
157
    }
158
159
    /**
160
     * @inheritdoc
161
     */
162
    public function write($string)
163
    {
164
        $this->buffer .= $string;
165
        // TODO: What should happen here?
166
        if (strlen($this->buffer) >= $this->hwm) {
167
            throw new \RuntimeException('Fail');
168
        }
169
        return strlen($string);
170
    }
171
172
    /**
173
     * @inheritdoc
174
     */
175
    public function getMetadata($key = null)
176
    {
177
        if ($key === 'hwm') {
178
            return $this->hwm;
179
        }
180
        return $key ? null : [];
181
    }
182
}
183