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);
}

 

10-06 21:08