swoole_buffer提供的substr操作用于从缓冲区中取出内容。
string swoole_buffer->substr(int $offset, int $length = -1, bool $remove = false);
$offset
表示偏移量,如果为负数,表示倒数计算偏移量$length
表示读取数据的长度,默认为从 $offset 到整个缓存区末尾$remove
表示从缓冲区的头部将此数据移除。只有 $offset = 0 时此参数才有效
下面我们分析下其流程。
static PHP_METHOD(swoole_buffer, substr)
{
long offset;
long length = -1;
zend_bool remove = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|lb", &offset, &length, &remove) == FAILURE)
{
RETURN_FALSE;
}
swString *buffer = swoole_get_object(getThis());
if (remove && !(offset == 0 && length <= buffer->length))
{
remove = 0;
}
if (offset < 0)
{
offset = buffer->length + offset;
}
offset += buffer->offset;
if (length < 0)
{
length = buffer->length - offset;
}
if (offset + length > buffer->length)
{
swoole_php_error(E_WARNING, "offset(%ld, %ld) is out of bounds.", offset, length);
RETURN_FALSE;
}
if (remove)
{
buffer->offset += length;
zend_update_property_long(swoole_buffer_class_entry_ptr, getThis(), ZEND_STRL("length"), buffer->length - buffer->offset TSRMLS_CC);
if (buffer->offset > SW_STRING_BUFFER_GARBAGE_MIN && buffer->offset * SW_STRING_BUFFER_GARBAGE_RATIO > buffer->size)
{
swoole_buffer_recycle(buffer);
}
}
SW_RETURN_STRINGL(buffer->str + offset, length, 1);
}