00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00059 #ifndef APR_BUCKETS_H
00060 #define APR_BUCKETS_H
00061
00062 #if defined(APR_BUCKET_DEBUG) && !defined(APR_RING_DEBUG)
00063 #define APR_RING_DEBUG
00064 #endif
00065
00066 #include "apu.h"
00067 #include "apr_network_io.h"
00068 #include "apr_file_io.h"
00069 #include "apr_general.h"
00070 #include "apr_mmap.h"
00071 #include "apr_errno.h"
00072 #include "apr_ring.h"
00073 #include "apr.h"
00074 #if APR_HAVE_SYS_UIO_H
00075 #include <sys/uio.h>
00076 #endif
00077 #if APR_HAVE_STDARG_H
00078 #include <stdarg.h>
00079 #endif
00080
00081 #ifdef __cplusplus
00082 extern "C" {
00083 #endif
00084
00092 #define APR_BUCKET_BUFF_SIZE 8000
00093
00095 typedef enum {
00096 APR_BLOCK_READ,
00097 APR_NONBLOCK_READ
00098 } apr_read_type_e;
00099
00152
00153
00154
00155
00157 typedef struct apr_bucket_brigade apr_bucket_brigade;
00159 typedef struct apr_bucket apr_bucket;
00161 typedef struct apr_bucket_alloc_t apr_bucket_alloc_t;
00162
00164 typedef struct apr_bucket_type_t apr_bucket_type_t;
00165
00169 struct apr_bucket_type_t {
00173 const char *name;
00178 int num_func;
00189 enum {
00191 APR_BUCKET_DATA = 0,
00193 APR_BUCKET_METADATA = 1
00194 } is_metadata;
00202 void (*destroy)(void *data);
00203
00214 apr_status_t (*read)(apr_bucket *b, const char **str, apr_size_t *len,
00215 apr_read_type_e block);
00216
00230 apr_status_t (*setaside)(apr_bucket *e, apr_pool_t *pool);
00231
00241 apr_status_t (*split)(apr_bucket *e, apr_size_t point);
00242
00249 apr_status_t (*copy)(apr_bucket *e, apr_bucket **c);
00250
00251 };
00252
00262 struct apr_bucket {
00264 APR_RING_ENTRY(apr_bucket) link;
00266 const apr_bucket_type_t *type;
00272 apr_size_t length;
00280 apr_off_t start;
00282 void *data;
00290 void (*free)(void *e);
00292 apr_bucket_alloc_t *list;
00293 };
00294
00296 struct apr_bucket_brigade {
00302 apr_pool_t *p;
00304
00305
00306
00307
00308
00309
00310
00311 APR_RING_HEAD(apr_bucket_list, apr_bucket) list;
00313 apr_bucket_alloc_t *bucket_alloc;
00314 };
00315
00316
00320 typedef apr_status_t (*apr_brigade_flush)(apr_bucket_brigade *bb, void *ctx);
00321
00322
00323
00324
00325
00326
00327 #ifdef APR_BUCKET_DEBUG
00328
00329 #define APR_BRIGADE_CHECK_CONSISTENCY(b) \
00330 APR_RING_CHECK_CONSISTENCY(&(b)->list, apr_bucket, link)
00331
00332 #define APR_BUCKET_CHECK_CONSISTENCY(e) \
00333 APR_RING_CHECK_ELEM_CONSISTENCY((e), apr_bucket, link)
00334
00335 #else
00342 #define APR_BRIGADE_CHECK_CONSISTENCY(b)
00349 #define APR_BUCKET_CHECK_CONSISTENCY(e)
00350 #endif
00351
00352
00369 #define APR_BRIGADE_SENTINEL(b) APR_RING_SENTINEL(&(b)->list, apr_bucket, link)
00370
00376 #define APR_BRIGADE_EMPTY(b) APR_RING_EMPTY(&(b)->list, apr_bucket, link)
00377
00383 #define APR_BRIGADE_FIRST(b) APR_RING_FIRST(&(b)->list)
00389 #define APR_BRIGADE_LAST(b) APR_RING_LAST(&(b)->list)
00390
00432 #define APR_BRIGADE_FOREACH(e, b) \
00433 APR_RING_FOREACH((e), &(b)->list, apr_bucket, link)
00434
00440 #define APR_BRIGADE_INSERT_HEAD(b, e) do { \
00441 apr_bucket *ap__b = (e); \
00442 APR_RING_INSERT_HEAD(&(b)->list, ap__b, apr_bucket, link); \
00443 APR_BRIGADE_CHECK_CONSISTENCY((b)); \
00444 } while (0)
00445
00451 #define APR_BRIGADE_INSERT_TAIL(b, e) do { \
00452 apr_bucket *ap__b = (e); \
00453 APR_RING_INSERT_TAIL(&(b)->list, ap__b, apr_bucket, link); \
00454 APR_BRIGADE_CHECK_CONSISTENCY((b)); \
00455 } while (0)
00456
00462 #define APR_BRIGADE_CONCAT(a, b) do { \
00463 APR_RING_CONCAT(&(a)->list, &(b)->list, apr_bucket, link); \
00464 APR_BRIGADE_CHECK_CONSISTENCY((a)); \
00465 } while (0)
00466
00472 #define APR_BRIGADE_PREPEND(a, b) do { \
00473 APR_RING_PREPEND(&(a)->list, &(b)->list, apr_bucket, link); \
00474 APR_BRIGADE_CHECK_CONSISTENCY((a)); \
00475 } while (0)
00476
00482 #define APR_BUCKET_INSERT_BEFORE(a, b) do { \
00483 apr_bucket *ap__a = (a), *ap__b = (b); \
00484 APR_RING_INSERT_BEFORE(ap__a, ap__b, link); \
00485 APR_BUCKET_CHECK_CONSISTENCY(ap__a); \
00486 } while (0)
00487
00493 #define APR_BUCKET_INSERT_AFTER(a, b) do { \
00494 apr_bucket *ap__a = (a), *ap__b = (b); \
00495 APR_RING_INSERT_AFTER(ap__a, ap__b, link); \
00496 APR_BUCKET_CHECK_CONSISTENCY(ap__a); \
00497 } while (0)
00498
00504 #define APR_BUCKET_NEXT(e) APR_RING_NEXT((e), link)
00505
00510 #define APR_BUCKET_PREV(e) APR_RING_PREV((e), link)
00511
00516 #define APR_BUCKET_REMOVE(e) APR_RING_REMOVE((e), link)
00517
00522 #define APR_BUCKET_INIT(e) APR_RING_ELEM_INIT((e), link)
00523
00530 #define APR_BUCKET_IS_METADATA(e) ((e)->type->is_metadata)
00531
00537 #define APR_BUCKET_IS_FLUSH(e) ((e)->type == &apr_bucket_type_flush)
00538
00543 #define APR_BUCKET_IS_EOS(e) ((e)->type == &apr_bucket_type_eos)
00544
00549 #define APR_BUCKET_IS_FILE(e) ((e)->type == &apr_bucket_type_file)
00550
00555 #define APR_BUCKET_IS_PIPE(e) ((e)->type == &apr_bucket_type_pipe)
00556
00561 #define APR_BUCKET_IS_SOCKET(e) ((e)->type == &apr_bucket_type_socket)
00562
00567 #define APR_BUCKET_IS_HEAP(e) ((e)->type == &apr_bucket_type_heap)
00568
00573 #define APR_BUCKET_IS_TRANSIENT(e) ((e)->type == &apr_bucket_type_transient)
00574
00579 #define APR_BUCKET_IS_IMMORTAL(e) ((e)->type == &apr_bucket_type_immortal)
00580 #if APR_HAS_MMAP
00581
00586 #define APR_BUCKET_IS_MMAP(e) ((e)->type == &apr_bucket_type_mmap)
00587 #endif
00588
00593 #define APR_BUCKET_IS_POOL(e) ((e)->type == &apr_bucket_type_pool)
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00606 typedef struct apr_bucket_refcount apr_bucket_refcount;
00613 struct apr_bucket_refcount {
00615 int refcount;
00616 };
00617
00618
00619
00621 typedef struct apr_bucket_heap apr_bucket_heap;
00625 struct apr_bucket_heap {
00627 apr_bucket_refcount refcount;
00631 char *base;
00633 apr_size_t alloc_len;
00635 void (*free_func)(void *data);
00636 };
00637
00639 typedef struct apr_bucket_pool apr_bucket_pool;
00643 struct apr_bucket_pool {
00655 apr_bucket_heap heap;
00661 const char *base;
00668 apr_pool_t *pool;
00672 apr_bucket_alloc_t *list;
00673 };
00674
00675 #if APR_HAS_MMAP
00676
00677 typedef struct apr_bucket_mmap apr_bucket_mmap;
00681 struct apr_bucket_mmap {
00683 apr_bucket_refcount refcount;
00685 apr_mmap_t *mmap;
00686 };
00687 #endif
00688
00690 typedef struct apr_bucket_file apr_bucket_file;
00694 struct apr_bucket_file {
00696 apr_bucket_refcount refcount;
00698 apr_file_t *fd;
00701 apr_pool_t *readpool;
00702 #if APR_HAS_MMAP
00703
00705 int can_mmap;
00706 #endif
00707 };
00708
00710 typedef union apr_bucket_structs apr_bucket_structs;
00715 union apr_bucket_structs {
00716 apr_bucket b;
00717 apr_bucket_heap heap;
00718 apr_bucket_pool pool;
00719 #if APR_HAS_MMAP
00720 apr_bucket_mmap mmap;
00721 #endif
00722 apr_bucket_file file;
00723 };
00724
00730 #define APR_BUCKET_ALLOC_SIZE APR_ALIGN_DEFAULT(2*sizeof(apr_bucket_structs))
00731
00732
00740 APU_DECLARE(apr_bucket_brigade *) apr_brigade_create(apr_pool_t *p,
00741 apr_bucket_alloc_t *list);
00742
00748 APU_DECLARE(apr_status_t) apr_brigade_destroy(apr_bucket_brigade *b);
00749
00761 APU_DECLARE(apr_status_t) apr_brigade_cleanup(void *data);
00762
00772 APU_DECLARE(apr_bucket_brigade *) apr_brigade_split(apr_bucket_brigade *b,
00773 apr_bucket *e);
00774
00783 APU_DECLARE(apr_status_t) apr_brigade_partition(apr_bucket_brigade *b,
00784 apr_off_t point,
00785 apr_bucket **after_point);
00786
00787 #if APR_NOT_DONE_YET
00794 APU_DECLARE(void) apr_brigade_consume(apr_bucket_brigade *b,
00795 apr_off_t nbytes);
00796 #endif
00797
00805 APU_DECLARE(apr_status_t) apr_brigade_length(apr_bucket_brigade *bb,
00806 int read_all,
00807 apr_off_t *length);
00808
00816 APU_DECLARE(apr_status_t) apr_brigade_flatten(apr_bucket_brigade *bb,
00817 char *c,
00818 apr_size_t *len);
00819
00827 APU_DECLARE(apr_status_t) apr_brigade_pflatten(apr_bucket_brigade *bb,
00828 char **c,
00829 apr_size_t *len,
00830 apr_pool_t *pool);
00831
00840 APU_DECLARE(apr_status_t) apr_brigade_split_line(apr_bucket_brigade *bbOut,
00841 apr_bucket_brigade *bbIn,
00842 apr_read_type_e block,
00843 apr_off_t maxbytes);
00844
00854 APU_DECLARE(apr_status_t) apr_brigade_to_iovec(apr_bucket_brigade *b,
00855 struct iovec *vec, int *nvec);
00856
00865 APU_DECLARE(apr_status_t) apr_brigade_vputstrs(apr_bucket_brigade *b,
00866 apr_brigade_flush flush,
00867 void *ctx,
00868 va_list va);
00869
00879 APU_DECLARE(apr_status_t) apr_brigade_write(apr_bucket_brigade *b,
00880 apr_brigade_flush flush, void *ctx,
00881 const char *str, apr_size_t nbyte);
00882
00892 APU_DECLARE(apr_status_t) apr_brigade_writev(apr_bucket_brigade *b,
00893 apr_brigade_flush flush,
00894 void *ctx,
00895 const struct iovec *vec,
00896 apr_size_t nvec);
00897
00906 APU_DECLARE(apr_status_t) apr_brigade_puts(apr_bucket_brigade *bb,
00907 apr_brigade_flush flush, void *ctx,
00908 const char *str);
00909
00918 APU_DECLARE(apr_status_t) apr_brigade_putc(apr_bucket_brigade *b,
00919 apr_brigade_flush flush, void *ctx,
00920 const char c);
00921
00930 APU_DECLARE_NONSTD(apr_status_t) apr_brigade_putstrs(apr_bucket_brigade *b,
00931 apr_brigade_flush flush,
00932 void *ctx, ...);
00933
00944 APU_DECLARE_NONSTD(apr_status_t) apr_brigade_printf(apr_bucket_brigade *b,
00945 apr_brigade_flush flush,
00946 void *ctx,
00947 const char *fmt, ...)
00948 __attribute__((format(printf,4,5)));
00949
00960 APU_DECLARE(apr_status_t) apr_brigade_vprintf(apr_bucket_brigade *b,
00961 apr_brigade_flush flush,
00962 void *ctx,
00963 const char *fmt, va_list va);
00964
00965
00979 APU_DECLARE_NONSTD(apr_bucket_alloc_t *) apr_bucket_alloc_create(apr_pool_t *p);
00980
00989 APU_DECLARE_NONSTD(apr_bucket_alloc_t *) apr_bucket_alloc_create_ex(apr_allocator_t *allocator);
00990
00995 APU_DECLARE_NONSTD(void) apr_bucket_alloc_destroy(apr_bucket_alloc_t *list);
00996
01002 APU_DECLARE_NONSTD(void *) apr_bucket_alloc(apr_size_t size, apr_bucket_alloc_t *list);
01003
01008 APU_DECLARE_NONSTD(void) apr_bucket_free(void *block);
01009
01010
01011
01018 #define apr_bucket_destroy(e) do { \
01019 (e)->type->destroy((e)->data); \
01020 (e)->free(e); \
01021 } while (0)
01022
01034 #define apr_bucket_delete(e) do { \
01035 APR_BUCKET_REMOVE(e); \
01036 apr_bucket_destroy(e); \
01037 } while (0)
01038
01046 #define apr_bucket_read(e,str,len,block) (e)->type->read(e, str, len, block)
01047
01054 #define apr_bucket_setaside(e,p) (e)->type->setaside(e,p)
01055
01061 #define apr_bucket_split(e,point) (e)->type->split(e, point)
01062
01068 #define apr_bucket_copy(e,c) (e)->type->copy(e, c)
01069
01070
01071
01081 APU_DECLARE_NONSTD(apr_status_t) apr_bucket_setaside_noop(apr_bucket *data,
01082 apr_pool_t *pool);
01083
01091 APU_DECLARE_NONSTD(apr_status_t) apr_bucket_setaside_notimpl(apr_bucket *data,
01092 apr_pool_t *pool);
01093
01101 APU_DECLARE_NONSTD(apr_status_t) apr_bucket_split_notimpl(apr_bucket *data,
01102 apr_size_t point);
01103
01111 APU_DECLARE_NONSTD(apr_status_t) apr_bucket_copy_notimpl(apr_bucket *e,
01112 apr_bucket **c);
01113
01123 APU_DECLARE_NONSTD(void) apr_bucket_destroy_noop(void *data);
01124
01131
01132
01133
01134
01135
01140 APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_flush;
01146 APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_eos;
01150 APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_file;
01155 APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_heap;
01156 #if APR_HAS_MMAP
01160 APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_mmap;
01161 #endif
01167 APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_pool;
01171 APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_pipe;
01177 APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_immortal;
01183 APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_transient;
01187 APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_socket;
01188
01189
01190
01191
01203 APU_DECLARE_NONSTD(apr_status_t) apr_bucket_simple_split(apr_bucket *b,
01204 apr_size_t point);
01205
01216 APU_DECLARE_NONSTD(apr_status_t) apr_bucket_simple_copy(apr_bucket *a,
01217 apr_bucket **b);
01218
01219
01220
01221
01236 APU_DECLARE(apr_bucket *) apr_bucket_shared_make(apr_bucket *b, void *data,
01237 apr_off_t start,
01238 apr_size_t length);
01239
01248 APU_DECLARE(int) apr_bucket_shared_destroy(void *data);
01249
01261 APU_DECLARE_NONSTD(apr_status_t) apr_bucket_shared_split(apr_bucket *b,
01262 apr_size_t point);
01263
01273 APU_DECLARE_NONSTD(apr_status_t) apr_bucket_shared_copy(apr_bucket *a,
01274 apr_bucket **b);
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01295 APU_DECLARE(apr_bucket *) apr_bucket_eos_create(apr_bucket_alloc_t *list);
01296
01304 APU_DECLARE(apr_bucket *) apr_bucket_eos_make(apr_bucket *b);
01305
01313 APU_DECLARE(apr_bucket *) apr_bucket_flush_create(apr_bucket_alloc_t *list);
01314
01322 APU_DECLARE(apr_bucket *) apr_bucket_flush_make(apr_bucket *b);
01323
01331 APU_DECLARE(apr_bucket *) apr_bucket_immortal_create(const char *buf,
01332 apr_size_t nbyte,
01333 apr_bucket_alloc_t *list);
01334
01342 APU_DECLARE(apr_bucket *) apr_bucket_immortal_make(apr_bucket *b,
01343 const char *buf,
01344 apr_size_t nbyte);
01345
01353 APU_DECLARE(apr_bucket *) apr_bucket_transient_create(const char *buf,
01354 apr_size_t nbyte,
01355 apr_bucket_alloc_t *list);
01356
01364 APU_DECLARE(apr_bucket *) apr_bucket_transient_make(apr_bucket *b,
01365 const char *buf,
01366 apr_size_t nbyte);
01367
01382 APU_DECLARE(apr_bucket *) apr_bucket_heap_create(const char *buf,
01383 apr_size_t nbyte,
01384 void (*free_func)(void *data),
01385 apr_bucket_alloc_t *list);
01395 APU_DECLARE(apr_bucket *) apr_bucket_heap_make(apr_bucket *b, const char *buf,
01396 apr_size_t nbyte,
01397 void (*free_func)(void *data));
01398
01408 APU_DECLARE(apr_bucket *) apr_bucket_pool_create(const char *buf,
01409 apr_size_t length,
01410 apr_pool_t *pool,
01411 apr_bucket_alloc_t *list);
01412
01421 APU_DECLARE(apr_bucket *) apr_bucket_pool_make(apr_bucket *b, const char *buf,
01422 apr_size_t length,
01423 apr_pool_t *pool);
01424
01425 #if APR_HAS_MMAP
01435 APU_DECLARE(apr_bucket *) apr_bucket_mmap_create(apr_mmap_t *mm,
01436 apr_off_t start,
01437 apr_size_t length,
01438 apr_bucket_alloc_t *list);
01439
01449 APU_DECLARE(apr_bucket *) apr_bucket_mmap_make(apr_bucket *b, apr_mmap_t *mm,
01450 apr_off_t start,
01451 apr_size_t length);
01452 #endif
01453
01460 APU_DECLARE(apr_bucket *) apr_bucket_socket_create(apr_socket_t *thissock,
01461 apr_bucket_alloc_t *list);
01468 APU_DECLARE(apr_bucket *) apr_bucket_socket_make(apr_bucket *b,
01469 apr_socket_t *thissock);
01470
01477 APU_DECLARE(apr_bucket *) apr_bucket_pipe_create(apr_file_t *thispipe,
01478 apr_bucket_alloc_t *list);
01479
01486 APU_DECLARE(apr_bucket *) apr_bucket_pipe_make(apr_bucket *b,
01487 apr_file_t *thispipe);
01488
01499 APU_DECLARE(apr_bucket *) apr_bucket_file_create(apr_file_t *fd,
01500 apr_off_t offset,
01501 apr_size_t len,
01502 apr_pool_t *p,
01503 apr_bucket_alloc_t *list);
01504
01515 APU_DECLARE(apr_bucket *) apr_bucket_file_make(apr_bucket *b, apr_file_t *fd,
01516 apr_off_t offset,
01517 apr_size_t len, apr_pool_t *p);
01518
01525 APU_DECLARE(apr_status_t) apr_bucket_file_enable_mmap(apr_bucket *b,
01526 int enabled);
01527
01529 #ifdef __cplusplus
01530 }
01531 #endif
01532
01533 #endif