Completed
Push — master ( 7a51d1...ff4d30 )
by Maik
01:43
created

MemoryStream::isWriteable()   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 0
crap 1
1
<?php
2
3
/**
4
 * This file is part of the PHP Generics package.
5
 *
6
 * @package Generics
7
 */
8
namespace Generics\Streams;
9
10
use Generics\Util\Interpolator;
11
12
/**
13
 * This class provides a memory stream for both input and output
14
 *
15
 * @author Maik Greubel <[email protected]>
16
 */
17
class MemoryStream implements InputOutputStream
18
{
19
    use Interpolator {
20
        interpolate as tinterpolate;
21
    }
22
23
    /**
24
     * The local memory buffer
25
     *
26
     * @var string
27
     */
28
    private $memory;
29
30
    /**
31
     * Current position in memory buffer
32
     *
33
     * @var int
34
     */
35
    private $current;
36
37
    /**
38
     * Whether it is possible to perform reading action
39
     *
40
     * @var boolean
41
     */
42
    private $ready;
43
44
    /**
45
     * Whether stream is closed
46
     *
47
     * @var boolean
48
     */
49
    private $closed;
50
51
    /**
52
     * Create a new MemoryStream
53
     *
54
     * @param InputStream $in
55
     *            optional existing input stream - will be copied
56
     */
57 35
    public function __construct(InputStream $in = null)
58
    {
59 35
        $this->memory = "";
60 35
        if ($in != null) {
61 1
            $copy = clone $in;
62 1
            $copy->reset();
63 1
            while ($copy->ready()) {
64 1
                $this->memory .= $copy->read();
65
            }
66 1
            $copy->close();
67
        }
68 35
        $this->current = 0;
69 35
        $this->ready = true;
70 35
        $this->closed = false;
71 35
    }
72
73
    /**
74
     *
75
     * {@inheritdoc}
76
     * @see \Generics\Streams\Stream::close()
77
     */
78 5
    public function close()
79
    {
80 5
        unset($this->memory);
81 5
        $this->current = 0;
82 5
        $this->ready = false;
83 5
        $this->closed = true;
84 5
    }
85
86
    /**
87
     *
88
     * {@inheritdoc}
89
     * @see \Generics\Streams\Stream::ready()
90
     */
91 25
    public function ready()
92
    {
93 25
        return $this->ready;
94
    }
95
96
    /**
97
     *
98
     * {@inheritdoc}
99
     * @see \Generics\Streams\OutputStream::write()
100
     */
101 33
    public function write($buffer)
102
    {
103 33
        if ($this->closed) {
104 1
            throw new StreamException("Stream is not open");
105
        }
106 32
        $this->memory .= $buffer;
107 32
        $this->ready = true;
108 32
    }
109
110
    /**
111
     *
112
     * {@inheritdoc}
113
     * @see \Generics\Streams\InputStream::read()
114
     */
115 28
    public function read($length = 1, $offset = null)
116
    {
117 28
        if ($this->closed) {
118 1
            throw new StreamException("Stream is not open");
119
        }
120
        
121 27
        if ($offset !== null) {
122
            $this->current = intval($offset);
123
        }
124
        
125 27
        if (strlen($this->memory) <= $this->current) {
126 10
            $this->ready = false;
127 10
            return "";
128
        }
129
        
130 27
        if (strlen($this->memory) - $this->current < $length) {
131 27
            $length = strlen($this->memory) - $this->current;
132
        }
133
        
134 27
        $out = substr($this->memory, $this->current, $length);
135 27
        $this->current += $length;
136
        
137 27
        if ($this->current == strlen($this->memory)) {
138 27
            $this->ready = false;
139
        }
140
        
141 27
        return $out;
142
    }
143
144
    /**
145
     *
146
     * {@inheritdoc}
147
     * @see \Countable::count()
148
     */
149 13
    public function count()
150
    {
151 13
        if ($this->closed) {
152 1
            throw new StreamException("Stream is not open");
153
        }
154 12
        if (! isset($this->memory)) {
155
            return 0;
156
        }
157 12
        return strlen($this->memory);
158
    }
159
160
    /**
161
     *
162
     * {@inheritdoc}
163
     * @see \Generics\Resettable::reset()
164
     */
165 13
    public function reset()
166
    {
167 13
        if ($this->closed) {
168 1
            throw new StreamException("Stream is not open");
169
        }
170 12
        $this->current = 0;
171 12
        $this->ready = true;
172 12
    }
173
174
    /**
175
     * Write to stream by interpolation of context vars into a string
176
     *
177
     * @param string $string
178
     *            The string to interpolate, may contains placeholders in format {placeholder}.
179
     * @param array $context
180
     *            The context array containing the associative replacers and its values.
181
     */
182 24
    public function interpolate($string, array $context)
183
    {
184 24
        $this->write($this->tinterpolate($string, $context));
185 24
    }
186
187
    /**
188
     *
189
     * {@inheritdoc}
190
     * @see \Generics\Streams\OutputStream::isWriteable()
191
     */
192 1
    public function isWriteable()
193
    {
194 1
        return true;
195
    }
196
197
    /**
198
     *
199
     * {@inheritdoc}
200
     * @see \Generics\Streams\OutputStream::flush()
201
     */
202 4
    public function flush()
203
    {
204 4
        if ($this->closed) {
205 1
            throw new StreamException("Stream is not open");
206
        }
207
        
208 3
        unset($this->memory);
209 3
        $this->memory = "";
210 3
        $this->reset();
211 3
    }
212
213
    /**
214
     *
215
     * {@inheritdoc}
216
     * @see \Generics\Streams\Stream::isOpen()
217
     */
218
    public function isOpen()
219
    {
220
        return true;
221
    }
222
}
223