Completed
Push — master ( 1211ab...2a8d76 )
by Alexpts
08:00
created
src/Stream.php 1 patch
Indentation   +223 added lines, -223 removed lines patch added patch discarded remove patch
@@ -23,227 +23,227 @@
 block discarded – undo
23 23
 
24 24
 class Stream implements StreamInterface
25 25
 {
26
-	/** @var resource|null A resource reference */
27
-	protected $stream = null;
28
-	protected bool $seekable = false;
29
-	protected bool $readable = false;
30
-	protected bool $writable = false;
31
-	/** @var array|mixed|void|null */
32
-	protected $uri;
33
-	/** @var int|null */
34
-	protected ?int $size = null;
35
-
36
-	protected const READ_WRITE_HASH = [
37
-		'read' => [
38
-			'r' => true, 'w+' => true, 'r+' => true, 'x+' => true, 'c+' => true,
39
-			'rb' => true, 'w+b' => true, 'r+b' => true, 'x+b' => true,
40
-			'c+b' => true, 'rt' => true, 'w+t' => true, 'r+t' => true,
41
-			'x+t' => true, 'c+t' => true, 'a+' => true,
42
-		],
43
-		'write' => [
44
-			'w' => true, 'w+' => true, 'rw' => true, 'r+' => true, 'x+' => true,
45
-			'c+' => true, 'wb' => true, 'w+b' => true, 'r+b' => true,
46
-			'x+b' => true, 'c+b' => true, 'w+t' => true, 'r+t' => true,
47
-			'x+t' => true, 'c+t' => true, 'a' => true, 'a+' => true,
48
-		],
49
-	];
50
-
51
-	/**
52
-	 * Creates a new PSR-7 stream.
53
-	 *
54
-	 * @param string|resource|StreamInterface $body
55
-	 *
56
-	 * @return StreamInterface
57
-	 *
58
-	 * @throws InvalidArgumentException
59
-	 */
60
-	public static function create($body = ''): StreamInterface
61
-	{
62
-		if ($body instanceof StreamInterface) {
63
-			return $body;
64
-		}
65
-
66
-		if (is_string($body)) {
67
-			$resource = fopen('php://temp', 'rw+');
68
-			fwrite($resource, $body);
69
-			$body = $resource;
70
-		}
71
-
72
-		if (is_resource($body)) {
73
-			$new = new self();
74
-			$new->stream = $body;
75
-			$meta = stream_get_meta_data($new->stream);
76
-			$new->seekable = $meta['seekable'] && 0 === \fseek($new->stream, 0, \SEEK_CUR);
77
-			$new->readable = isset(self::READ_WRITE_HASH['read'][$meta['mode']]);
78
-			$new->writable = isset(self::READ_WRITE_HASH['write'][$meta['mode']]);
79
-			$new->uri = $new->getMetadata('uri');
80
-
81
-			return $new;
82
-		}
83
-
84
-		throw new InvalidArgumentException('First argument to Stream::create() must be a string, resource or StreamInterface.');
85
-	}
86
-
87
-	/**
88
-	 * Closes the stream when the destructed.
89
-	 */
90
-	public function __destruct()
91
-	{
92
-		$this->close();
93
-	}
94
-
95
-	public function __toString(): string
96
-	{
97
-		if ($this->isSeekable()) {
98
-			$this->seek(0);
99
-		}
100
-
101
-		return $this->getContents();
102
-	}
103
-
104
-	public function close(): void
105
-	{
106
-		if (isset($this->stream) && is_resource($this->stream)) {
107
-			fclose($this->stream);
108
-			$this->detach();
109
-		}
110
-	}
111
-
112
-	public function detach()
113
-	{
114
-		if ($this->stream === null) {
115
-			return null;
116
-		}
117
-
118
-		$result = $this->stream;
119
-		$this->stream = null;
120
-
121
-		$this->size = $this->uri = null;
122
-		$this->readable = $this->writable = $this->seekable = false;
123
-
124
-		return $result;
125
-	}
126
-
127
-	public function getSize(): ?int
128
-	{
129
-		if (null !== $this->size) {
130
-			return $this->size;
131
-		}
132
-
133
-		if (!isset($this->stream)) {
134
-			return null;
135
-		}
136
-
137
-		// Clear the stat cache if the stream has a URI
138
-		if ($this->uri) {
139
-			clearstatcache(true, $this->uri);
140
-		}
141
-
142
-		$stats = fstat($this->stream);
143
-		if (isset($stats['size'])) {
144
-			$this->size = $stats['size'];
145
-			return $this->size;
146
-		}
147
-
148
-		return null;
149
-	}
150
-
151
-	public function tell(): int
152
-	{
153
-		$position = $this->stream === null ? false : ftell($this->stream);
154
-		if (false === $position) {
155
-			throw new RuntimeException('Unable to determine stream position');
156
-		}
157
-
158
-		return $position;
159
-	}
160
-
161
-	public function eof(): bool
162
-	{
163
-		return !$this->stream || feof($this->stream);
164
-	}
165
-
166
-	public function isSeekable(): bool
167
-	{
168
-		return $this->seekable;
169
-	}
170
-
171
-	public function seek($offset, $whence = SEEK_SET): void
172
-	{
173
-		if (!$this->seekable) {
174
-			throw new RuntimeException('Stream is not seekable');
175
-		}
176
-
177
-		if (-1 === fseek($this->stream, $offset, $whence)) {
178
-			throw new RuntimeException('Unable to seek to stream position ' . $offset . ' with whence ' . \var_export($whence, true));
179
-		}
180
-	}
181
-
182
-	public function rewind(): void
183
-	{
184
-		$this->seek(0);
185
-	}
186
-
187
-	public function isWritable(): bool
188
-	{
189
-		return $this->writable;
190
-	}
191
-
192
-	public function write($string): int
193
-	{
194
-		if (!$this->writable) {
195
-			throw new RuntimeException('Cannot write to a non-writable stream');
196
-		}
197
-
198
-		// We can't know the size after writing anything
199
-		$this->size = null;
200
-
201
-		if (false === $result = fwrite($this->stream, $string)) {
202
-			throw new RuntimeException('Unable to write to stream');
203
-		}
204
-
205
-		return $result;
206
-	}
207
-
208
-	public function isReadable(): bool
209
-	{
210
-		return $this->readable;
211
-	}
212
-
213
-	public function read($length): string
214
-	{
215
-		if (!$this->readable) {
216
-			throw new RuntimeException('Cannot read from non-readable stream');
217
-		}
218
-
219
-		return fread($this->stream, $length);
220
-	}
221
-
222
-	public function getContents(): string
223
-	{
224
-		if (!isset($this->stream)) {
225
-			throw new RuntimeException('Unable to read stream contents');
226
-		}
227
-
228
-		if (false === $contents = stream_get_contents($this->stream)) {
229
-			throw new RuntimeException('Unable to read stream contents');
230
-		}
231
-
232
-		return $contents;
233
-	}
234
-
235
-	public function getMetadata($key = null)
236
-	{
237
-		if (!isset($this->stream)) {
238
-			return $key ? null : [];
239
-		}
240
-
241
-		$meta = stream_get_meta_data($this->stream);
242
-
243
-		if (null === $key) {
244
-			return $meta;
245
-		}
246
-
247
-		return $meta[$key] ?? null;
248
-	}
26
+    /** @var resource|null A resource reference */
27
+    protected $stream = null;
28
+    protected bool $seekable = false;
29
+    protected bool $readable = false;
30
+    protected bool $writable = false;
31
+    /** @var array|mixed|void|null */
32
+    protected $uri;
33
+    /** @var int|null */
34
+    protected ?int $size = null;
35
+
36
+    protected const READ_WRITE_HASH = [
37
+        'read' => [
38
+            'r' => true, 'w+' => true, 'r+' => true, 'x+' => true, 'c+' => true,
39
+            'rb' => true, 'w+b' => true, 'r+b' => true, 'x+b' => true,
40
+            'c+b' => true, 'rt' => true, 'w+t' => true, 'r+t' => true,
41
+            'x+t' => true, 'c+t' => true, 'a+' => true,
42
+        ],
43
+        'write' => [
44
+            'w' => true, 'w+' => true, 'rw' => true, 'r+' => true, 'x+' => true,
45
+            'c+' => true, 'wb' => true, 'w+b' => true, 'r+b' => true,
46
+            'x+b' => true, 'c+b' => true, 'w+t' => true, 'r+t' => true,
47
+            'x+t' => true, 'c+t' => true, 'a' => true, 'a+' => true,
48
+        ],
49
+    ];
50
+
51
+    /**
52
+     * Creates a new PSR-7 stream.
53
+     *
54
+     * @param string|resource|StreamInterface $body
55
+     *
56
+     * @return StreamInterface
57
+     *
58
+     * @throws InvalidArgumentException
59
+     */
60
+    public static function create($body = ''): StreamInterface
61
+    {
62
+        if ($body instanceof StreamInterface) {
63
+            return $body;
64
+        }
65
+
66
+        if (is_string($body)) {
67
+            $resource = fopen('php://temp', 'rw+');
68
+            fwrite($resource, $body);
69
+            $body = $resource;
70
+        }
71
+
72
+        if (is_resource($body)) {
73
+            $new = new self();
74
+            $new->stream = $body;
75
+            $meta = stream_get_meta_data($new->stream);
76
+            $new->seekable = $meta['seekable'] && 0 === \fseek($new->stream, 0, \SEEK_CUR);
77
+            $new->readable = isset(self::READ_WRITE_HASH['read'][$meta['mode']]);
78
+            $new->writable = isset(self::READ_WRITE_HASH['write'][$meta['mode']]);
79
+            $new->uri = $new->getMetadata('uri');
80
+
81
+            return $new;
82
+        }
83
+
84
+        throw new InvalidArgumentException('First argument to Stream::create() must be a string, resource or StreamInterface.');
85
+    }
86
+
87
+    /**
88
+     * Closes the stream when the destructed.
89
+     */
90
+    public function __destruct()
91
+    {
92
+        $this->close();
93
+    }
94
+
95
+    public function __toString(): string
96
+    {
97
+        if ($this->isSeekable()) {
98
+            $this->seek(0);
99
+        }
100
+
101
+        return $this->getContents();
102
+    }
103
+
104
+    public function close(): void
105
+    {
106
+        if (isset($this->stream) && is_resource($this->stream)) {
107
+            fclose($this->stream);
108
+            $this->detach();
109
+        }
110
+    }
111
+
112
+    public function detach()
113
+    {
114
+        if ($this->stream === null) {
115
+            return null;
116
+        }
117
+
118
+        $result = $this->stream;
119
+        $this->stream = null;
120
+
121
+        $this->size = $this->uri = null;
122
+        $this->readable = $this->writable = $this->seekable = false;
123
+
124
+        return $result;
125
+    }
126
+
127
+    public function getSize(): ?int
128
+    {
129
+        if (null !== $this->size) {
130
+            return $this->size;
131
+        }
132
+
133
+        if (!isset($this->stream)) {
134
+            return null;
135
+        }
136
+
137
+        // Clear the stat cache if the stream has a URI
138
+        if ($this->uri) {
139
+            clearstatcache(true, $this->uri);
140
+        }
141
+
142
+        $stats = fstat($this->stream);
143
+        if (isset($stats['size'])) {
144
+            $this->size = $stats['size'];
145
+            return $this->size;
146
+        }
147
+
148
+        return null;
149
+    }
150
+
151
+    public function tell(): int
152
+    {
153
+        $position = $this->stream === null ? false : ftell($this->stream);
154
+        if (false === $position) {
155
+            throw new RuntimeException('Unable to determine stream position');
156
+        }
157
+
158
+        return $position;
159
+    }
160
+
161
+    public function eof(): bool
162
+    {
163
+        return !$this->stream || feof($this->stream);
164
+    }
165
+
166
+    public function isSeekable(): bool
167
+    {
168
+        return $this->seekable;
169
+    }
170
+
171
+    public function seek($offset, $whence = SEEK_SET): void
172
+    {
173
+        if (!$this->seekable) {
174
+            throw new RuntimeException('Stream is not seekable');
175
+        }
176
+
177
+        if (-1 === fseek($this->stream, $offset, $whence)) {
178
+            throw new RuntimeException('Unable to seek to stream position ' . $offset . ' with whence ' . \var_export($whence, true));
179
+        }
180
+    }
181
+
182
+    public function rewind(): void
183
+    {
184
+        $this->seek(0);
185
+    }
186
+
187
+    public function isWritable(): bool
188
+    {
189
+        return $this->writable;
190
+    }
191
+
192
+    public function write($string): int
193
+    {
194
+        if (!$this->writable) {
195
+            throw new RuntimeException('Cannot write to a non-writable stream');
196
+        }
197
+
198
+        // We can't know the size after writing anything
199
+        $this->size = null;
200
+
201
+        if (false === $result = fwrite($this->stream, $string)) {
202
+            throw new RuntimeException('Unable to write to stream');
203
+        }
204
+
205
+        return $result;
206
+    }
207
+
208
+    public function isReadable(): bool
209
+    {
210
+        return $this->readable;
211
+    }
212
+
213
+    public function read($length): string
214
+    {
215
+        if (!$this->readable) {
216
+            throw new RuntimeException('Cannot read from non-readable stream');
217
+        }
218
+
219
+        return fread($this->stream, $length);
220
+    }
221
+
222
+    public function getContents(): string
223
+    {
224
+        if (!isset($this->stream)) {
225
+            throw new RuntimeException('Unable to read stream contents');
226
+        }
227
+
228
+        if (false === $contents = stream_get_contents($this->stream)) {
229
+            throw new RuntimeException('Unable to read stream contents');
230
+        }
231
+
232
+        return $contents;
233
+    }
234
+
235
+    public function getMetadata($key = null)
236
+    {
237
+        if (!isset($this->stream)) {
238
+            return $key ? null : [];
239
+        }
240
+
241
+        $meta = stream_get_meta_data($this->stream);
242
+
243
+        if (null === $key) {
244
+            return $meta;
245
+        }
246
+
247
+        return $meta[$key] ?? null;
248
+    }
249 249
 }
250 250
\ No newline at end of file
Please login to merge, or discard this patch.