예제 #1
0
APU_DECLARE(apr_bucket_brigade *) apr_brigade_split_ex(apr_bucket_brigade *b,
                                                       apr_bucket *e,
                                                       apr_bucket_brigade *a)
{
    apr_bucket *f;

    if (!a) {
        a = apr_brigade_create(b->p, b->bucket_alloc);
    }
    else if (!APR_BRIGADE_EMPTY(a)) {
        apr_brigade_cleanup(a);
    }
    /* Return an empty brigade if there is nothing left in 
     * the first brigade to split off 
     */
    if (e != APR_BRIGADE_SENTINEL(b)) {
        f = APR_RING_LAST(&b->list);
        APR_RING_UNSPLICE(e, f, link);
        APR_RING_SPLICE_HEAD(&a->list, e, f, apr_bucket, link);
    }

    APR_BRIGADE_CHECK_CONSISTENCY(a);
    APR_BRIGADE_CHECK_CONSISTENCY(b);

    return a;
}
예제 #2
0
/**
 * Split the contents of a brigade after bucket 'e' to an existing brigade
 *
 * XXXX: Should this function be added to APR-Util?
 */
static void brigade_move(apr_bucket_brigade *b, apr_bucket_brigade *a,
                         apr_bucket *e)
{
    apr_bucket *f;

    if (e != APR_BRIGADE_SENTINEL(b)) {
        f = APR_RING_LAST(&b->list);
        APR_RING_UNSPLICE(e, f, link);
        APR_RING_SPLICE_HEAD(&a->list, e, f, apr_bucket, link);
    }

    APR_BRIGADE_CHECK_CONSISTENCY(a);
    APR_BRIGADE_CHECK_CONSISTENCY(b);
}
예제 #3
0
APU_DECLARE(apr_status_t) apr_brigade_partition(apr_bucket_brigade *b,
                                                apr_off_t point,
                                                apr_bucket **after_point)
{
    apr_bucket *e;
    const char *s;
    apr_size_t len;
    apr_uint64_t point64;
    apr_status_t rv;

    if (point < 0) {
        /* this could cause weird (not necessarily SEGV) things to happen */
        return APR_EINVAL;
    }
    if (point == 0) {
        *after_point = APR_BRIGADE_FIRST(b);
        return APR_SUCCESS;
    }

    /*
     * Try to reduce the following casting mess: We know that point will be
     * larger equal 0 now and forever and thus that point (apr_off_t) and
     * apr_size_t will fit into apr_uint64_t in any case.
     */
    point64 = (apr_uint64_t)point;

    APR_BRIGADE_CHECK_CONSISTENCY(b);

    for (e = APR_BRIGADE_FIRST(b);
         e != APR_BRIGADE_SENTINEL(b);
         e = APR_BUCKET_NEXT(e))
    {
        /* For an unknown length bucket, while 'point64' is beyond the possible
         * size contained in apr_size_t, read and continue...
         */
        if ((e->length == (apr_size_t)(-1))
            && (point64 > (apr_uint64_t)APR_SIZE_MAX)) {
            /* point64 is too far out to simply split this bucket,
             * we must fix this bucket's size and keep going... */
            rv = apr_bucket_read(e, &s, &len, APR_BLOCK_READ);
            if (rv != APR_SUCCESS) {
                *after_point = e;
                return rv;
            }
        }
        else if ((point64 < (apr_uint64_t)e->length)
                 || (e->length == (apr_size_t)(-1))) {
            /* We already consumed buckets where point64 is beyond
             * our interest ( point64 > APR_SIZE_MAX ), above.
             * Here point falls between 0 and APR_SIZE_MAX
             * and is within this bucket, or this bucket's len
             * is undefined, so now we are ready to split it.
             * First try to split the bucket natively... */
            if ((rv = apr_bucket_split(e, (apr_size_t)point64)) 
                    != APR_ENOTIMPL) {
                *after_point = APR_BUCKET_NEXT(e);
                return rv;
            }

            /* if the bucket cannot be split, we must read from it,
             * changing its type to one that can be split */
            rv = apr_bucket_read(e, &s, &len, APR_BLOCK_READ);
            if (rv != APR_SUCCESS) {
                *after_point = e;
                return rv;
            }

            /* this assumes that len == e->length, which is okay because e
             * might have been morphed by the apr_bucket_read() above, but
             * if it was, the length would have been adjusted appropriately */
            if (point64 < (apr_uint64_t)e->length) {
                rv = apr_bucket_split(e, (apr_size_t)point64);
                *after_point = APR_BUCKET_NEXT(e);
                return rv;
            }
        }
        if (point64 == (apr_uint64_t)e->length) {
            *after_point = APR_BUCKET_NEXT(e);
            return APR_SUCCESS;
        }
        point64 -= (apr_uint64_t)e->length;
    }
    *after_point = APR_BRIGADE_SENTINEL(b); 
    return APR_INCOMPLETE;
}
예제 #4
0
APU_DECLARE(apr_status_t) apr_brigade_partition(apr_bucket_brigade *b,
                                                apr_off_t point,
                                                apr_bucket **after_point)
{
    apr_bucket *e;
    const char *s;
    apr_size_t len;
    apr_status_t rv;

    if (point < 0) {
        /* this could cause weird (not necessarily SEGV) things to happen */
        return APR_EINVAL;
    }
    if (point == 0) {
        *after_point = APR_BRIGADE_FIRST(b);
        return APR_SUCCESS;
    }

    APR_BRIGADE_CHECK_CONSISTENCY(b);

    for (e = APR_BRIGADE_FIRST(b);
         e != APR_BRIGADE_SENTINEL(b);
         e = APR_BUCKET_NEXT(e))
    {
        if ((e->length == (apr_size_t)(-1)) && (point > (apr_size_t)(-1))) {
            /* point is too far out to simply split this bucket,
             * we must fix this bucket's size and keep going... */
            rv = apr_bucket_read(e, &s, &len, APR_BLOCK_READ);
            if (rv != APR_SUCCESS) {
                *after_point = e;
                return rv;
            }
        }
        if ((point < e->length) || (e->length == (apr_size_t)(-1))) {
            /* We already checked e->length -1 above, so we now
             * trust e->length < MAX_APR_SIZE_T.
             * First try to split the bucket natively... */
            if ((rv = apr_bucket_split(e, (apr_size_t)point)) 
                    != APR_ENOTIMPL) {
                *after_point = APR_BUCKET_NEXT(e);
                return rv;
            }

            /* if the bucket cannot be split, we must read from it,
             * changing its type to one that can be split */
            rv = apr_bucket_read(e, &s, &len, APR_BLOCK_READ);
            if (rv != APR_SUCCESS) {
                *after_point = e;
                return rv;
            }

            /* this assumes that len == e->length, which is okay because e
             * might have been morphed by the apr_bucket_read() above, but
             * if it was, the length would have been adjusted appropriately */
            if (point < e->length) {
                rv = apr_bucket_split(e, (apr_size_t)point);
                *after_point = APR_BUCKET_NEXT(e);
                return rv;
            }
        }
        if (point == e->length) {
            *after_point = APR_BUCKET_NEXT(e);
            return APR_SUCCESS;
        }
        point -= e->length;
    }
    *after_point = APR_BRIGADE_SENTINEL(b); 
    return APR_INCOMPLETE;
}