apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Greg Stein <gst...@lyra.org>
Subject Re: [PATCH] ap_brigade_split_any
Date Mon, 11 Dec 2000 23:31:50 GMT
I'm not sure where this semantic was introduced. (I'll blame Ryan :-)

The intent isn't to create *another* brigade. It is to split a bucket
*within* a brigade. The specific operation that we want to provide for is
within the byterange filter:

1) split a bucket at points P1 and P2
2) copy buckets from P1 through P2 and add these to the output brigade

We do not want to destructively modify the original brigade. We are using
split() as a precursor to copying a subrange of the input brigade.

Cheers,
-g

On Sat, Dec 09, 2000 at 03:54:48PM -0800, Cliff Woolley wrote:
> 
> Here it is... though it's tested only to compile.  Take a look and see if this seems
> sane.
> 
> --Cliff
> 
> 
> 
> Index: include/ap_buckets.h
> ===================================================================
> RCS file: /home/cvspublic/apr-util/include/ap_buckets.h,v
> retrieving revision 1.59
> diff -u -r1.59 ap_buckets.h
> --- include/ap_buckets.h	2000/12/09 21:22:43	1.59
> +++ include/ap_buckets.h	2000/12/09 23:51:46
> @@ -583,6 +583,18 @@
>  APR_DECLARE(ap_bucket_brigade *) ap_brigade_split(ap_bucket_brigade *b,
>  						 ap_bucket *e);
>  
> +/**
> + * Split a bucket brigade into two using an offset in bytes into the
> + * brigade.  This is useful whenever a filter wants to use a known range
> + * of bytes from the brigade without having to manually step through each
> + * bucket up to that point.
> + * @param b The brigade to split
> + * @param point The offset to split the brigade at
> + * @return The new brigade, or NULL in any error condition
> + * @deffunc ap_bucket_brigade *ap_brigade_split_offset(ap_bucket_brigade *b,
> apr_off_t point)
> + */
> +APR_DECLARE(ap_bucket_brigade *) ap_brigade_split_offset(ap_bucket_brigade *b,
> apr_off_t point);
> +
>  #if APR_NOT_DONE_YET
>  /**
>   * consume nbytes from beginning of b -- call ap_bucket_destroy as
> @@ -704,18 +716,6 @@
>   * @deffunc apr_status_t ap_bucket_copy(ap_bucket *e, ap_bucket **c)
>   */
>  #define ap_bucket_copy(e,c) e->type->copy(e, c)
> -
> -/**
> - * Split a bucket into two, using ap_bucket_split() if that's possible
> - * for the given bucket type. If split() is not implemented for the
> - * bucket's type, then we perform a blocking read on the bucket. That
> - * morphs the bucket into a splittable bucket (eg, pipe becomes heap),
> - * and we then split the result.
> - * @param e The bucket to split
> - * @param point The offset to split the bucket at
> - * @deffunc apr_status_t ap_bucket_split_any(ap_bucket *e, apr_off_t point)
> - */
> -APR_DECLARE(apr_status_t) ap_bucket_split_any(ap_bucket *e, apr_off_t point);
>  
>  /* Bucket type handling */
>  
> Index: src/buckets/ap_buckets.c
> ===================================================================
> RCS file: /home/cvspublic/apr-util/src/buckets/ap_buckets.c,v
> retrieving revision 1.36
> diff -u -r1.36 ap_buckets.c
> --- src/buckets/ap_buckets.c	2000/12/09 21:22:44	1.36
> +++ src/buckets/ap_buckets.c	2000/12/09 23:51:47
> @@ -122,31 +122,41 @@
>      return a;
>  }
>  
> -APR_DECLARE(apr_status_t) ap_bucket_split_any(ap_bucket *e, apr_off_t point)
> +APR_DECLARE(ap_bucket_brigade *) ap_brigade_split_offset(ap_bucket_brigade *b,
> apr_off_t point)
>  {
> -    apr_status_t rv;
> -    const char *str;
> +    ap_bucket *e;
> +    const char *s;
>      apr_size_t len;
>  
> -    /* try to split this bucket directly */
> -    rv = ap_bucket_split(e, point);
> -    if (rv != APR_ENOTIMPL) {
> -        return rv;
> -    }
> +    if (point < 0)
> +        return NULL;
>  
> -    /* if the bucket cannot be split, we must read from it,
> -     * changing its type to one that can be split */
> -    if (point < 0) {
> -        return APR_EINVAL;
> -    }
> -    rv = ap_bucket_read(e, &str, &len, AP_BLOCK_READ);
> -    if (rv != APR_SUCCESS) {
> -        return rv;
> -    }
> -    if (point > len) {
> -        return APR_EINVAL;
> +    AP_BRIGADE_FOREACH(e, b) {
> +        /* bucket is of a known length */
> +        if ((point > e->length) && (e->length != -1)) {
> +            if (AP_BUCKET_IS_EOS(e))
> +                return NULL;
> +            point -= e->length;
> +        }
> +        else {
> +            /* try to split the bucket natively */
> +            if (ap_bucket_split(e, point) != APR_ENOTIMPL)
> +                return ap_brigade_split(b, AP_BUCKET_NEXT(e));
> +
> +            /* if the bucket cannot be split, we must read from it,
> +             * changing its type to one that can be split */
> +            if (ap_bucket_read(e, &s, &len, AP_BLOCK_READ) != APR_SUCCESS)
> +                return NULL;
> +
> +            if (point <= len) {
> +                if (ap_bucket_split(e, point) == APR_SUCCESS)
> +                    return ap_brigade_split(b, AP_BUCKET_NEXT(e));
> +                else
> +                    return NULL;
> +            }
> +        }
>      }
> -    return ap_bucket_split(e, point);
> +    return NULL;
>  }
>  
>  APR_DECLARE(int) ap_brigade_to_iovec(ap_bucket_brigade *b, 
> 
> __________________________________________________
> Do You Yahoo!?
> Yahoo! Shopping - Thousands of Stores. Millions of Products.
> http://shopping.yahoo.com/

-- 
Greg Stein, http://www.lyra.org/

Mime
View raw message