Class
StringBuffer
A buffer of streamed bytes that one coroutine fills and another reads, for parsing protocols that arrive in frames.
Introduction#
Designed for servers (HTTP, FastCGI, WebSocket) that read fixed-size frames from a byte stream. A reader waits for data, readFixed() waits for a whole frame, and end() marks the end of the stream. Unbounded by default: a writer that outpaces its reader grows the buffer without limit. With $maxSize, write() waits until the reader has made room. For passing values between coroutines, use a channel.
If the writing coroutine exits without calling end(), readers must not wait forever. Ask for getDeadmanSwitch() in the writer and keep the object until it ends: when it is destroyed without end() having been called, a reader that has read the buffered data gets an exception instead of waiting.
Class synopsis#
class StringBuffer implements SelectableInterface {
/* Methods */
public StringBuffer::__construct(?int $maxSize = null)
public StringBuffer::await(float $timeout = PHP_FLOAT_MAX): void
public StringBuffer::isReady(): bool
public StringBuffer::isEmpty(): bool
public StringBuffer::write(string $chunk, float $timeout = PHP_FLOAT_MAX): void
public StringBuffer::read(int $maxLength, float $timeout = PHP_FLOAT_MAX): string
public StringBuffer::readFromResource($resource): Fiber
public StringBuffer::end(): void
public StringBuffer::eof(): bool
public StringBuffer::readFixed(int $length, float $timeout = PHP_FLOAT_MAX): ?string
public StringBuffer::writeToResource($resource): Fiber
public StringBuffer::unread(string $chunk): void
public StringBuffer::getDeadmanSwitch(): DeadmanSwitch
}Constants#
| Name | Value | Description |
|---|---|---|
BUFFER_WASTE_LIMIT | 4096 | How much unusable string data can the string buffer hold before we must perform substr to remove data already returned. |
Methods#
| Method | Description |
|---|---|
__construct | Creates an empty buffer. |
await | Waits until the buffer has data to read or has ended. |
isReady | Returns true if a read would not wait: data is buffered, or the buffer has ended or failed. |
isEmpty | Returns true if no data is buffered for reading. |
write | Appends $chunk to the buffer, and wakes the reader. |
read | Returns up to $maxLength bytes, and waits while the buffer is empty and not ended. |
readFromResource | Starts a coroutine that reads the stream into the buffer, and ends the buffer when the stream ends. |
end | Marks the end of the stream: no more writes are accepted, and readers get the data left and then the end. |
eof | Returns true if the buffer has ended and all its data has been read. |
readFixed | Returns exactly $length bytes, and waits until that many are buffered. |
writeToResource | Starts a coroutine that writes the buffer to the stream until the buffer has ended and been read. |
unread | Puts $chunk back at the front of the buffer, to be read first. |
getDeadmanSwitch | Get a deadman switch for this object. |
Examples#
phasync::run(function () {
$buffer = new phasync\Util\StringBuffer();
phasync::go(function () use ($buffer) {
$buffer->write("he");
phasync::sleep(0.01);
$buffer->write("llo\n");
$buffer->end();
});
var_dump($buffer->readFixed(5)); // string(5) "hello", after both writes
var_dump($buffer->read(10)); // string(1) "\n"
var_dump($buffer->read(10)); // string(0) "": the buffer has ended
});See also#
phasync::channelCreates a channel and returns its two ends in$readand$write.SelectableInterfaceAn object that can be asked whether using it would block, and waited for until it would not.