static apr_status_t serf_aggregate_peek()

in buckets/aggregate_buckets.c [434:497]


static apr_status_t serf_aggregate_peek(serf_bucket_t *bucket,
                                        const char **data,
                                        apr_size_t *len)
{
    aggregate_context_t *ctx = bucket->data;
    serf_bucket_t *head;
    apr_status_t status;

    cleanup_aggregate(ctx, bucket->allocator);

    /* Peek the first bucket in the list, if any. */
    if (!ctx->list) {
        *len = 0;
        if (ctx->hold_open) {
            status = ctx->hold_open(ctx->hold_open_baton, bucket);
            if (APR_STATUS_IS_EAGAIN(status))
                status = APR_SUCCESS;
            return status;
        }
        else {
            return APR_EOF;
        }
    }

    head = ctx->list->bucket;

    status = serf_bucket_peek(head, data, len);

    /* Is the current head *at* eof? */
    while (APR_STATUS_IS_EOF(status) && !*len) {
        bucket_list_t *item = ctx->list;

        if (item->next)
            ctx->list = item->next;
        else
            ctx->list = ctx->last = NULL;

        /* We don't have outstanding data. We are free to release now */
        serf_bucket_destroy(item->bucket);
        serf_bucket_mem_free(bucket->allocator, item);

        if (ctx->list) {
            head = ctx->list->bucket;
            status = serf_bucket_peek(head, data, len);
        }
        else
            break; /* Check hold open below */
    }

    if (APR_STATUS_IS_EOF(status)) {
        if (ctx->list && ctx->list->next) {
            status = APR_SUCCESS;
        } else {
            if (ctx->hold_open) {
                status = ctx->hold_open(ctx->hold_open_baton, bucket);
                if (APR_STATUS_IS_EAGAIN(status))
                    status = APR_SUCCESS;
                return status;
            }
        }
    }

    return status;
}