Passed
Pull Request — psr-implementation (#46)
by Martino Catur
01:37
created

BufferStream   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 156
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 33
dl 0
loc 156
rs 10
c 0
b 0
f 0
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
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
    private $hwm;
20
21
    private $buffer = '';
22
23
    /**
24
     * @param int $hwm High water mark, representing the preferred maximum
25
     *                 buffer size. If the size of the buffer exceeds the high
26
     *                 water mark, then calls to write will continue to succeed
27
     *                 but will return false to inform writers to slow down
28
     *                 until the buffer has been drained by reading from it.
29
     */
30
    public function __construct($hwm = 16384)
31
    {
32
        $this->hwm = $hwm;
33
    }
34
35
    /**
36
     * @inheritdoc
37
     */
38
    public function __toString()
39
    {
40
        return $this->getContents();
41
    }
42
    
43
    /**
44
     * @inheritdoc
45
     */
46
    public function getContents()
47
    {
48
        $buffer = $this->buffer;
49
        $this->buffer = '';
50
        return $buffer;
51
    }
52
53
    /**
54
     * @inheritdoc
55
     */
56
    public function close()
57
    {
58
        $this->buffer = '';
59
    }
60
61
    /**
62
     * @inheritdoc
63
     */
64
    public function detach()
65
    {
66
        $this->close();
67
    }
68
69
    /**
70
     * @inheritdoc
71
     */
72
    public function getSize()
73
    {
74
        return strlen($this->buffer);
75
    }
76
77
    /**
78
     * @inheritdoc
79
     */
80
    public function isReadable()
81
    {
82
        return true;
83
    }
84
85
    /**
86
     * @inheritdoc
87
     */
88
    public function isWritable()
89
    {
90
        return true;
91
    }
92
93
    /**
94
     * @inheritdoc
95
     */
96
    public function isSeekable()
97
    {
98
        return false;
99
    }
100
101
    /**
102
     * @inheritdoc
103
     */
104
    public function rewind()
105
    {
106
        $this->seek(0);
107
    }
108
109
    /**
110
     * @inheritdoc
111
     */
112
    public function seek($offset, $whence = SEEK_SET)
113
    {
114
        throw new \RuntimeException('Cannot seek a BufferStream');
115
    }
116
117
    /**
118
     * @inheritdoc
119
     */
120
    public function eof()
121
    {
122
        return strlen($this->buffer) === 0;
123
    }
124
125
    /**
126
     * @inheritdoc
127
     */
128
    public function tell()
129
    {
130
        throw new \RuntimeException('Cannot determine the position of a BufferStream');
131
    }
132
133
    /**
134
     * @inheritdoc
135
     */
136
    public function read($length)
137
    {
138
        $currentLength = strlen($this->buffer);
139
        if ($length >= $currentLength) {
140
            // No need to slice the buffer because we don't have enough data.
141
            $result = $this->buffer;
142
            $this->buffer = '';
143
        } else {
144
            // Slice up the result to provide a subset of the buffer.
145
            $result = substr($this->buffer, 0, $length);
146
            $this->buffer = substr($this->buffer, $length);
147
        }
148
        return $result;
149
    }
150
151
    /**
152
     * @inheritdoc
153
     */
154
    public function write($string)
155
    {
156
        $this->buffer .= $string;
157
        // TODO: What should happen here?
158
        if (strlen($this->buffer) >= $this->hwm) {
159
            throw new \RuntimeException('Fail');
160
        }
161
        return strlen($string);
162
    }
163
164
    /**
165
     * @inheritdoc
166
     */
167
    public function getMetadata($key = null)
168
    {
169
        if ($key == 'hwm') {
170
            return $this->hwm;
171
        }
172
        return $key ? null : [];
173
    }
174
}
175