-
Notifications
You must be signed in to change notification settings - Fork 0
/
functions.php
289 lines (266 loc) · 8.5 KB
/
functions.php
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
<?php declare(strict_types=1);
namespace Tale;
use Generator;
use Psr\Http\Message\StreamFactoryInterface;
use Psr\Http\Message\StreamInterface;
use Tale\Stream\Iterator\LineIterator;
use Tale\Stream\Iterator\ReadIterator;
use Tale\Stream\Iterator\SplitIterator;
use Tale\Stream\Iterator\WriteIterator;
use Tale\Stream\NullStream;
/**
* Creates a new Stream instance from a PHP stream resource.
*
* @param $resource
* @return StreamInterface
*/
function stream($resource): StreamInterface
{
return new Stream($resource);
}
/**
* Creates a new stream factory to easily create streams in a centralized manner.
*
* @return StreamFactoryInterface
*/
function stream_factory(): StreamFactoryInterface
{
return new StreamFactory();
}
/**
* Creates a new File Stream given a file path.
*
* This function works very similar to fopen(), but it will simply return a valid Stream instance.
*
* @param string $filename The path to a file or stream wrapper resource.
* @param string $mode The mode to open the file with (Same as fopen() mode).
* @param bool|null $useIncludePath Should we use the include_path or not?
* @param null $context A stream context (Same as fopen() stream context)
* @return StreamInterface
*/
function stream_file(
string $filename,
string $mode = 'rb',
?bool $useIncludePath = false,
$context = null
): StreamInterface {
return Stream::createFileStream($filename, $mode, $useIncludePath, $context);
}
/**
* Creates a new Input Stream.
*
* This uses the php://input stream wrapper.
* Use this to read the HTTP POST/PUT body from requests.
*
* @return StreamInterface
*/
function stream_input(): StreamInterface
{
return Stream::createInputStream();
}
/**
* Creates a new Output Stream.
*
* This uses the php://output stream wrapper.
* Use this to write to HTTP responses.
*
* @return StreamInterface
*/
function stream_output(): StreamInterface
{
return Stream::createOutputStream();
}
/**
* Creates a new memory stream you can read from and write to freely.
*
* This uses the php://memory stream wrapper.
* You can pass it initial content and it will always start at position 0.
*
* @param string $content Initial content to fill the stream with.
* @return StreamInterface
*/
function stream_memory(string $content = ''): StreamInterface
{
return Stream::createMemoryStream($content);
}
/**
* Creates a new temporary stream you can read from and write to freely.
*
* The stream will use your memory unless you pass the second parameter, then it
* will swap to a file after the maximum memory is reached.
*
* This uses the php://temp stream wrapper.
* You can pass it initial content and it will always start at position 0.
*
* @param string $content Initial content to fill the stream with.
* @param int|null $maxMemory Amount of bytes when the stream will start swapping to a file.
* @return StreamInterface
*/
function stream_temp(string $content = '', ?int $maxMemory = null): StreamInterface
{
return Stream::createTempStream($content, $maxMemory);
}
/**
* @return StreamInterface
*/
function stream_stdin(): StreamInterface
{
return Stream::createStdinStream();
}
/**
* @return StreamInterface
*/
function stream_stderr(): StreamInterface
{
return Stream::createStderrStream();
}
/**
* @return StreamInterface
*/
function stream_stdout(): StreamInterface
{
return Stream::createStderrStream();
}
/**
* @return StreamInterface
*/
function stream_null(): StreamInterface
{
return new NullStream();
}
/**
* Creates a read iterator for a stream that will read a stream chunk by chunk.
*
* You can iterate it and every item will be a string exactly as long as the passed chunk size.
* Useful to read streams with regards to memory and/or with iterators.
*
* @param StreamInterface $stream The stream to read chunks from.
* @param int $chunkSize The chunk size (Default: 1024)
* @return ReadIterator
*/
function stream_read(StreamInterface $stream, int $chunkSize = 1024): ReadIterator
{
return new ReadIterator($stream, $chunkSize);
}
/**
* Creates a new line iterator for streams.
*
* You can iterate it and it will read the stream line by line.
* It has no soft limit on line length.
*
* @param ReadIterator $readIterator A read iterator to read from.
* @param string $delimiter A delimiter to split lines by (Default: "\n")
* @return LineIterator
*/
function stream_read_lines(ReadIterator $readIterator, string $delimiter = LineIterator::DELIMITER_LF): LineIterator
{
return new LineIterator($readIterator, $delimiter);
}
/**
* Returns an iterator that contains all lines in your stream.
*
* You can iterate it and it will read the stream line by line lazily.
* It has no soft limit on line length.
*
* @param StreamInterface $stream The stream to read lines of.
* @param string $delimiter A delimiter to split lines by (Default: "\n")
* @param int $chunkSize The chunk size to use (more = faster, but more memory usage) (Default: 1024)
* @return Generator<string>
*/
function stream_get_lines(
StreamInterface $stream,
string $delimiter = LineIterator::DELIMITER_LF,
int $chunkSize = 1024
): Generator {
yield from stream_read_lines(stream_read($stream, $chunkSize), $delimiter);
}
/**
* Creates a split iterator that will read a stream part by part.
*
* You can pass it a delimiter to split lines with.
* It has no soft limit on length of the part.
*
* @param ReadIterator $readIterator A read iterator to read from.
* @param string $delimiter A delimiter to split parts by
* @return SplitIterator
*/
function stream_read_split(ReadIterator $readIterator, string $delimiter): SplitIterator
{
return new SplitIterator($readIterator, $delimiter);
}
/**
* Splits a stream by a delimiter and returns an iterator containing the parts.
*
* Basically explode() for PSR streams.
* You can iterate it and it will read the stream part by part lazily.
* It has no hard limit on part length.
*
* @param StreamInterface $stream The stream to read chunks from.
* @param string $delimiter A delimiter to split parts by
* @param int $chunkSize The chunk size (Default: 1024)
* @return Generator<string>
*/
function stream_split(
StreamInterface $stream,
string $delimiter,
int $chunkSize = 1024
): Generator {
yield from stream_read_split(stream_read($stream, $chunkSize), $delimiter);
}
/**
* Creates a write iterator that will write an iterable to a stream when it is iterated itself.
*
* This is useful for piping streams in a memory efficient manner.
* You can pipe streams by passing a ReadIterator of a stream as the second parameter.
*
* Don't forget to iterate the iterator or nothing gets written (You can also use ->writeAll() on it).
*
* @param StreamInterface $stream The stream to write to.
* @param iterable $sourceIterable The iterable to read from.
* @return WriteIterator
*/
function stream_write(StreamInterface $stream, iterable $sourceIterable): WriteIterator
{
return new WriteIterator($stream, $sourceIterable);
}
/**
* Writes an iterable to a stream.
*
* It will iterate the passed iterable and write it to the stream item by item.
*
* It will return the total amount of written bytes.
*
* @param StreamInterface $stream The stream to write to.
* @param iterable $sourceIterable The iterable to read from.
* @return int
*/
function stream_write_all(StreamInterface $stream, iterable $sourceIterable): int
{
return stream_write($stream, $sourceIterable)->writeAll();
}
/**
* Creates a write iterator that will write one stream to another (piping) once iterated.
*
* Don't forget to iterate the iterator or nothing gets written (You can also use ->writeAll() on it).
*
* @param StreamInterface $inputStream The stream to write to.
* @param StreamInterface $outputStream The stream to read from.
* @param int $chunkSize The chunk size to use (higher = faster but more memory) (Default: 1024)
* @return WriteIterator
*/
function stream_pipe(StreamInterface $inputStream, StreamInterface $outputStream, int $chunkSize = 1024): WriteIterator
{
return stream_write($outputStream, stream_read($inputStream, $chunkSize));
}
/**
* Writes one stream to another (piping).
*
* @param StreamInterface $inputStream The stream to write to.
* @param StreamInterface $outputStream The stream to read from.
* @param int $chunkSize The chunk size to use (higher = faster but more memory) (Default: 1024)
* @return int
*/
function stream_pipe_all(StreamInterface $inputStream, StreamInterface $outputStream, int $chunkSize = 1024): int
{
return stream_pipe($inputStream, $outputStream, $chunkSize)->writeAll();
}