apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Cliff Woolley <cliffwool...@yahoo.com>
Subject Re: [PATCH] ap_brigade_partition() (was Re: brigade/bucket splitting)
Date Tue, 12 Dec 2000 06:15:01 GMT
--- Cliff Woolley <cliffwoolley@yahoo.com> wrote:
> ...
> +            if (point < len) {
> +                if (ap_bucket_split(e, point) == APR_SUCCESS)
> +                    return AP_BUCKET_NEXT(e);
> +                else
> +                    return NULL;
> +            }
> +            else if (point == len)
> +                return AP_BUCKET_NEXT(e);
> +        }
>      }

Oops, I just thought of a little buglet in this bit... I forgot to subtract len from
point if point > len as is done in the surrounding case.  Following is a revised
patch with this problem fixed.

--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/12 06:05:52
@@ -583,6 +583,18 @@
 APR_DECLARE(ap_bucket_brigade *) ap_brigade_split(ap_bucket_brigade *b,
 						 ap_bucket *e);
 
+/**
+ * Partition a bucket brigade at a given offset (in bytes from the start of
+ * the brigade).  This is useful whenever a filter wants to use known ranges
+ * of bytes from the brigade; the ranges can even overlap.
+ * @param b The brigade to partition
+ * @param point The offset at which to partition the brigade
+ * @return A pointer to the first bucket after the partition;
+ *         or NULL in any error condition (including partition past the end)
+ * @deffunc ap_bucket *ap_brigade_partition(ap_bucket_brigade *b, apr_off_t point)
+ */
+APR_DECLARE(ap_bucket *) ap_brigade_partition(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/12 06:06:26
@@ -122,31 +122,48 @@
     return a;
 }
 
-APR_DECLARE(apr_status_t) ap_bucket_split_any(ap_bucket *e, apr_off_t point)
+APR_DECLARE(ap_bucket *) ap_brigade_partition(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 if (point == e->length) {
+            return AP_BUCKET_NEXT(e);
+        }
+        else {
+            /* try to split the bucket natively */
+            if (ap_bucket_split(e, point) != APR_ENOTIMPL)
+                return 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_BUCKET_NEXT(e);
+                else
+                    return NULL;
+            }
+            else if (point == len)
+                return AP_BUCKET_NEXT(e);
+            else
+                point -= len;
+        }
     }
-    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/

Mime
View raw message