Menu
Reference
ByteBuffer
final class ByteBuffer
A growable byte string with a read cursor.
Append bytes at the end with append(); consume them from the front with read(), skip() and friends. Offsets and lengths are in bytes and always relative to the cursor (the first unconsumed byte). The buffer never throws: a read past the end is short, and a lookup that finds nothing answers -1. It is built for incremental parsers, where a partial message is left in place and finished when more bytes arrive.
$b = new Buffer\ByteBuffer();
$b->append("line one\r\nline two");
$end = $b->indexOf("\r\n");
$line = $b->read($end);
$b->skip(2);This is not Manticore\Ds\ByteBuffer, which is a fixed-size native buffer.
Example
// Buffer\ByteBuffer: append bytes, consume them through a cursor.
use Buffer\ByteBuffer;
$b = new ByteBuffer();
$b->append("GET / HTTP/1.1\r\nHost: x\r\n\r\nBODY");
// indexOf() is relative to the cursor; -1 means "not there (yet)".
$end = $b->indexOf("\r\n\r\n");
echo "head ends at ", $end, "\n";
$head = $b->read($end); // consume the head
$b->skip(4); // and the blank line, without copying it out
echo "head: ", json_encode($head), "\n";
echo "left: ", $b->length(), " bytes, next byte ", $b->byteAt(0), " (", chr($b->byteAt(0)), ")\n";
echo "byteAt past the end: ", $b->byteAt(100), "\n";
// peek() looks, read() consumes; both are short at the end of the buffer.
echo "peek: ", $b->peek(2), "\n";
echo "read: ", $b->read(100), "\n";
echo "empty: ", var_export($b->isEmpty(), true), "\n";
// A capped buffer refuses a write that would cross the cap, and appends nothing.
$c = new ByteBuffer(8);
var_dump($c->append("12345"));
var_dump($c->append("6789"));
echo "view: ", $c->view(), "\n";
echo "readAll: ", $c->readAll(), " then empty=", var_export($c->isEmpty(), true), "\n";Output
head ends at 23
head: "GET \/ HTTP\/1.1\r\nHost: x"
left: 4 bytes, next byte 66 (B)
byteAt past the end: -1
peek: BO
read: BODY
empty: true
bool(true)
bool(false)
view: 12345
readAll: 12345 then empty=trueProperties
buf | string | The raw bytes, including the part already consumed. |
pos | int | Offset into {@see $buf} of the first unconsumed byte. |
cap | int | Ceiling on the number of unconsumed bytes; 0 (the default) means no limit. |
buf#source
string $buf = ''
The raw bytes, including the part already consumed. Normally read it through view() or peek() instead; this is the storage the cursor {@see $pos} indexes into.
pos#source
int $pos = 0
Offset into {@see $buf} of the first unconsumed byte. Everything before it has been consumed and is dropped lazily by compact().
cap#source
int $cap = 0
Ceiling on the number of unconsumed bytes; 0 (the default) means no limit. append() refuses a write that would cross it.
Methods
__construct() | Create an empty buffer. |
length() | The number of unconsumed bytes. |
isEmpty() | Whether there are no unconsumed bytes. |
append() | Append bytes at the end. |
peek() | Look at the next bytes without consuming them. |
read() | Consume and return the next bytes. |
readAll() | Consume and return everything unconsumed, leaving the buffer empty. |
skip() | Consume bytes without returning them. |
indexOf() | Find a byte string in the unconsumed bytes. |
byteAt() | The value of one unconsumed byte. |
view() | All unconsumed bytes as a string, without consuming them. |
compact() | Release memory held by already-consumed bytes. |
clear() | Discard all bytes, consumed or not, and reset the cursor. |
__construct()#source
function __construct(int $cap = 0)
Create an empty buffer.
Parameters
$capint = 0- limit on unconsumed bytes, or 0 for no limit
length()#source
function length(): int
The number of unconsumed bytes.
Returns
int — the byte count
isEmpty()#source
function isEmpty(): bool
Whether there are no unconsumed bytes.
Returns
bool — true when length() is 0
append()#source
function append(string $s): bool
Append bytes at the end.
When the write would push the number of unconsumed bytes past {@see $cap}, nothing is appended and the answer is false; the caller decides what a full buffer means (a server answers 431 or 413, for instance).
Parameters
$sstring- the bytes to add
Returns
bool — true when appended, false when refused for exceeding the cap
peek()#source
function peek(int $n): string
Look at the next bytes without consuming them.
Parameters
$nint- how many bytes; zero or negative gives ''
Returns
string — up to $n bytes, fewer when the buffer holds fewer
read()#source
function read(int $n): string
Consume and return the next bytes.
Parameters
$nint- how many bytes; zero or negative gives '' and consumes nothing
Returns
string — up to $n bytes, fewer when the buffer holds fewer
readAll()#source
function readAll(): string
Consume and return everything unconsumed, leaving the buffer empty.
Returns
string — all unconsumed bytes, possibly ''
skip()#source
function skip(int $n): void
Consume bytes without returning them. Skipping more than the buffer holds stops at the end; zero or negative does nothing.
Parameters
$nint- how many bytes to drop
indexOf()#source
function indexOf(string $needle, int $from = 0): int
Find a byte string in the unconsumed bytes.
Both the answer and $from are relative to the cursor, so a parser that
has already scanned a prefix can resume after it instead of rescanning.
Parameters
$needlestring- the bytes to look for
$fromint = 0- where to start, relative to the cursor; negative counts as 0
Returns
int — offset of the first match relative to the cursor, or -1 when there is none
byteAt()#source
function byteAt(int $i): int
The value of one unconsumed byte.
Parameters
$iint- offset relative to the cursor
Returns
int — the byte, 0 to 255, or -1 when $i is negative or past the end
view()#source
function view(): string
All unconsumed bytes as a string, without consuming them.
Scan it, then tell the buffer how much to consume with skip() or read(); a partial message costs no copy that way.
Returns
string — the unconsumed bytes
compact()#source
function compact(): void
Release memory held by already-consumed bytes.
read() and skip() call this for you. A fully consumed buffer is reset to empty; otherwise the consumed prefix is dropped once it reaches 8192 bytes. Calling it by hand is never required.
clear()#source
function clear(): void
Discard all bytes, consumed or not, and reset the cursor.