jwoolley 01/02/27 12:45:39
Modified: buckets apr_brigade.c apr_buckets_eos.c apr_buckets_file.c
apr_buckets_flush.c apr_buckets_heap.c
apr_buckets_mmap.c apr_buckets_pipe.c
apr_buckets_pool.c apr_buckets_refcount.c
apr_buckets_simple.c apr_buckets_socket.c
include apr_buckets.h
Added: . CHANGES
Log:
*) The apr_bucket_shared and apr_bucket_simple structures have been
removed as an API simplification/optimization. This should be
transparent outside APR-util except to callers who attempt to
directly manipulate the buckets' internal structure (which is
not recommended anyway) and to callers who create their own
bucket types.
*) apr_bucket_simple_split() and apr_bucket_simple_copy() are now
exported functions, which could be helpful in implementing
external bucket types.
*) The third parameter to apr_bucket_shared_make() is now
'apr_off_t length' rather than 'apr_off_t end', since the
end usually had to be computed by the caller and all we
really want is the length anyway.
This addresses issue #1 from the "Bucket API cleanup issues" thread.
Revision Changes Path
1.1 apr-util/CHANGES
Index: CHANGES
===================================================================
Changes with APR-util b1
*) The apr_bucket_shared and apr_bucket_simple structures have been
removed as an API simplification/optimization. This should be
transparent outside APR-util except to callers who attempt to
directly manipulate the buckets' internal structure (which is
not recommended anyway) and to callers who create their own
bucket types. [Cliff Woolley]
*) apr_bucket_simple_split() and apr_bucket_simple_copy() are now
exported functions, which could be helpful in implementing
external bucket types. [Cliff Woolley]
*) The third parameter to apr_bucket_shared_make() is now
'apr_off_t length' rather than 'apr_off_t end', since the
end usually had to be computed by the caller and all we
really want is the length anyway. [Cliff Woolley]
1.10 +14 -26 apr-util/buckets/apr_brigade.c
Index: apr_brigade.c
===================================================================
RCS file: /home/cvs/apr-util/buckets/apr_brigade.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -u -r1.9 -r1.10
--- apr_brigade.c 2001/02/16 04:17:07 1.9
+++ apr_brigade.c 2001/02/27 20:45:36 1.10
@@ -239,18 +239,15 @@
}
if (APR_BUCKET_IS_HEAP(b)) {
- apr_bucket_shared *s = b->data;
- apr_bucket_heap *h = s->data;
+ apr_bucket_heap *h = b->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);
+ if (*n > (h->alloc_len - b->length)) {
+ APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_transient_create(*str,
*n));
return 1;
}
}
else if (*n > APR_BUCKET_BUFF_SIZE) {
- apr_bucket *e = apr_bucket_transient_create(*str, *n);
- APR_BRIGADE_INSERT_TAIL(bb, e);
+ APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_transient_create(*str, *n));
return 1;
}
@@ -282,40 +279,31 @@
return apr_brigade_write(b, flush, ctx, &c, 1);
}
-APU_DECLARE(int) apr_brigade_write(apr_bucket_brigade *b,
+APU_DECLARE(int) apr_brigade_write(apr_bucket_brigade *bb,
apr_brigade_flush flush, void *ctx,
const char *str, apr_size_t nbyte)
{
- if (check_brigade_flush(&str, &nbyte, b, flush)) {
+ if (check_brigade_flush(&str, &nbyte, bb, flush)) {
if (flush) {
- return flush(b, ctx);
+ return flush(bb, ctx);
}
}
else {
- apr_bucket *buck = APR_BRIGADE_LAST(b);
- apr_bucket_shared *s;
- apr_bucket_heap *h;
+ apr_bucket *b = APR_BRIGADE_LAST(bb);
char *buf;
- if (!APR_BUCKET_IS_HEAP(buck) || APR_BRIGADE_EMPTY(b)) {
+ if (APR_BRIGADE_EMPTY(bb) || !APR_BUCKET_IS_HEAP(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);
+ b = apr_bucket_heap_create(buf, APR_BUCKET_BUFF_SIZE, 0, NULL);
+ APR_BRIGADE_INSERT_TAIL(bb, b);
}
else {
- s = buck->data;
- h = s->data;
-
- buf = h->base + s->end;
+ apr_bucket_heap *h = b->data;
+ buf = h->base + b->start + b->length;
}
memcpy(buf, str, nbyte);
- s->end += nbyte;
+ b->length += nbyte;
}
return nbyte;
}
1.22 +1 -1 apr-util/buckets/apr_buckets_eos.c
Index: apr_buckets_eos.c
===================================================================
RCS file: /home/cvs/apr-util/buckets/apr_buckets_eos.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -u -r1.21 -r1.22
--- apr_buckets_eos.c 2001/02/16 04:17:07 1.21
+++ apr_buckets_eos.c 2001/02/27 20:45:36 1.22
@@ -72,8 +72,8 @@
APU_DECLARE(apr_bucket *) apr_bucket_eos_make(apr_bucket *b)
{
b->length = 0;
+ b->start = 0;
b->data = NULL;
-
b->type = &apr_bucket_type_eos;
return b;
1.36 +13 -18 apr-util/buckets/apr_buckets_file.c
Index: apr_buckets_file.c
===================================================================
RCS file: /home/cvs/apr-util/buckets/apr_buckets_file.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -d -u -r1.35 -r1.36
--- apr_buckets_file.c 2001/02/27 18:53:07 1.35
+++ apr_buckets_file.c 2001/02/27 20:45:36 1.36
@@ -99,13 +99,13 @@
static apr_status_t file_read(apr_bucket *e, const char **str,
apr_size_t *len, apr_read_type_e block)
{
- apr_bucket_shared *s = e->data;
- apr_bucket_file *a = s->data;
+ apr_bucket_file *a = e->data;
apr_file_t *f = a->fd;
apr_bucket *b = NULL;
char *buf;
apr_status_t rv;
apr_off_t filelength = e->length; /* bytes remaining in file past
offset */
+ apr_off_t fileoffset = e->start;
#if APR_HAS_MMAP
apr_mmap_t *mm = NULL;
#endif
@@ -117,7 +117,7 @@
* file mmapped */
apr_status_t status;
apr_pool_t *p = apr_file_pool_get(f);
- if ((status = apr_mmap_create(&mm, f, s->start, filelength,
+ if ((status = apr_mmap_create(&mm, f, fileoffset, filelength,
APR_MMAP_READ, p)) != APR_SUCCESS) {
mm = NULL;
}
@@ -126,8 +126,8 @@
mm = NULL;
}
if (mm) {
- apr_bucket_mmap_make(e, mm, 0, e->length); /*XXX: check for failure?
*/
- file_destroy(s);
+ apr_bucket_mmap_make(e, mm, 0, filelength); /*XXX: check for
failure? */
+ file_destroy(a);
return apr_bucket_read(e, str, len, block);
}
#endif
@@ -137,8 +137,8 @@
buf = malloc(*len);
/* Handle offset ... */
- if (s->start) {
- rv = apr_file_seek(f, APR_SET, &s->start);
+ if (fileoffset) {
+ rv = apr_file_seek(f, APR_SET, &fileoffset);
if (rv != APR_SUCCESS) {
free(buf);
return rv;
@@ -159,16 +159,16 @@
/* If we have more to read from the file, then create another bucket */
if (filelength > 0) {
/* for efficiency, we can just build a new apr_bucket struct
- * to wrap around the existing shared+file bucket */
- s->start += (*len);
+ * to wrap around the existing file bucket */
b = malloc(sizeof(*b));
- b->data = s;
- b->type = &apr_bucket_type_file;
+ b->start = fileoffset + (*len);
b->length = filelength;
+ b->data = a;
+ b->type = &apr_bucket_type_file;
APR_BUCKET_INSERT_AFTER(e, b);
}
else {
- file_destroy(s);
+ file_destroy(a);
}
*str = buf;
@@ -186,12 +186,7 @@
}
f->fd = fd;
- b = apr_bucket_shared_make(b, f, offset, offset + len);
- if (b == NULL) {
- free(f);
- return NULL;
- }
-
+ b = apr_bucket_shared_make(b, f, offset, len);
b->type = &apr_bucket_type_file;
return b;
1.14 +1 -1 apr-util/buckets/apr_buckets_flush.c
Index: apr_buckets_flush.c
===================================================================
RCS file: /home/cvs/apr-util/buckets/apr_buckets_flush.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -u -r1.13 -r1.14
--- apr_buckets_flush.c 2001/02/16 04:17:07 1.13
+++ apr_buckets_flush.c 2001/02/27 20:45:36 1.14
@@ -72,8 +72,8 @@
APU_DECLARE(apr_bucket *) apr_bucket_flush_make(apr_bucket *b)
{
b->length = 0;
+ b->start = 0;
b->data = NULL;
-
b->type = &apr_bucket_type_flush;
return b;
1.28 +3 -12 apr-util/buckets/apr_buckets_heap.c
Index: apr_buckets_heap.c
===================================================================
RCS file: /home/cvs/apr-util/buckets/apr_buckets_heap.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -u -r1.27 -r1.28
--- apr_buckets_heap.c 2001/02/16 04:17:07 1.27
+++ apr_buckets_heap.c 2001/02/27 20:45:36 1.28
@@ -61,11 +61,10 @@
static apr_status_t heap_read(apr_bucket *b, const char **str,
apr_size_t *len, apr_read_type_e block)
{
- apr_bucket_shared *s = b->data;
- apr_bucket_heap *h = s->data;
+ apr_bucket_heap *h = b->data;
- *str = h->base + s->start;
- *len = s->end - s->start;
+ *str = h->base + b->start;
+ *len = b->length;
return APR_SUCCESS;
}
@@ -109,14 +108,6 @@
}
b = apr_bucket_shared_make(b, h, 0, length);
- if (b == NULL) {
- if (copy) {
- free(h->base);
- }
- free(h);
- return NULL;
- }
-
b->type = &apr_bucket_type_heap;
if (w)
1.30 +5 -10 apr-util/buckets/apr_buckets_mmap.c
Index: apr_buckets_mmap.c
===================================================================
RCS file: /home/cvs/apr-util/buckets/apr_buckets_mmap.c,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -d -u -r1.29 -r1.30
--- apr_buckets_mmap.c 2001/02/16 04:17:07 1.29
+++ apr_buckets_mmap.c 2001/02/27 20:45:36 1.30
@@ -61,17 +61,16 @@
static apr_status_t mmap_read(apr_bucket *b, const char **str,
apr_size_t *length, apr_read_type_e block)
{
- apr_bucket_shared *s = b->data;
- apr_bucket_mmap *m = s->data;
+ apr_bucket_mmap *m = b->data;
apr_status_t ok;
void *addr;
- ok = apr_mmap_offset(&addr, m->mmap, s->start);
+ ok = apr_mmap_offset(&addr, m->mmap, b->start);
if (ok != APR_SUCCESS) {
return ok;
}
*str = addr;
- *length = s->end - s->start;
+ *length = b->length;
return APR_SUCCESS;
}
@@ -83,6 +82,7 @@
if (m == NULL) {
return;
}
+ /* XXX: apr_mmap_delete(m->mmap)? */
free(m);
}
@@ -100,12 +100,7 @@
}
m->mmap = mm;
- b = apr_bucket_shared_make(b, m, start, start+length);
- if (b == NULL) {
- free(m);
- return NULL;
- }
-
+ b = apr_bucket_shared_make(b, m, start, length);
b->type = &apr_bucket_type_mmap;
return b;
1.32 +19 -14 apr-util/buckets/apr_buckets_pipe.c
Index: apr_buckets_pipe.c
===================================================================
RCS file: /home/cvs/apr-util/buckets/apr_buckets_pipe.c,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -d -u -r1.31 -r1.32
--- apr_buckets_pipe.c 2001/02/27 19:19:11 1.31
+++ apr_buckets_pipe.c 2001/02/27 20:45:36 1.32
@@ -60,8 +60,6 @@
apr_size_t *len, apr_read_type_e block)
{
apr_file_t *p = a->data;
- apr_bucket_shared *s;
- apr_bucket_heap *h;
char *buf;
apr_status_t rv;
apr_interval_time_t timeout;
@@ -86,15 +84,6 @@
return rv;
}
/*
- * Change the current bucket to refer to what we read,
- * even if we read nothing because we hit EOF.
- */
- apr_bucket_heap_make(a, buf, *len, 0, NULL); /* XXX: check for failure?
*/
- s = a->data;
- h = s->data;
- h->alloc_len = HUGE_STRING_LEN; /* note the real buffer size */
- *str = buf;
- /*
* If there's more to read we have to keep the rest of the pipe
* for later. Otherwise, we'll close the pipe.
* XXX: Note that more complicated bucket types that
@@ -107,11 +96,26 @@
* new bucket.
*/
if (*len > 0) {
+ apr_bucket_heap *h;
+ /* Change the current bucket to refer to what we read */
+ /* XXX: check for failure? */
+ a = apr_bucket_heap_make(a, buf, *len, 0, NULL);
+ h = a->data;
+ h->alloc_len = HUGE_STRING_LEN; /* note the real buffer size */
+ *str = buf;
APR_BUCKET_INSERT_AFTER(a, apr_bucket_pipe_create(p));
}
- else if (rv == APR_EOF) {
- apr_file_close(p);
- return (block == APR_NONBLOCK_READ) ? APR_EOF : APR_SUCCESS;
+ else {
+ free(buf);
+ a = apr_bucket_immortal_make(a, "", 0);
+ *str = a->data;
+ if (rv == APR_EOF) {
+ apr_file_close(p);
+ if (block == APR_NONBLOCK_READ) {
+ /* XXX: this is bogus, should return APR_SUCCESS */
+ return APR_EOF;
+ }
+ }
}
return APR_SUCCESS;
}
@@ -133,6 +137,7 @@
*/
b->type = &apr_bucket_type_pipe;
b->length = -1;
+ b->start = -1;
b->data = p;
return b;
1.13 +17 -23 apr-util/buckets/apr_buckets_pool.c
Index: apr_buckets_pool.c
===================================================================
RCS file: /home/cvs/apr-util/buckets/apr_buckets_pool.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -u -r1.12 -r1.13
--- apr_buckets_pool.c 2001/02/16 04:17:07 1.12
+++ apr_buckets_pool.c 2001/02/27 20:45:36 1.13
@@ -57,37 +57,36 @@
static apr_status_t pool_bucket_cleanup(void *data)
{
- apr_bucket_shared *s = data;
- apr_bucket_shared *new;
- apr_bucket_pool *h = s->data;
+ apr_bucket_pool *h = data;
apr_bucket *b = h->b;
- apr_size_t w;
-
- apr_bucket_heap_make(b, h->base, b->length, 1, &w);
- new = b->data;
-
- new->start = s->start;
- new->end = s->end;
+ apr_off_t start = b->start;
+ apr_off_t length = b->length;
- apr_bucket_shared_destroy(s);
+ b = apr_bucket_heap_make(b, h->base, b->length, 1, NULL);
+ b->start = start;
+ b->length = length;
+ /*
+ * XXX: this is fubar... only the *first* apr_bucket to reference
+ * the bucket is changed to a heap bucket... ALL references must
+ * be changed or at least "notified" in some way. Fix is in the
+ * works. --jcw
+ */
return APR_SUCCESS;
}
static apr_status_t pool_read(apr_bucket *b, const char **str,
apr_size_t *len, apr_read_type_e block)
{
- apr_bucket_shared *s = b->data;
- apr_bucket_pool *h = s->data;
+ apr_bucket_pool *h = b->data;
- *str = h->base + s->start;
- *len = s->end - s->start;
+ *str = h->base + b->start;
+ *len = b->length;
return APR_SUCCESS;
}
static void pool_destroy(void *data)
{
- apr_bucket_shared *s = data;
- apr_bucket_pool *h = s->data;
+ apr_bucket_pool *h = data;
apr_pool_cleanup_kill(h->p, data, pool_bucket_cleanup);
h = apr_bucket_shared_destroy(data);
@@ -114,13 +113,8 @@
h->p = p;
b = apr_bucket_shared_make(b, h, 0, length);
- if (b == NULL) {
- free(h);
- return NULL;
- }
-
b->type = &apr_bucket_type_pool;
- h->b = b;
+ h->b = b; /* XXX: see comment in pool_bucket_cleanup() */
apr_pool_cleanup_register(h->p, b->data, pool_bucket_cleanup,
apr_pool_cleanup_null);
return b;
1.15 +23 -66 apr-util/buckets/apr_buckets_refcount.c
Index: apr_buckets_refcount.c
===================================================================
RCS file: /home/cvs/apr-util/buckets/apr_buckets_refcount.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -u -r1.14 -r1.15
--- apr_buckets_refcount.c 2001/02/16 04:17:07 1.14
+++ apr_buckets_refcount.c 2001/02/27 20:45:36 1.15
@@ -58,96 +58,53 @@
#include "apr_buckets.h"
-APU_DECLARE_NONSTD(apr_status_t) apr_bucket_shared_split(apr_bucket *a,
apr_off_t point)
+APU_DECLARE_NONSTD(apr_status_t) apr_bucket_shared_split(apr_bucket *a,
+ apr_off_t point)
{
- apr_bucket *b;
- apr_bucket_shared *ad, *bd;
+ apr_bucket_refcount *r = a->data;
apr_status_t rv;
- if (point < 0 || point > a->length) {
- return APR_EINVAL;
- }
-
- rv = apr_bucket_shared_copy(a, &b);
- if (rv != APR_SUCCESS) {
+ if ((rv = apr_bucket_simple_split(a, point)) != APR_SUCCESS) {
return rv;
}
-
- ad = a->data;
- bd = b->data;
-
- a->length = point;
- ad->end = ad->start + point;
- b->length -= point;
- bd->start += point;
-
- APR_BUCKET_INSERT_AFTER(a, b);
+ r->refcount++;
return APR_SUCCESS;
}
-APU_DECLARE_NONSTD(apr_status_t) apr_bucket_shared_copy(apr_bucket *a,
apr_bucket **c)
+APU_DECLARE_NONSTD(apr_status_t) apr_bucket_shared_copy(apr_bucket *a,
+ apr_bucket **b)
{
- apr_bucket *b;
- apr_bucket_shared *ad, *bd;
- apr_bucket_refcount *r;
+ apr_bucket_refcount *r = a->data;
+ apr_status_t rv;
- b = malloc(sizeof(*b));
- if (b == NULL) {
- return APR_ENOMEM;
- }
- bd = malloc(sizeof(*bd));
- if (bd == NULL) {
- free(b);
- return APR_ENOMEM;
+ if ((rv = apr_bucket_simple_copy(a, b)) != APR_SUCCESS) {
+ return rv;
}
- *b = *a;
- ad = a->data;
- b->data = bd;
- *bd = *ad;
-
- r = ad->data;
- r->refcount += 1;
-
- *c = b;
+ r->refcount++;
return APR_SUCCESS;
}
+/* XXX: can this just return true or false? */
APU_DECLARE(void *) apr_bucket_shared_destroy(void *data)
{
- apr_bucket_shared *s = data;
- apr_bucket_refcount *r = s->data;
-
- free(s);
- r->refcount -= 1;
- if (r->refcount == 0) {
- return r;
- }
- else {
- return NULL;
- }
+ apr_bucket_refcount *r = data;
+ r->refcount--;
+ return (r->refcount == 0) ? r : NULL;
}
APU_DECLARE(apr_bucket *) apr_bucket_shared_make(apr_bucket *b, void *data,
- apr_off_t start, apr_off_t end)
+ apr_off_t start,
+ apr_off_t length)
{
- apr_bucket_shared *s;
apr_bucket_refcount *r = data;
- s = malloc(sizeof(*s));
- if (s == NULL) {
- return NULL;
- }
-
- b->data = s;
- b->length = end - start;
- /* caller initializes the type field and function pointers */
- s->start = start;
- s->end = end;
- s->data = r;
+ b->data = r;
+ b->start = start;
+ b->length = length;
+ /* caller initializes the type field */
r->refcount = 1;
- /* caller initializes the rest of r */
return b;
}
1.23 +26 -67 apr-util/buckets/apr_buckets_simple.c
Index: apr_buckets_simple.c
===================================================================
RCS file: /home/cvs/apr-util/buckets/apr_buckets_simple.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -u -r1.22 -r1.23
--- apr_buckets_simple.c 2001/02/16 04:17:07 1.22
+++ apr_buckets_simple.c 2001/02/27 20:45:36 1.23
@@ -55,56 +55,35 @@
#include "apr_buckets.h"
#include <stdlib.h>
-/*
- * We can't simplify this function by using an apr_bucket_make function
- * because we aren't sure of the exact type of this bucket.
- */
-static apr_status_t simple_copy(apr_bucket *a, apr_bucket **c)
+APU_DECLARE_NONSTD(apr_status_t) apr_bucket_simple_copy(apr_bucket *a,
+ apr_bucket **b)
{
- apr_bucket *b;
- apr_bucket_simple *ad, *bd;
-
- b = malloc(sizeof(*b));
- if (b == NULL) {
- return APR_ENOMEM;
- }
- bd = malloc(sizeof(*bd));
- if (bd == NULL) {
- free(b);
+ if ((*b = malloc(sizeof(**b))) == NULL) {
return APR_ENOMEM;
}
- *b = *a;
- ad = a->data;
- b->data = bd;
- *bd = *ad;
-
- *c = b;
+ **b = *a;
return APR_SUCCESS;
}
-static apr_status_t simple_split(apr_bucket *a, apr_off_t point)
+APU_DECLARE_NONSTD(apr_status_t) apr_bucket_simple_split(apr_bucket *a,
+ apr_off_t point)
{
apr_bucket *b;
- apr_bucket_simple *ad, *bd;
apr_status_t rv;
if (point < 0 || point > a->length) {
return APR_EINVAL;
}
- rv = simple_copy(a, &b);
+ rv = apr_bucket_simple_copy(a, &b);
if (rv != APR_SUCCESS) {
return rv;
}
-
- ad = a->data;
- bd = b->data;
- a->length = point;
- ad->end = ad->start + point;
+ a->length = point;
b->length -= point;
- bd->start += point;
+ b->start += point;
APR_BUCKET_INSERT_AFTER(a, b);
@@ -114,28 +93,18 @@
static apr_status_t simple_read(apr_bucket *b, const char **str,
apr_size_t *len, apr_read_type_e block)
{
- apr_bucket_simple *bd = b->data;
- *str = bd->start;
- *len = bd->end - bd->start;
+ *str = b->data + b->start;
+ *len = b->length;
return APR_SUCCESS;
}
APU_DECLARE(apr_bucket *) apr_bucket_immortal_make(apr_bucket *b,
const char *buf, apr_size_t length)
{
- apr_bucket_simple *bd;
-
- bd = malloc(sizeof(*bd));
- if (bd == NULL) {
- return NULL;
- }
-
- bd->start = buf;
- bd->end = buf+length;
-
- b->type = &apr_bucket_type_immortal;
- b->length = length;
- b->data = bd;
+ b->data = (char *)buf;
+ b->length = length;
+ b->start = 0;
+ b->type = &apr_bucket_type_immortal;
return b;
}
@@ -157,30 +126,20 @@
*/
static apr_status_t transient_setaside(apr_bucket *b)
{
- apr_bucket_simple *bd;
- const char *start, *end;
- apr_size_t w;
-
- bd = b->data;
- start = bd->start;
- end = bd->end;
- /* XXX: handle small heap buckets */
- b = apr_bucket_heap_make(b, start, end-start, 1, &w);
- if (b == NULL || w != end-start) {
- return APR_ENOMEM;
+ b = apr_bucket_heap_make(b, b->data+b->start, b->length, 1, NULL);
+ if (b == NULL) {
+ return APR_ENOMEM;
}
- free(bd);
return APR_SUCCESS;
}
APU_DECLARE(apr_bucket *) apr_bucket_transient_make(apr_bucket *b,
const char *buf, apr_size_t length)
{
- b = apr_bucket_immortal_make(b, buf, length);
- if (b == NULL) {
- return NULL;
- }
- b->type = &apr_bucket_type_transient;
+ b->data = (char *)buf;
+ b->length = length;
+ b->start = 0;
+ b->type = &apr_bucket_type_transient;
return b;
}
@@ -195,8 +154,8 @@
free,
simple_read,
apr_bucket_setaside_notimpl,
- simple_split,
- simple_copy
+ apr_bucket_simple_split,
+ apr_bucket_simple_copy
};
APU_DECLARE_DATA const apr_bucket_type_t apr_bucket_type_transient = {
@@ -204,6 +163,6 @@
free,
simple_read,
transient_setaside,
- simple_split,
- simple_copy
+ apr_bucket_simple_split,
+ apr_bucket_simple_copy
};
1.21 +16 -13 apr-util/buckets/apr_buckets_socket.c
Index: apr_buckets_socket.c
===================================================================
RCS file: /home/cvs/apr-util/buckets/apr_buckets_socket.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -u -r1.20 -r1.21
--- apr_buckets_socket.c 2001/02/27 19:19:11 1.20
+++ apr_buckets_socket.c 2001/02/27 20:45:36 1.21
@@ -60,8 +60,6 @@
apr_size_t *len, apr_read_type_e block)
{
apr_socket_t *p = a->data;
- apr_bucket_shared *s;
- apr_bucket_heap *h;
char *buf;
apr_status_t rv;
apr_int32_t timeout;
@@ -86,15 +84,6 @@
return rv;
}
/*
- * Change the current bucket to refer to what we read,
- * even if we read nothing because we hit EOF.
- */
- apr_bucket_heap_make(a, buf, *len, 0, NULL); /* XXX: check for failure?
*/
- s = a->data;
- h = s->data;
- h->alloc_len = HUGE_STRING_LEN; /* note the real buffer size */
- *str = buf;
- /*
* If there's more to read we have to keep the rest of the socket
* for later. XXX: Note that more complicated bucket types that
* refer to data not in memory and must therefore have a read()
@@ -110,10 +99,23 @@
* down for reading, but there is no benefit to doing so.
*/
if (*len > 0) {
+ apr_bucket_heap *h;
+ /* Change the current bucket to refer to what we read */
+ /* XXX: check for failure? */
+ a = apr_bucket_heap_make(a, buf, *len, 0, NULL);
+ h = a->data;
+ h->alloc_len = HUGE_STRING_LEN; /* note the real buffer size */
+ *str = buf;
APR_BUCKET_INSERT_AFTER(a, apr_bucket_socket_create(p));
}
- else if (rv == APR_EOF && block == APR_NONBLOCK_READ) {
- return APR_EOF;
+ else {
+ free(buf);
+ a = apr_bucket_immortal_make(a, "", 0);
+ *str = a->data;
+ if (rv == APR_EOF && block == APR_NONBLOCK_READ) {
+ /* XXX: this is bogus... should return APR_SUCCESS */
+ return APR_EOF;
+ }
}
return APR_SUCCESS;
}
@@ -130,6 +132,7 @@
*/
b->type = &apr_bucket_type_socket;
b->length = -1;
+ b->start = -1;
b->data = p;
return b;
1.83 +59 -57 apr-util/include/apr_buckets.h
Index: apr_buckets.h
===================================================================
RCS file: /home/cvs/apr-util/include/apr_buckets.h,v
retrieving revision 1.82
retrieving revision 1.83
diff -u -d -u -r1.82 -r1.83
--- apr_buckets.h 2001/02/26 18:13:05 1.82
+++ apr_buckets.h 2001/02/27 20:45:38 1.83
@@ -229,6 +229,13 @@
* the value of this field will be -1.
*/
apr_off_t length;
+ /** The start of the data in the bucket relative to the private base
+ * pointer. The vast majority of bucket types allow a fixed block of
+ * data to be referenced by multiple buckets, each bucket pointing to
+ * a different segment of the data. That segment starts at base+start
+ * and ends at base+start+length. If length == -1, start == -1.
+ */
+ apr_off_t start;
/** type-dependent data hangs off this pointer */
void *data;
};
@@ -489,39 +496,8 @@
int refcount;
};
-typedef struct apr_bucket_shared apr_bucket_shared;
-/**
- * The data pointer of a refcounted bucket points to an
- * apr_bucket_shared structure which describes the region of the shared
- * object that this bucket refers to. The apr_bucket_shared isn't a
- * fully-fledged bucket type: it is a utility type that proper bucket
- * types are based on.
- */
-struct apr_bucket_shared {
- /** start of the data in the bucket relative to the private base pointer
*/
- apr_off_t start;
- /** end of the data in the bucket relative to the private base pointer */
- apr_off_t end;
- /** pointer to the real private data of the bucket,
- * which starts with an apr_bucket_refcount */
- void *data;
-};
-
-/* ***** Non-reference-counted bucket types ***** */
-
+/* ***** Reference-counted bucket types ***** */
-typedef struct apr_bucket_simple apr_bucket_simple;
-/**
- * TRANSIENT and IMMORTAL buckets don't have much to do with looking
- * after the memory that they refer to so they share a lot of their
- * implementation.
- */
-struct apr_bucket_simple {
- /** The start of the data in the bucket */
- const char *start;
- /** The end of the data in the bucket */
- const char *end;
-};
typedef struct apr_bucket_pool apr_bucket_pool;
/**
@@ -545,9 +521,6 @@
apr_bucket *b;
};
-/* ***** Reference-counted bucket types ***** */
-
-
typedef struct apr_bucket_heap apr_bucket_heap;
/**
* A bucket referring to data allocated off the heap.
@@ -858,7 +831,7 @@
* A place holder function that signifies that the destroy function was not
* implemented for this bucket
* @param data The bucket to destroy
- * @deffunc void apr_bucket_destroy(apr_bucket *data)
+ * @deffunc void apr_bucket_destroy_notimpl(void *data)
*/
APU_DECLARE_NONSTD(void) apr_bucket_destroy_notimpl(void *data);
@@ -926,38 +899,67 @@
*/
APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_socket;
-/* ***** Shared reference-counted buckets ***** */
+
+/* ***** Simple buckets ***** */
+
+/**
+ * Split a simple bucket into two at the given point. Most non-reference
+ * counting buckets that allow multiple references to the same block of
+ * data (eg transient and immortal) will use this as their split function
+ * without any additional type-specific handling.
+ * @param b The bucket to be split
+ * @param point The offset of the first byte in the new bucket
+ * @return APR_EINVAL if the point is not within the bucket;
+ * APR_ENOMEM if allocation failed;
+ * or APR_SUCCESS
+ * @deffunc apr_status_t apr_bucket_simple_split(apr_bucket *b, apr_off_t
point)
+ */
+APU_DECLARE_NONSTD(apr_status_t) apr_bucket_simple_split(apr_bucket *b,
+ apr_off_t point);
/**
+ * Copy a simple bucket. Most non-reference-counting buckets that allow
+ * multiple references to the same block of data (eg transient and immortal)
+ * will use this as their copy function without any additional type-specific
+ * handling.
+ * @param a The bucket to copy
+ * @param b Returns a pointer to the new bucket
+ * @return APR_ENOMEM if allocation failed;
+ * or APR_SUCCESS
+ * @deffunc apr_status_t apr_bucket_simple_copy(apr_bucket *a, apr_bucket
**b)
+ */
+APU_DECLARE_NONSTD(apr_status_t) apr_bucket_simple_copy(apr_bucket *a,
+ apr_bucket **b);
+
+
+/* ***** Shared, reference-counted buckets ***** */
+
+/**
* Initialize a bucket containing reference-counted data that may be
* shared. The caller must allocate the bucket if necessary and
* initialize its type-dependent fields, and allocate and initialize
* its own private data structure. This function should only be called
* by type-specific bucket creation functions.
- * @param b The bucket to initialize,
- * or NULL if a new one should be allocated
+ * @param b The bucket to initialize
* @param data A pointer to the private data structure
* with the reference count at the start
* @param start The start of the data in the bucket
* relative to the private base pointer
- * @param end The end of the data in the bucket
- * relative to the private base pointer
+ * @param length The length of the data in the bucket
* @return The new bucket, or NULL if allocation failed
- * @deffunc apr_bucket *apr_bucket_shared_make(apr_bucket_refcount *r,
apr_off_t start, apr_off_t end)
+ * @deffunc apr_bucket *apr_bucket_shared_make(apr_bucket_refcount *r,
apr_off_t start, apr_off_t length)
*/
-APU_DECLARE(apr_bucket *)
- apr_bucket_shared_make(apr_bucket *b, void *data,
- apr_off_t start, apr_off_t end);
+APU_DECLARE(apr_bucket *) apr_bucket_shared_make(apr_bucket *b, void *data,
+ apr_off_t start, apr_off_t length);
/**
- * Decrement the refcount of the data in the bucket and free the
- * apr_bucket_shared structure. This function should only be called by
- * type-specific bucket destruction functions.
+ * Decrement the refcount of the data in the bucket. This function
+ * should only be called by type-specific bucket destruction functions.
* @param data The private data pointer from the bucket to be destroyed
* @return NULL if nothing needs to be done,
* otherwise a pointer to the private data structure which
* must be destroyed because its reference count is zero
- * @deffunc void *apr_bucket_shared_destroy(apr_bucket *b)
+ * @deffunc void *apr_bucket_shared_destroy(void *data)
*/
APU_DECLARE(void *) apr_bucket_shared_destroy(void *data);
@@ -973,24 +975,24 @@
* or APR_SUCCESS
* @deffunc apr_status_t apr_bucket_shared_split(apr_bucket *b, apr_off_t
point)
*/
-APU_DECLARE_NONSTD(apr_status_t)
- apr_bucket_shared_split(apr_bucket *b, apr_off_t
point);
+APU_DECLARE_NONSTD(apr_status_t) apr_bucket_shared_split(apr_bucket *b,
+ apr_off_t point);
/**
* Copy a refcounted bucket, incrementing the reference count. Most
* reference-counting bucket types will be able to use this function
* as their copy function without any additional type-specific handling.
* @param a The bucket to copy
- * @param c Returns a pointer to the new bucket
+ * @param b Returns a pointer to the new bucket
* @return APR_ENOMEM if allocation failed;
or APR_SUCCESS
- * @deffunc apr_status_t apr_bucket_shared_copy(apr_bucket *a, apr_bucket
**c)
+ * @deffunc apr_status_t apr_bucket_shared_copy(apr_bucket *a, apr_bucket
**b)
*/
-APU_DECLARE_NONSTD(apr_status_t)
- apr_bucket_shared_copy(apr_bucket *a, apr_bucket **c);
+APU_DECLARE_NONSTD(apr_status_t) apr_bucket_shared_copy(apr_bucket *a,
+ apr_bucket **b);
-/* ***** Functions to Create Buckets of varying type ***** */
+/* ***** Functions to Create Buckets of varying types ***** */
/*
* Each bucket type foo has two initialization functions:
* apr_bucket_make_foo which sets up some already-allocated memory as a
@@ -1017,7 +1019,7 @@
free(b); \
return NULL; \
} \
- APR_RING_ELEM_INIT(ap__b, link); \
+ APR_RING_ELEM_INIT(ap__b, link); \
return ap__b; \
} while(0)