static apr_uint64_t serf_split_get_remaining()

in buckets/split_buckets.c [274:339]


static apr_uint64_t serf_split_get_remaining(serf_bucket_t *bucket)
{
    split_stream_ctx_t *sctx = bucket->data;
    split_context_t *ctx = sctx->ctx;
    split_stream_ctx_t *head;
    apr_uint64_t remaining;

    if (!ctx || sctx->at_eof) {
        return 0; /* at eof */
    }
    else if (ctx->head == sctx) {
        /* We are HEAD. We hereby unlock the data to allow reading the size */
        sctx->cant_read = false;
    }

    if (sctx->fixed_size) {
        return sctx->fixed_size - sctx->read_size; /* already calculated */
    }

    /* Do we know the total size? */
    head = ctx->head;

    if (head->tail_size == SERF_LENGTH_UNKNOWN) {
        if (head->cant_read) {
            /* Can't obtain the size without unlocking data*/
            ctx->want_size = true;

            return SERF_LENGTH_UNKNOWN;
        }
        head->tail_size = serf_bucket_get_remaining(ctx->stream);

        if (head->tail_size == SERF_LENGTH_UNKNOWN)
            return SERF_LENGTH_UNKNOWN;

        /* Add what we already have to avoid updating on every read */
        head->tail_size += head->read_size;
    }

    remaining = head->tail_size;
    /* And now we fix the sizes of the buckets until we get to
       the one we're interested in */
    while (head) {

        if (!head->fixed_size) {
            /* Size not decided yet. Let's make this chunk as big
               as allowed */
            head->fixed_size = (remaining < head->max_size)
                                ? (apr_size_t)remaining
                                : head->max_size;

            /* Disable dynamic sizing now */
            head->min_size = head->max_size = head->fixed_size;
        }

        if (head == sctx) {
            /* We got the information we need. Exit now to avoid
               fixing the length of more buckets than needed */
            return sctx->fixed_size - sctx->read_size;
        }

        remaining -= head->fixed_size;
        head = head->next;
    }

    return SERF_LENGTH_UNKNOWN; /* Hit NULL before our bucket??? */
}