in buckets/hpack_buckets.c [1523:1593]
static apr_status_t hpack_read_bytes(serf_bucket_t *bucket,
apr_size_t required,
const void **data)
{
serf_hpack_decode_ctx_t *ctx = bucket->data;
apr_status_t status = APR_SUCCESS;
apr_size_t len;
const char *some_data;
/* assert(required < ctx->buffer_used); */
if (required == 0)
{
*data = ctx->buffer;
return APR_SUCCESS;
}
if (!ctx->buffer_used)
{
status = serf_bucket_read(ctx->stream, required, &some_data, &len);
if (SERF_BUCKET_READ_ERROR(status) || (len == required))
{
if (APR_STATUS_IS_EOF(status) && len == required)
status = APR_SUCCESS;
*data = some_data;
return status;
}
hpack_decode_buffer_ensure(bucket, required);
memcpy(ctx->buffer, some_data, len);
ctx->buffer_used = len;
if (status)
return status;
/* Fall through: Try to continue reading*/
}
else
{
/* Ensure that the buffer is large enough to hold everything */
hpack_decode_buffer_ensure(bucket, required);
}
while (ctx->buffer_used < required)
{
status = serf_bucket_read(ctx->stream, required - ctx->buffer_used,
&some_data, &len);
if (SERF_BUCKET_READ_ERROR(status))
return status;
memcpy(ctx->buffer + ctx->buffer_used, some_data, len);
ctx->buffer_used += len;
if (status)
break;
else if (!status && !len)
return SERF_ERROR_EMPTY_READ;
}
if (ctx->buffer_used == required)
{
*data = ctx->buffer;
ctx->buffer_used = 0; /* Done with buffer */
status = APR_SUCCESS;
}
return status;
}