Passed
Push — master ( c3277e...6db6a3 )
by Anatoly
04:11 queued 16s
created
src/Stream.php 1 patch
Indentation   +303 added lines, -303 removed lines patch added patch discarded remove patch
@@ -34,307 +34,307 @@
 block discarded – undo
34 34
 
35 35
 class Stream implements StreamInterface
36 36
 {
37
-    /**
38
-     * @var resource|null
39
-     */
40
-    private $resource;
41
-
42
-    private bool $autoClose;
43
-
44
-    /**
45
-     * @param mixed $resource
46
-     *
47
-     * @throws InvalidArgumentException
48
-     */
49
-    public function __construct($resource, bool $autoClose = true)
50
-    {
51
-        if (!is_resource($resource)) {
52
-            throw new InvalidArgumentException('Unexpected stream resource');
53
-        }
54
-
55
-        $this->resource = $resource;
56
-        $this->autoClose = $autoClose;
57
-    }
58
-
59
-    /**
60
-     * @param mixed $resource
61
-     *
62
-     * @throws InvalidArgumentException
63
-     */
64
-    public static function create($resource): StreamInterface
65
-    {
66
-        if ($resource instanceof StreamInterface) {
67
-            return $resource;
68
-        }
69
-
70
-        return new self($resource);
71
-    }
72
-
73
-    public function __destruct()
74
-    {
75
-        if ($this->autoClose) {
76
-            $this->close();
77
-        }
78
-    }
79
-
80
-    /**
81
-     * @inheritDoc
82
-     */
83
-    public function detach()
84
-    {
85
-        $resource = $this->resource;
86
-        $this->resource = null;
87
-
88
-        return $resource;
89
-    }
90
-
91
-    /**
92
-     * @inheritDoc
93
-     */
94
-    public function close(): void
95
-    {
96
-        $resource = $this->detach();
97
-        if (!is_resource($resource)) {
98
-            return;
99
-        }
100
-
101
-        fclose($resource);
102
-    }
103
-
104
-    /**
105
-     * @inheritDoc
106
-     */
107
-    public function eof(): bool
108
-    {
109
-        if (!is_resource($this->resource)) {
110
-            return true;
111
-        }
112
-
113
-        return feof($this->resource);
114
-    }
115
-
116
-    /**
117
-     * @inheritDoc
118
-     */
119
-    public function tell(): int
120
-    {
121
-        if (!is_resource($this->resource)) {
122
-            throw new RuntimeException('Stream has no resource');
123
-        }
124
-
125
-        $result = ftell($this->resource);
126
-        if ($result === false) {
127
-            throw new RuntimeException('Unable to get the stream pointer position');
128
-        }
129
-
130
-        return $result;
131
-    }
132
-
133
-    /**
134
-     * @inheritDoc
135
-     */
136
-    public function isSeekable(): bool
137
-    {
138
-        if (!is_resource($this->resource)) {
139
-            return false;
140
-        }
141
-
142
-        $metadata = stream_get_meta_data($this->resource);
143
-
144
-        return $metadata['seekable'];
145
-    }
146
-
147
-    /**
148
-     * @inheritDoc
149
-     */
150
-    public function rewind(): void
151
-    {
152
-        $this->seek(0);
153
-    }
154
-
155
-    /**
156
-     * @inheritDoc
157
-     */
158
-    public function seek($offset, $whence = SEEK_SET): void
159
-    {
160
-        if (!is_resource($this->resource)) {
161
-            throw new RuntimeException('Stream has no resource');
162
-        }
163
-
164
-        if (!$this->isSeekable()) {
165
-            throw new RuntimeException('Stream is not seekable');
166
-        }
167
-
168
-        $result = fseek($this->resource, $offset, $whence);
169
-        if ($result !== 0) {
170
-            throw new RuntimeException('Unable to move the stream pointer position');
171
-        }
172
-    }
173
-
174
-    /**
175
-     * @inheritDoc
176
-     */
177
-    public function isWritable(): bool
178
-    {
179
-        if (!is_resource($this->resource)) {
180
-            return false;
181
-        }
182
-
183
-        $metadata = stream_get_meta_data($this->resource);
184
-
185
-        return strpbrk($metadata['mode'], '+acwx') !== false;
186
-    }
187
-
188
-    /**
189
-     * @inheritDoc
190
-     */
191
-    public function write($string): int
192
-    {
193
-        if (!is_resource($this->resource)) {
194
-            throw new RuntimeException('Stream has no resource');
195
-        }
196
-
197
-        if (!$this->isWritable()) {
198
-            throw new RuntimeException('Stream is not writable');
199
-        }
200
-
201
-        $result = fwrite($this->resource, $string);
202
-        if ($result === false) {
203
-            throw new RuntimeException('Unable to write to the stream');
204
-        }
205
-
206
-        return $result;
207
-    }
208
-
209
-    /**
210
-     * @since 3.7.0
211
-     *
212
-     * @throws OverflowException
213
-     */
214
-    public function writeStream(StreamInterface $stream, int $limit = -1): int
215
-    {
216
-        $written = 0;
217
-        while (!$stream->eof()) {
218
-            $written += $this->write($stream->read(4096));
219
-            if ($limit > 0 && $written > $limit) {
220
-                throw new OverflowException('Maximum stream size exceeded.');
221
-            }
222
-        }
223
-
224
-        return $written;
225
-    }
226
-
227
-    /**
228
-     * @inheritDoc
229
-     */
230
-    public function isReadable(): bool
231
-    {
232
-        if (!is_resource($this->resource)) {
233
-            return false;
234
-        }
235
-
236
-        $metadata = stream_get_meta_data($this->resource);
237
-
238
-        return strpbrk($metadata['mode'], '+r') !== false;
239
-    }
240
-
241
-    /**
242
-     * @inheritDoc
243
-     *
244
-     * @psalm-param int $length
245
-     * @phpstan-param int<1, max> $length
246
-     */
247
-    public function read($length): string
248
-    {
249
-        if (!is_resource($this->resource)) {
250
-            throw new RuntimeException('Stream has no resource');
251
-        }
252
-
253
-        if (!$this->isReadable()) {
254
-            throw new RuntimeException('Stream is not readable');
255
-        }
256
-
257
-        $result = fread($this->resource, $length);
258
-        if ($result === false) {
259
-            throw new RuntimeException('Unable to read from the stream');
260
-        }
261
-
262
-        return $result;
263
-    }
264
-
265
-    /**
266
-     * @inheritDoc
267
-     */
268
-    public function getContents(): string
269
-    {
270
-        if (!is_resource($this->resource)) {
271
-            throw new RuntimeException('Stream has no resource');
272
-        }
273
-
274
-        if (!$this->isReadable()) {
275
-            throw new RuntimeException('Stream is not readable');
276
-        }
277
-
278
-        $result = stream_get_contents($this->resource);
279
-        if ($result === false) {
280
-            throw new RuntimeException('Unable to read the remainder of the stream');
281
-        }
282
-
283
-        return $result;
284
-    }
285
-
286
-    /**
287
-     * @inheritDoc
288
-     */
289
-    public function getMetadata($key = null)
290
-    {
291
-        if (!is_resource($this->resource)) {
292
-            return null;
293
-        }
294
-
295
-        $metadata = stream_get_meta_data($this->resource);
296
-        if ($key === null) {
297
-            return $metadata;
298
-        }
299
-
300
-        return $metadata[$key] ?? null;
301
-    }
302
-
303
-    /**
304
-     * @inheritDoc
305
-     */
306
-    public function getSize(): ?int
307
-    {
308
-        if (!is_resource($this->resource)) {
309
-            return null;
310
-        }
311
-
312
-        /** @var array{size: int}|false */
313
-        $stats = fstat($this->resource);
314
-        if ($stats === false) {
315
-            return null;
316
-        }
317
-
318
-        return $stats['size'];
319
-    }
320
-
321
-    /**
322
-     * @inheritDoc
323
-     */
324
-    public function __toString(): string
325
-    {
326
-        if (!$this->isReadable()) {
327
-            return '';
328
-        }
329
-
330
-        try {
331
-            if ($this->isSeekable()) {
332
-                $this->rewind();
333
-            }
334
-
335
-            return $this->getContents();
336
-        } catch (Throwable $e) {
337
-            return '';
338
-        }
339
-    }
37
+	/**
38
+	 * @var resource|null
39
+	 */
40
+	private $resource;
41
+
42
+	private bool $autoClose;
43
+
44
+	/**
45
+	 * @param mixed $resource
46
+	 *
47
+	 * @throws InvalidArgumentException
48
+	 */
49
+	public function __construct($resource, bool $autoClose = true)
50
+	{
51
+		if (!is_resource($resource)) {
52
+			throw new InvalidArgumentException('Unexpected stream resource');
53
+		}
54
+
55
+		$this->resource = $resource;
56
+		$this->autoClose = $autoClose;
57
+	}
58
+
59
+	/**
60
+	 * @param mixed $resource
61
+	 *
62
+	 * @throws InvalidArgumentException
63
+	 */
64
+	public static function create($resource): StreamInterface
65
+	{
66
+		if ($resource instanceof StreamInterface) {
67
+			return $resource;
68
+		}
69
+
70
+		return new self($resource);
71
+	}
72
+
73
+	public function __destruct()
74
+	{
75
+		if ($this->autoClose) {
76
+			$this->close();
77
+		}
78
+	}
79
+
80
+	/**
81
+	 * @inheritDoc
82
+	 */
83
+	public function detach()
84
+	{
85
+		$resource = $this->resource;
86
+		$this->resource = null;
87
+
88
+		return $resource;
89
+	}
90
+
91
+	/**
92
+	 * @inheritDoc
93
+	 */
94
+	public function close(): void
95
+	{
96
+		$resource = $this->detach();
97
+		if (!is_resource($resource)) {
98
+			return;
99
+		}
100
+
101
+		fclose($resource);
102
+	}
103
+
104
+	/**
105
+	 * @inheritDoc
106
+	 */
107
+	public function eof(): bool
108
+	{
109
+		if (!is_resource($this->resource)) {
110
+			return true;
111
+		}
112
+
113
+		return feof($this->resource);
114
+	}
115
+
116
+	/**
117
+	 * @inheritDoc
118
+	 */
119
+	public function tell(): int
120
+	{
121
+		if (!is_resource($this->resource)) {
122
+			throw new RuntimeException('Stream has no resource');
123
+		}
124
+
125
+		$result = ftell($this->resource);
126
+		if ($result === false) {
127
+			throw new RuntimeException('Unable to get the stream pointer position');
128
+		}
129
+
130
+		return $result;
131
+	}
132
+
133
+	/**
134
+	 * @inheritDoc
135
+	 */
136
+	public function isSeekable(): bool
137
+	{
138
+		if (!is_resource($this->resource)) {
139
+			return false;
140
+		}
141
+
142
+		$metadata = stream_get_meta_data($this->resource);
143
+
144
+		return $metadata['seekable'];
145
+	}
146
+
147
+	/**
148
+	 * @inheritDoc
149
+	 */
150
+	public function rewind(): void
151
+	{
152
+		$this->seek(0);
153
+	}
154
+
155
+	/**
156
+	 * @inheritDoc
157
+	 */
158
+	public function seek($offset, $whence = SEEK_SET): void
159
+	{
160
+		if (!is_resource($this->resource)) {
161
+			throw new RuntimeException('Stream has no resource');
162
+		}
163
+
164
+		if (!$this->isSeekable()) {
165
+			throw new RuntimeException('Stream is not seekable');
166
+		}
167
+
168
+		$result = fseek($this->resource, $offset, $whence);
169
+		if ($result !== 0) {
170
+			throw new RuntimeException('Unable to move the stream pointer position');
171
+		}
172
+	}
173
+
174
+	/**
175
+	 * @inheritDoc
176
+	 */
177
+	public function isWritable(): bool
178
+	{
179
+		if (!is_resource($this->resource)) {
180
+			return false;
181
+		}
182
+
183
+		$metadata = stream_get_meta_data($this->resource);
184
+
185
+		return strpbrk($metadata['mode'], '+acwx') !== false;
186
+	}
187
+
188
+	/**
189
+	 * @inheritDoc
190
+	 */
191
+	public function write($string): int
192
+	{
193
+		if (!is_resource($this->resource)) {
194
+			throw new RuntimeException('Stream has no resource');
195
+		}
196
+
197
+		if (!$this->isWritable()) {
198
+			throw new RuntimeException('Stream is not writable');
199
+		}
200
+
201
+		$result = fwrite($this->resource, $string);
202
+		if ($result === false) {
203
+			throw new RuntimeException('Unable to write to the stream');
204
+		}
205
+
206
+		return $result;
207
+	}
208
+
209
+	/**
210
+	 * @since 3.7.0
211
+	 *
212
+	 * @throws OverflowException
213
+	 */
214
+	public function writeStream(StreamInterface $stream, int $limit = -1): int
215
+	{
216
+		$written = 0;
217
+		while (!$stream->eof()) {
218
+			$written += $this->write($stream->read(4096));
219
+			if ($limit > 0 && $written > $limit) {
220
+				throw new OverflowException('Maximum stream size exceeded.');
221
+			}
222
+		}
223
+
224
+		return $written;
225
+	}
226
+
227
+	/**
228
+	 * @inheritDoc
229
+	 */
230
+	public function isReadable(): bool
231
+	{
232
+		if (!is_resource($this->resource)) {
233
+			return false;
234
+		}
235
+
236
+		$metadata = stream_get_meta_data($this->resource);
237
+
238
+		return strpbrk($metadata['mode'], '+r') !== false;
239
+	}
240
+
241
+	/**
242
+	 * @inheritDoc
243
+	 *
244
+	 * @psalm-param int $length
245
+	 * @phpstan-param int<1, max> $length
246
+	 */
247
+	public function read($length): string
248
+	{
249
+		if (!is_resource($this->resource)) {
250
+			throw new RuntimeException('Stream has no resource');
251
+		}
252
+
253
+		if (!$this->isReadable()) {
254
+			throw new RuntimeException('Stream is not readable');
255
+		}
256
+
257
+		$result = fread($this->resource, $length);
258
+		if ($result === false) {
259
+			throw new RuntimeException('Unable to read from the stream');
260
+		}
261
+
262
+		return $result;
263
+	}
264
+
265
+	/**
266
+	 * @inheritDoc
267
+	 */
268
+	public function getContents(): string
269
+	{
270
+		if (!is_resource($this->resource)) {
271
+			throw new RuntimeException('Stream has no resource');
272
+		}
273
+
274
+		if (!$this->isReadable()) {
275
+			throw new RuntimeException('Stream is not readable');
276
+		}
277
+
278
+		$result = stream_get_contents($this->resource);
279
+		if ($result === false) {
280
+			throw new RuntimeException('Unable to read the remainder of the stream');
281
+		}
282
+
283
+		return $result;
284
+	}
285
+
286
+	/**
287
+	 * @inheritDoc
288
+	 */
289
+	public function getMetadata($key = null)
290
+	{
291
+		if (!is_resource($this->resource)) {
292
+			return null;
293
+		}
294
+
295
+		$metadata = stream_get_meta_data($this->resource);
296
+		if ($key === null) {
297
+			return $metadata;
298
+		}
299
+
300
+		return $metadata[$key] ?? null;
301
+	}
302
+
303
+	/**
304
+	 * @inheritDoc
305
+	 */
306
+	public function getSize(): ?int
307
+	{
308
+		if (!is_resource($this->resource)) {
309
+			return null;
310
+		}
311
+
312
+		/** @var array{size: int}|false */
313
+		$stats = fstat($this->resource);
314
+		if ($stats === false) {
315
+			return null;
316
+		}
317
+
318
+		return $stats['size'];
319
+	}
320
+
321
+	/**
322
+	 * @inheritDoc
323
+	 */
324
+	public function __toString(): string
325
+	{
326
+		if (!$this->isReadable()) {
327
+			return '';
328
+		}
329
+
330
+		try {
331
+			if ($this->isSeekable()) {
332
+				$this->rewind();
333
+			}
334
+
335
+			return $this->getContents();
336
+		} catch (Throwable $e) {
337
+			return '';
338
+		}
339
+	}
340 340
 }
Please login to merge, or discard this patch.