You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by rb...@apache.org on 2001/02/09 07:19:44 UTC

cvs commit: apr-util/include apr_buckets.h

rbb         01/02/08 22:19:44

  Modified:    buckets  apr_brigade.c
               include  apr_buckets.h
  Log:
  Allow brigades to buffer data natively with apr_brigade_write,
  apr_brigade_puts, etc.  This uses a heap bucket to store the data at the
  end of the brigade.  If the bucket overflows, then we call the flush
  function that is passed in to flush the brigade to the correct location.
  Submitted by:	Ryan Bloom and Greg Stein
  
  Revision  Changes    Path
  1.5       +147 -27   apr-util/buckets/apr_brigade.c
  
  Index: apr_brigade.c
  ===================================================================
  RCS file: /home/cvs/apr-util/buckets/apr_brigade.c,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -d -b -w -u -r1.4 -r1.5
  --- apr_brigade.c	2001/02/08 07:45:23	1.4
  +++ apr_brigade.c	2001/02/09 06:19:43	1.5
  @@ -56,6 +56,7 @@
   #include "apr_lib.h"
   #include "apr_pools.h"
   #include "apr_tables.h"
  +#include "apr_buckets.h"
   #include "apr_errno.h"
   
   #include <stdlib.h>
  @@ -66,8 +67,6 @@
   #include <sys/uio.h>
   #endif
   
  -#include "apr_buckets.h"
  -
   static apr_status_t apr_brigade_cleanup(void *data)
   {
       apr_bucket_brigade *b = data;
  @@ -97,8 +96,9 @@
   {
       apr_bucket_brigade *b;
   
  -    b = apr_palloc(p, sizeof(*b));
  +    b = apr_pcalloc(p, sizeof(*b));
       b->p = p;
  +
       APR_RING_INIT(&b->list, apr_bucket, link);
   
       apr_pool_cleanup_register(b->p, b, apr_brigade_cleanup, apr_brigade_cleanup);
  @@ -185,12 +185,56 @@
       return vec - orig;
   }
   
  -APU_DECLARE(int) apr_brigade_vputstrs(apr_bucket_brigade *b, va_list va)
  +static int check_brigade_flush(const char **str, 
  +                               apr_size_t *n, apr_bucket_brigade *bb,
  +                               brigade_flush flush)
   {
  -    apr_bucket *r;
  +    apr_bucket *b = APR_BRIGADE_LAST(bb);
  +
  +    if (APR_BRIGADE_EMPTY(bb)) {
  +        if (*n > APR_BUCKET_BUFF_SIZE) {
  +            apr_bucket *e;
  +            if (flush) {
  +                e = apr_bucket_transient_create(*str, *n);
  +            }
  +            else {
  +                e = apr_bucket_heap_create(*str, *n, 0, NULL);
  +            }
  +            APR_BRIGADE_INSERT_TAIL(bb, e);
  +            return 1;
  +        }
  +        else {
  +            return 0;
  +        }
  +    }
  +
  +    if (APR_BUCKET_IS_HEAP(b)) {
  +        apr_bucket_shared *s = b->data;
  +        apr_bucket_heap *h = s->data;
  +
  +        if (*n > (h->alloc_len - (s->end - s->start))) {
  +            apr_bucket *e = apr_bucket_transient_create(*str, *n);
  +            APR_BRIGADE_INSERT_TAIL(bb, e);
  +            return 1;
  +        }
  +    }
  +    else if (*n > APR_BUCKET_BUFF_SIZE) {
  +        apr_bucket *e = apr_bucket_transient_create(*str, *n);
  +        APR_BRIGADE_INSERT_TAIL(bb, e);
  +        return 1;
  +    }
  +
  +    return 0;
  +}
  +
  +APU_DECLARE(int) apr_brigade_vputstrs(apr_bucket_brigade *b, 
  +                                      brigade_flush flush, void *ctx,
  +                                      va_list va)
  +                                    
  +                                   
  +{
       const char *x;
       int j, k;
  -    apr_size_t i;
   
       for (k = 0;;) {
           x = va_arg(va, const char *);
  @@ -198,55 +242,131 @@
               break;
           j = strlen(x);
          
  -	/* XXX: copy or not? let the caller decide? */
  -        r = apr_bucket_heap_create(x, j, 1, &i);
  -        if (i != j) {
  -            /* Do we need better error reporting?  */
  -            return -1;
  +        k += apr_brigade_write(b, flush, ctx, x, j);
           }
  -        k += i;
  +    return k;
  +}
   
  -        APR_BRIGADE_INSERT_TAIL(b, r);
  +APU_DECLARE(int) apr_brigade_putc(apr_bucket_brigade *b, brigade_flush flush, 
  +                                  void *ctx, const char c)
  +{
  +    apr_size_t nbyte = 1;
  +    const char *str = &c;
  +
  +    if (check_brigade_flush(&str, &nbyte, b, flush)) {
  +        if (flush) {
  +            return flush(b, ctx);
       }
  +    }
  +    else {
  +        apr_bucket *buck = APR_BRIGADE_LAST(b);
  +        apr_bucket_shared *s;
  +        apr_bucket_heap *h;
  +        char *buf;
   
  -    return k;
  +        if (!APR_BUCKET_IS_HEAP(buck) || APR_BRIGADE_EMPTY(b)) {
  +            buf = malloc(APR_BUCKET_BUFF_SIZE);
  +
  +            buck = apr_bucket_heap_create(buf, APR_BUCKET_BUFF_SIZE, 0, NULL);
  +            s = buck->data;
  +            s->start = s->end = 0;
  +            h = s->data;
  +
  +            APR_BRIGADE_INSERT_TAIL(b, buck);
   }
  +        else {
  +            s = buck->data;
  +            h = s->data;
   
  -APU_DECLARE_NONSTD(int) apr_brigade_putstrs(apr_bucket_brigade *b, ...)
  +            buf = h->base + s->end;
  +        }
  +        memcpy(buf, &c, 1);
  +        s->end++;
  +    }
  +
  +    return 1;
  +}
  +
  +APU_DECLARE(int) apr_brigade_write(apr_bucket_brigade *b, 
  +                                   brigade_flush flush, void *ctx, 
  +                                   const char *str, apr_size_t nbyte)
   {
  +    if (check_brigade_flush(&str, &nbyte, b, flush)) {
  +        if (flush) {
  +            return flush(b, ctx);
  +        }
  +    }
  +    else {
  +        apr_bucket *buck = APR_BRIGADE_LAST(b);
  +        apr_bucket_shared *s;
  +        apr_bucket_heap *h;
  +        char *buf;
  +
  +        if (!APR_BUCKET_IS_HEAP(buck) || APR_BRIGADE_EMPTY(b)) {
  +            buf = malloc(APR_BUCKET_BUFF_SIZE);
  +
  +            buck = apr_bucket_heap_create(buf, APR_BUCKET_BUFF_SIZE, 0, NULL);
  +            s = buck->data;
  +            s->start = s->end = 0;
  +            h = s->data;
  +
  +            APR_BRIGADE_INSERT_TAIL(b, buck);
  +        }
  +        else {
  +            s = buck->data;
  +            h = s->data;
  +
  +            buf = h->base + s->end;
  +        }
  +
  +        memcpy(buf, str, nbyte);
  +        s->end += nbyte;
  +    }
  +    return nbyte;
  +}
  +
  +APU_DECLARE(int) apr_brigade_puts(apr_bucket_brigade *b, brigade_flush flush, 
  +                                  void *ctx, const char *str)
  +{
  +    return apr_brigade_write(b, flush, ctx, str, strlen(str));
  +}
  +
  +APU_DECLARE_NONSTD(int) apr_brigade_putstrs(apr_bucket_brigade *b, 
  +                                           brigade_flush flush, void *ctx, ...)
  +{
       va_list va;
       int written;
   
  -    va_start(va, b);
  -    written = apr_brigade_vputstrs(b, va);
  +    va_start(va, ctx);
  +    written = apr_brigade_vputstrs(b, flush, ctx, va);
       va_end(va);
       return written;
   }
   
  -APU_DECLARE_NONSTD(int) apr_brigade_printf(apr_bucket_brigade *b, const char *fmt, ...)
  +APU_DECLARE_NONSTD(int) apr_brigade_printf(apr_bucket_brigade *b, 
  +                                           brigade_flush flush, void *ctx, 
  +                                           const char *fmt, ...)
   {
       va_list ap;
       int res;
   
       va_start(ap, fmt);
  -    res = apr_brigade_vprintf(b, fmt, ap);
  +    res = apr_brigade_vprintf(b, flush, ctx, fmt, ap);
       va_end(ap);
       return res;
   }
   
  -APU_DECLARE(int) apr_brigade_vprintf(apr_bucket_brigade *b, const char *fmt, va_list va)
  +APU_DECLARE(int) apr_brigade_vprintf(apr_bucket_brigade *b, 
  +                                     brigade_flush flush, void *ctx, 
  +                                     const char *fmt, va_list va)
   {
       /* XXX:  This needs to be replaced with a function to printf
        * directly into a bucket.  I'm being lazy right now.  RBB
        */
       char buf[4096];
  -    apr_bucket *r;
  -    int res;
   
  -    res = apr_vsnprintf(buf, 4096, fmt, va);
  -
  -    r = apr_bucket_heap_create(buf, strlen(buf), 1, NULL);
  -    APR_BRIGADE_INSERT_TAIL(b, r);
  +    apr_vsnprintf(buf, 4096, fmt, va);
   
  -    return res;
  +    return apr_brigade_puts(b, flush, ctx, buf);
   }
  +
  
  
  
  1.70      +43 -14    apr-util/include/apr_buckets.h
  
  Index: apr_buckets.h
  ===================================================================
  RCS file: /home/cvs/apr-util/include/apr_buckets.h,v
  retrieving revision 1.69
  retrieving revision 1.70
  diff -u -d -b -w -u -r1.69 -r1.70
  --- apr_buckets.h	2001/02/08 07:45:29	1.69
  +++ apr_buckets.h	2001/02/09 06:19:44	1.70
  @@ -78,6 +78,8 @@
    * @package Bucket Brigades
    */
   
  +#define APR_BUCKET_BUFF_SIZE 9000
  +
   typedef enum {APR_BLOCK_READ, APR_NONBLOCK_READ} apr_read_type_e;
   
   /*
  @@ -248,6 +250,8 @@
       APR_RING_HEAD(apr_bucket_list, apr_bucket) list;
   };
   
  +typedef apr_status_t (*brigade_flush)(apr_bucket_brigade *bb, void *ctx);
  +
   /**
    * Wrappers around the RING macros to reduce the verbosity of the code
    * that handles bucket brigades.
  @@ -533,7 +537,7 @@
        * modified, it is only used to free the bucket.
        */
       char    *base;
  -    /** how much memory was allocated.  This may not be necessary */
  +    /** how much memory was allocated */
       size_t  alloc_len;
   };
   
  @@ -629,48 +633,73 @@
   				     struct iovec *vec, int nvec);
   
   /**
  - * This function writes a list of strings into a bucket brigade.  We just 
  - * allocate a new heap bucket for each string.
  + * This function writes a list of strings into a bucket brigade. 
    * @param b The bucket brigade to add to
    * @param va A list of strings to add
    * @return The number of bytes added to the brigade
  - * @deffunc int apr_brigade_vputstrs(apr_bucket_brigade *b, va_list va)
  + * @deffunc int apr_brigade_vputstrs(apr_bucket_brigade *b, brigade_flush flush, void *ctx, va_list va)
    */
  -APU_DECLARE(int) apr_brigade_vputstrs(apr_bucket_brigade *b, va_list va);
  +APU_DECLARE(int) apr_brigade_vputstrs(apr_bucket_brigade *b, brigade_flush flush, void *ctx, va_list va);
   
   /**
  + * This function writes an string into a bucket brigade.
  + * @param b The bucket brigade to add to
  + * @param str The string to add
  + * @return The number of bytes added to the brigade
  + * @deffunc int apr_brigade_write(ap_bucket_brigade *b, brigade_flush flush, void *ctx, const char *str)
  + */
  +APU_DECLARE(int) apr_brigade_write(apr_bucket_brigade *b, brigade_flush flush, void *ctx, const char *str, apr_size_t nbyte);
  +
  +/**
  + * This function writes an string into a bucket brigade.
  + * @param b The bucket brigade to add to
  + * @param str The string to add
  + * @return The number of bytes added to the brigade
  + * @deffunc int apr_brigade_puts(ap_bucket_brigade *b, brigade_flush flush, void *ctx, const char *str)
  + */
  +APU_DECLARE(int) apr_brigade_puts(apr_bucket_brigade *b, brigade_flush flush, void *ctx, const char *str);
  +
  +/**
  + * This function writes a character into a bucket brigade.
  + * @param b The bucket brigade to add to
  + * @param c The character to add
  + * @return The number of bytes added to the brigade
  + * @deffunc int apr_brigade_putc(apr_bucket_brigade *b, brigade_flush flush, void *ctx, const char c)
  + */
  +APU_DECLARE(int) apr_brigade_putc(apr_bucket_brigade *b, brigade_flush flush, void *ctx, const char c);
  +
  +/**
    * This function writes an unspecified number of strings into a bucket brigade.
  - * We just allocate a new heap bucket for each string.
    * @param b The bucket brigade to add to
    * @param ... The strings to add
    * @return The number of bytes added to the brigade
  - * @deffunc int apr_brigade_putstrs(apr_bucket_brigade *b, ...)
  + * @deffunc int apr_brigade_putstrs(apr_bucket_brigade *b, brigade_flush flush, void *ctx, ...)
    */
  -APU_DECLARE_NONSTD(int) apr_brigade_putstrs(apr_bucket_brigade *b, ...);
  +APU_DECLARE_NONSTD(int) apr_brigade_putstrs(apr_bucket_brigade *b, brigade_flush flush, void *ctx, ...);
   
   /**
  - * Evaluate a printf and put the resulting string into a bucket at the end 
  + * Evaluate a printf and put the resulting string at the end 
    * of the bucket brigade.
    * @param b The brigade to write to
    * @param fmt The format of the string to write
    * @param ... The arguments to fill out the format
    * @return The number of bytes added to the brigade
  - * @deffunc int apr_brigade_printf(apr_bucket_brigade *b, const char *fmt, ...) 
  + * @deffunc int apr_brigade_printf(apr_bucket_brigade *b, brigade_flush flush, void *ctx, const char *fmt, ...) 
    */
   APU_DECLARE_NONSTD(int) apr_brigade_printf(apr_bucket_brigade *b, 
  -                                          const char *fmt, ...);
  +                                          brigade_flush flush, void *ctx, const char *fmt, ...);
   
   /**
  - * Evaluate a printf and put the resulting string into a bucket at the end 
  + * Evaluate a printf and put the resulting string at the end 
    * of the bucket brigade.
    * @param b The brigade to write to
    * @param fmt The format of the string to write
    * @param va The arguments to fill out the format
    * @return The number of bytes added to the brigade
  - * @deffunc int apr_brigade_vprintf(apr_bucket_brigade *b, const char *fmt, va_list va) 
  + * @deffunc int apr_brigade_vprintf(apr_bucket_brigade *b, brigade_flush flush, void *ctx, const char *fmt, va_list va) 
    */
   APU_DECLARE(int) apr_brigade_vprintf(apr_bucket_brigade *b, 
  -                                    const char *fmt, va_list va);
  +                                    brigade_flush flush, void *ctx, const char *fmt, va_list va);
   
   
   /*  *****  Bucket Functions  *****  */
  
  
  

Re: cvs commit: apr-util/include apr_buckets.h

Posted by Bill Stoddard <bi...@wstoddard.com>.
> rbb         01/02/08 22:19:44
> 
>   Modified:    buckets  apr_brigade.c
>                include  apr_buckets.h
>   Log:
>   Allow brigades to buffer data natively with apr_brigade_write,
>   apr_brigade_puts, etc.  This uses a heap bucket to store the data at the
>   end of the brigade.  If the bucket overflows, then we call the flush
>   function that is passed in to flush the brigade to the correct location.
>   Submitted by: Ryan Bloom and Greg Stein
>   

WooHoo!!! 

Bill