forked from EvilFreelancer/routeros-api-php
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathResourceStream.php
More file actions
130 lines (109 loc) · 3.3 KB
/
Copy pathResourceStream.php
File metadata and controls
130 lines (109 loc) · 3.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
<?php
namespace RouterOS\Streams;
use RouterOS\Interfaces\StreamInterface;
use RouterOS\Exceptions\StreamException;
/**
* class ResourceStream
*
* Stream using a resource (socket, file, pipe etc.)
*
* @package RouterOS
* @since 0.9
*/
class ResourceStream implements StreamInterface
{
protected $stream;
/**
* Whether to throw exception on stream timeout
*
* @var bool
*/
protected $throwTimeoutException = true;
/**
* ResourceStream constructor.
*
* @param $stream
*/
public function __construct($stream)
{
if (!is_resource($stream)) {
throw new \InvalidArgumentException(sprintf('Argument must be a valid resource type. %s given.', gettype($stream)));
}
// TODO: Should we verify the resource type?
$this->stream = $stream;
}
/**
* Set whether to throw exception on stream timeout
*
* @param bool $throw
* @return self
*/
public function setThrowTimeoutException(bool $throw): self
{
$this->throwTimeoutException = $throw;
return $this;
}
/**
* {@inheritDoc}
*
* @throws \RouterOS\Exceptions\StreamException when length parameter is invalid
* @throws \InvalidArgumentException when the stream have been totally read and read method is called again
*/
public function read(int $length): string
{
if ($length <= 0) {
throw new \InvalidArgumentException('Cannot read zero ot negative count of bytes from a stream');
}
if (!is_resource($this->stream)) {
throw new StreamException('Stream is not writable');
}
$result = fread($this->stream, $length);
// PHP 8.4 may report timed_out=true even on successful partial reads
// Only throw timeout if we got no data AND stream actually timed out
if ($this->throwTimeoutException) {
$info = stream_get_meta_data($this->stream);
if ($info['timed_out'] && ($result === '' || $result === false)) {
throw new StreamException('Stream timed out');
}
}
if (false === $result) {
throw new StreamException("Error reading $length bytes");
}
return $result;
}
/**
* {@inheritDoc}
*
* @throws \RouterOS\Exceptions\StreamException when not possible to write bytes
*/
public function write(string $string, ?int $length = null): int
{
if (null === $length) {
$length = strlen($string);
}
if (!is_resource($this->stream)) {
throw new StreamException('Stream is not writable');
}
$result = fwrite($this->stream, $string, $length);
if (false === $result) {
throw new StreamException("Error writing $length bytes");
}
return $result;
}
/**
* {@inheritDoc}
*
* @throws \RouterOS\Exceptions\StreamException when not possible to close the stream
*/
public function close(): void
{
$hasBeenClosed = false;
if (null !== $this->stream) {
$hasBeenClosed = @fclose($this->stream);
$this->stream = null;
}
if (false === $hasBeenClosed) {
throw new StreamException('Error closing stream');
}
}
}