00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00020 #ifndef APR_BUCKETS_H
00021 #define APR_BUCKETS_H
00022
00023 #if defined(APR_BUCKET_DEBUG) && !defined(APR_RING_DEBUG)
00024 #define APR_RING_DEBUG
00025 #endif
00026
00027 #include "apu.h"
00028 #include "apr_network_io.h"
00029 #include "apr_file_io.h"
00030 #include "apr_general.h"
00031 #include "apr_mmap.h"
00032 #include "apr_errno.h"
00033 #include "apr_ring.h"
00034 #include "apr.h"
00035 #if APR_HAVE_SYS_UIO_H
00036 #include <sys/uio.h>
00037 #endif
00038 #if APR_HAVE_STDARG_H
00039 #include <stdarg.h>
00040 #endif
00041
00042 #ifdef __cplusplus
00043 extern "C" {
00044 #endif
00045
00053 #define APR_BUCKET_BUFF_SIZE 8000
00054
00056 typedef enum {
00057 APR_BLOCK_READ,
00058 APR_NONBLOCK_READ
00059 } apr_read_type_e;
00060
00113
00114
00115
00116
00118 typedef struct apr_bucket_brigade apr_bucket_brigade;
00120 typedef struct apr_bucket apr_bucket;
00122 typedef struct apr_bucket_alloc_t apr_bucket_alloc_t;
00123
00125 typedef struct apr_bucket_type_t apr_bucket_type_t;
00126
00130 struct apr_bucket_type_t {
00134 const char *name;
00139 int num_func;
00150 enum {
00152 APR_BUCKET_DATA = 0,
00154 APR_BUCKET_METADATA = 1
00155 } is_metadata;
00163 void (*destroy)(void *data);
00164
00175 apr_status_t (*read)(apr_bucket *b, const char **str, apr_size_t *len,
00176 apr_read_type_e block);
00177
00191 apr_status_t (*setaside)(apr_bucket *e, apr_pool_t *pool);
00192
00202 apr_status_t (*split)(apr_bucket *e, apr_size_t point);
00203
00210 apr_status_t (*copy)(apr_bucket *e, apr_bucket **c);
00211
00212 };
00213
00223 struct apr_bucket {
00225 APR_RING_ENTRY(apr_bucket) link;
00227 const apr_bucket_type_t *type;
00233 apr_size_t length;
00241 apr_off_t start;
00243 void *data;
00251 void (*free)(void *e);
00253 apr_bucket_alloc_t *list;
00254 };
00255
00257 struct apr_bucket_brigade {
00263 apr_pool_t *p;
00265
00266
00267
00268
00269
00270
00271
00272 APR_RING_HEAD(apr_bucket_list, apr_bucket) list;
00274 apr_bucket_alloc_t *bucket_alloc;
00275 };
00276
00277
00281 typedef apr_status_t (*apr_brigade_flush)(apr_bucket_brigade *bb, void *ctx);
00282
00283
00284
00285
00286
00287
00288 #ifdef APR_BUCKET_DEBUG
00289
00290 #define APR_BRIGADE_CHECK_CONSISTENCY(b) \
00291 APR_RING_CHECK_CONSISTENCY(&(b)->list, apr_bucket, link)
00292
00293 #define APR_BUCKET_CHECK_CONSISTENCY(e) \
00294 APR_RING_CHECK_ELEM_CONSISTENCY((e), apr_bucket, link)
00295
00296 #else
00297
00303 #define APR_BRIGADE_CHECK_CONSISTENCY(b)
00304
00310 #define APR_BUCKET_CHECK_CONSISTENCY(e)
00311 #endif
00312
00313
00330 #define APR_BRIGADE_SENTINEL(b) APR_RING_SENTINEL(&(b)->list, apr_bucket, link)
00331
00337 #define APR_BRIGADE_EMPTY(b) APR_RING_EMPTY(&(b)->list, apr_bucket, link)
00338
00344 #define APR_BRIGADE_FIRST(b) APR_RING_FIRST(&(b)->list)
00345
00350 #define APR_BRIGADE_LAST(b) APR_RING_LAST(&(b)->list)
00351
00393 #define APR_BRIGADE_FOREACH(e, b) \
00394 APR_RING_FOREACH((e), &(b)->list, apr_bucket, link)
00395
00401 #define APR_BRIGADE_INSERT_HEAD(b, e) do { \
00402 apr_bucket *ap__b = (e); \
00403 APR_RING_INSERT_HEAD(&(b)->list, ap__b, apr_bucket, link); \
00404 APR_BRIGADE_CHECK_CONSISTENCY((b)); \
00405 } while (0)
00406
00412 #define APR_BRIGADE_INSERT_TAIL(b, e) do { \
00413 apr_bucket *ap__b = (e); \
00414 APR_RING_INSERT_TAIL(&(b)->list, ap__b, apr_bucket, link); \
00415 APR_BRIGADE_CHECK_CONSISTENCY((b)); \
00416 } while (0)
00417
00423 #define APR_BRIGADE_CONCAT(a, b) do { \
00424 APR_RING_CONCAT(&(a)->list, &(b)->list, apr_bucket, link); \
00425 APR_BRIGADE_CHECK_CONSISTENCY((a)); \
00426 } while (0)
00427
00433 #define APR_BRIGADE_PREPEND(a, b) do { \
00434 APR_RING_PREPEND(&(a)->list, &(b)->list, apr_bucket, link); \
00435 APR_BRIGADE_CHECK_CONSISTENCY((a)); \
00436 } while (0)
00437
00443 #define APR_BUCKET_INSERT_BEFORE(a, b) do { \
00444 apr_bucket *ap__a = (a), *ap__b = (b); \
00445 APR_RING_INSERT_BEFORE(ap__a, ap__b, link); \
00446 APR_BUCKET_CHECK_CONSISTENCY(ap__a); \
00447 } while (0)
00448
00454 #define APR_BUCKET_INSERT_AFTER(a, b) do { \
00455 apr_bucket *ap__a = (a), *ap__b = (b); \
00456 APR_RING_INSERT_AFTER(ap__a, ap__b, link); \
00457 APR_BUCKET_CHECK_CONSISTENCY(ap__a); \
00458 } while (0)
00459
00465 #define APR_BUCKET_NEXT(e) APR_RING_NEXT((e), link)
00466
00471 #define APR_BUCKET_PREV(e) APR_RING_PREV((e), link)
00472
00477 #define APR_BUCKET_REMOVE(e) APR_RING_REMOVE((e), link)
00478
00483 #define APR_BUCKET_INIT(e) APR_RING_ELEM_INIT((e), link)
00484
00491 #define APR_BUCKET_IS_METADATA(e) ((e)->type->is_metadata)
00492
00498 #define APR_BUCKET_IS_FLUSH(e) ((e)->type == &apr_bucket_type_flush)
00499
00504 #define APR_BUCKET_IS_EOS(e) ((e)->type == &apr_bucket_type_eos)
00505
00510 #define APR_BUCKET_IS_FILE(e) ((e)->type == &apr_bucket_type_file)
00511
00516 #define APR_BUCKET_IS_PIPE(e) ((e)->type == &apr_bucket_type_pipe)
00517
00522 #define APR_BUCKET_IS_SOCKET(e) ((e)->type == &apr_bucket_type_socket)
00523
00528 #define APR_BUCKET_IS_HEAP(e) ((e)->type == &apr_bucket_type_heap)
00529
00534 #define APR_BUCKET_IS_TRANSIENT(e) ((e)->type == &apr_bucket_type_transient)
00535
00540 #define APR_BUCKET_IS_IMMORTAL(e) ((e)->type == &apr_bucket_type_immortal)
00541 #if APR_HAS_MMAP
00542
00547 #define APR_BUCKET_IS_MMAP(e) ((e)->type == &apr_bucket_type_mmap)
00548 #endif
00549
00554 #define APR_BUCKET_IS_POOL(e) ((e)->type == &apr_bucket_type_pool)
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00567 typedef struct apr_bucket_refcount apr_bucket_refcount;
00574 struct apr_bucket_refcount {
00576 int refcount;
00577 };
00578
00579
00580
00582 typedef struct apr_bucket_heap apr_bucket_heap;
00586 struct apr_bucket_heap {
00588 apr_bucket_refcount refcount;
00592 char *base;
00594 apr_size_t alloc_len;
00596 void (*free_func)(void *data);
00597 };
00598
00600 typedef struct apr_bucket_pool apr_bucket_pool;
00604 struct apr_bucket_pool {
00616 apr_bucket_heap heap;
00622 const char *base;
00629 apr_pool_t *pool;
00633 apr_bucket_alloc_t *list;
00634 };
00635
00636 #if APR_HAS_MMAP
00637
00638 typedef struct apr_bucket_mmap apr_bucket_mmap;
00642 struct apr_bucket_mmap {
00644 apr_bucket_refcount refcount;
00646 apr_mmap_t *mmap;
00647 };
00648 #endif
00649
00651 typedef struct apr_bucket_file apr_bucket_file;
00655 struct apr_bucket_file {
00657 apr_bucket_refcount refcount;
00659 apr_file_t *fd;
00662 apr_pool_t *readpool;
00663 #if APR_HAS_MMAP
00664
00666 int can_mmap;
00667 #endif
00668 };
00669
00671 typedef union apr_bucket_structs apr_bucket_structs;
00676 union apr_bucket_structs {
00677 apr_bucket b;
00678 apr_bucket_heap heap;
00679 apr_bucket_pool pool;
00680 #if APR_HAS_MMAP
00681 apr_bucket_mmap mmap;
00682 #endif
00683 apr_bucket_file file;
00684 };
00685
00691 #define APR_BUCKET_ALLOC_SIZE APR_ALIGN_DEFAULT(2*sizeof(apr_bucket_structs))
00692
00693
00701 APU_DECLARE(apr_bucket_brigade *) apr_brigade_create(apr_pool_t *p,
00702 apr_bucket_alloc_t *list);
00703
00709 APU_DECLARE(apr_status_t) apr_brigade_destroy(apr_bucket_brigade *b);
00710
00722 APU_DECLARE(apr_status_t) apr_brigade_cleanup(void *data);
00723
00733 APU_DECLARE(apr_bucket_brigade *) apr_brigade_split(apr_bucket_brigade *b,
00734 apr_bucket *e);
00735
00744 APU_DECLARE(apr_status_t) apr_brigade_partition(apr_bucket_brigade *b,
00745 apr_off_t point,
00746 apr_bucket **after_point);
00747
00748 #if APR_NOT_DONE_YET
00749
00755 APU_DECLARE(void) apr_brigade_consume(apr_bucket_brigade *b,
00756 apr_off_t nbytes);
00757 #endif
00758
00766 APU_DECLARE(apr_status_t) apr_brigade_length(apr_bucket_brigade *bb,
00767 int read_all,
00768 apr_off_t *length);
00769
00777 APU_DECLARE(apr_status_t) apr_brigade_flatten(apr_bucket_brigade *bb,
00778 char *c,
00779 apr_size_t *len);
00780
00788 APU_DECLARE(apr_status_t) apr_brigade_pflatten(apr_bucket_brigade *bb,
00789 char **c,
00790 apr_size_t *len,
00791 apr_pool_t *pool);
00792
00801 APU_DECLARE(apr_status_t) apr_brigade_split_line(apr_bucket_brigade *bbOut,
00802 apr_bucket_brigade *bbIn,
00803 apr_read_type_e block,
00804 apr_off_t maxbytes);
00805
00815 APU_DECLARE(apr_status_t) apr_brigade_to_iovec(apr_bucket_brigade *b,
00816 struct iovec *vec, int *nvec);
00817
00826 APU_DECLARE(apr_status_t) apr_brigade_vputstrs(apr_bucket_brigade *b,
00827 apr_brigade_flush flush,
00828 void *ctx,
00829 va_list va);
00830
00840 APU_DECLARE(apr_status_t) apr_brigade_write(apr_bucket_brigade *b,
00841 apr_brigade_flush flush, void *ctx,
00842 const char *str, apr_size_t nbyte);
00843
00853 APU_DECLARE(apr_status_t) apr_brigade_writev(apr_bucket_brigade *b,
00854 apr_brigade_flush flush,
00855 void *ctx,
00856 const struct iovec *vec,
00857 apr_size_t nvec);
00858
00867 APU_DECLARE(apr_status_t) apr_brigade_puts(apr_bucket_brigade *bb,
00868 apr_brigade_flush flush, void *ctx,
00869 const char *str);
00870
00879 APU_DECLARE(apr_status_t) apr_brigade_putc(apr_bucket_brigade *b,
00880 apr_brigade_flush flush, void *ctx,
00881 const char c);
00882
00891 APU_DECLARE_NONSTD(apr_status_t) apr_brigade_putstrs(apr_bucket_brigade *b,
00892 apr_brigade_flush flush,
00893 void *ctx, ...);
00894
00905 APU_DECLARE_NONSTD(apr_status_t) apr_brigade_printf(apr_bucket_brigade *b,
00906 apr_brigade_flush flush,
00907 void *ctx,
00908 const char *fmt, ...)
00909 __attribute__((format(printf,4,5)));
00910
00921 APU_DECLARE(apr_status_t) apr_brigade_vprintf(apr_bucket_brigade *b,
00922 apr_brigade_flush flush,
00923 void *ctx,
00924 const char *fmt, va_list va);
00925
00926
00940 APU_DECLARE_NONSTD(apr_bucket_alloc_t *) apr_bucket_alloc_create(apr_pool_t *p);
00941
00950 APU_DECLARE_NONSTD(apr_bucket_alloc_t *) apr_bucket_alloc_create_ex(apr_allocator_t *allocator);
00951
00956 APU_DECLARE_NONSTD(void) apr_bucket_alloc_destroy(apr_bucket_alloc_t *list);
00957
00963 APU_DECLARE_NONSTD(void *) apr_bucket_alloc(apr_size_t size, apr_bucket_alloc_t *list);
00964
00969 APU_DECLARE_NONSTD(void) apr_bucket_free(void *block);
00970
00971
00972
00979 #define apr_bucket_destroy(e) do { \
00980 (e)->type->destroy((e)->data); \
00981 (e)->free(e); \
00982 } while (0)
00983
00995 #define apr_bucket_delete(e) do { \
00996 APR_BUCKET_REMOVE(e); \
00997 apr_bucket_destroy(e); \
00998 } while (0)
00999
01007 #define apr_bucket_read(e,str,len,block) (e)->type->read(e, str, len, block)
01008
01015 #define apr_bucket_setaside(e,p) (e)->type->setaside(e,p)
01016
01022 #define apr_bucket_split(e,point) (e)->type->split(e, point)
01023
01029 #define apr_bucket_copy(e,c) (e)->type->copy(e, c)
01030
01031
01032
01042 APU_DECLARE_NONSTD(apr_status_t) apr_bucket_setaside_noop(apr_bucket *data,
01043 apr_pool_t *pool);
01044
01052 APU_DECLARE_NONSTD(apr_status_t) apr_bucket_setaside_notimpl(apr_bucket *data,
01053 apr_pool_t *pool);
01054
01062 APU_DECLARE_NONSTD(apr_status_t) apr_bucket_split_notimpl(apr_bucket *data,
01063 apr_size_t point);
01064
01072 APU_DECLARE_NONSTD(apr_status_t) apr_bucket_copy_notimpl(apr_bucket *e,
01073 apr_bucket **c);
01074
01084 APU_DECLARE_NONSTD(void) apr_bucket_destroy_noop(void *data);
01085
01092
01093
01094
01095
01096
01101 APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_flush;
01107 APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_eos;
01111 APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_file;
01116 APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_heap;
01117 #if APR_HAS_MMAP
01118
01121 APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_mmap;
01122 #endif
01123
01128 APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_pool;
01132 APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_pipe;
01138 APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_immortal;
01144 APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_transient;
01148 APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_socket;
01149
01150
01151
01152
01164 APU_DECLARE_NONSTD(apr_status_t) apr_bucket_simple_split(apr_bucket *b,
01165 apr_size_t point);
01166
01177 APU_DECLARE_NONSTD(apr_status_t) apr_bucket_simple_copy(apr_bucket *a,
01178 apr_bucket **b);
01179
01180
01181
01182
01197 APU_DECLARE(apr_bucket *) apr_bucket_shared_make(apr_bucket *b, void *data,
01198 apr_off_t start,
01199 apr_size_t length);
01200
01209 APU_DECLARE(int) apr_bucket_shared_destroy(void *data);
01210
01222 APU_DECLARE_NONSTD(apr_status_t) apr_bucket_shared_split(apr_bucket *b,
01223 apr_size_t point);
01224
01234 APU_DECLARE_NONSTD(apr_status_t) apr_bucket_shared_copy(apr_bucket *a,
01235 apr_bucket **b);
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01256 APU_DECLARE(apr_bucket *) apr_bucket_eos_create(apr_bucket_alloc_t *list);
01257
01265 APU_DECLARE(apr_bucket *) apr_bucket_eos_make(apr_bucket *b);
01266
01274 APU_DECLARE(apr_bucket *) apr_bucket_flush_create(apr_bucket_alloc_t *list);
01275
01283 APU_DECLARE(apr_bucket *) apr_bucket_flush_make(apr_bucket *b);
01284
01292 APU_DECLARE(apr_bucket *) apr_bucket_immortal_create(const char *buf,
01293 apr_size_t nbyte,
01294 apr_bucket_alloc_t *list);
01295
01303 APU_DECLARE(apr_bucket *) apr_bucket_immortal_make(apr_bucket *b,
01304 const char *buf,
01305 apr_size_t nbyte);
01306
01314 APU_DECLARE(apr_bucket *) apr_bucket_transient_create(const char *buf,
01315 apr_size_t nbyte,
01316 apr_bucket_alloc_t *list);
01317
01325 APU_DECLARE(apr_bucket *) apr_bucket_transient_make(apr_bucket *b,
01326 const char *buf,
01327 apr_size_t nbyte);
01328
01343 APU_DECLARE(apr_bucket *) apr_bucket_heap_create(const char *buf,
01344 apr_size_t nbyte,
01345 void (*free_func)(void *data),
01346 apr_bucket_alloc_t *list);
01356 APU_DECLARE(apr_bucket *) apr_bucket_heap_make(apr_bucket *b, const char *buf,
01357 apr_size_t nbyte,
01358 void (*free_func)(void *data));
01359
01369 APU_DECLARE(apr_bucket *) apr_bucket_pool_create(const char *buf,
01370 apr_size_t length,
01371 apr_pool_t *pool,
01372 apr_bucket_alloc_t *list);
01373
01382 APU_DECLARE(apr_bucket *) apr_bucket_pool_make(apr_bucket *b, const char *buf,
01383 apr_size_t length,
01384 apr_pool_t *pool);
01385
01386 #if APR_HAS_MMAP
01387
01396 APU_DECLARE(apr_bucket *) apr_bucket_mmap_create(apr_mmap_t *mm,
01397 apr_off_t start,
01398 apr_size_t length,
01399 apr_bucket_alloc_t *list);
01400
01410 APU_DECLARE(apr_bucket *) apr_bucket_mmap_make(apr_bucket *b, apr_mmap_t *mm,
01411 apr_off_t start,
01412 apr_size_t length);
01413 #endif
01414
01421 APU_DECLARE(apr_bucket *) apr_bucket_socket_create(apr_socket_t *thissock,
01422 apr_bucket_alloc_t *list);
01429 APU_DECLARE(apr_bucket *) apr_bucket_socket_make(apr_bucket *b,
01430 apr_socket_t *thissock);
01431
01438 APU_DECLARE(apr_bucket *) apr_bucket_pipe_create(apr_file_t *thispipe,
01439 apr_bucket_alloc_t *list);
01440
01447 APU_DECLARE(apr_bucket *) apr_bucket_pipe_make(apr_bucket *b,
01448 apr_file_t *thispipe);
01449
01460 APU_DECLARE(apr_bucket *) apr_bucket_file_create(apr_file_t *fd,
01461 apr_off_t offset,
01462 apr_size_t len,
01463 apr_pool_t *p,
01464 apr_bucket_alloc_t *list);
01465
01476 APU_DECLARE(apr_bucket *) apr_bucket_file_make(apr_bucket *b, apr_file_t *fd,
01477 apr_off_t offset,
01478 apr_size_t len, apr_pool_t *p);
01479
01486 APU_DECLARE(apr_status_t) apr_bucket_file_enable_mmap(apr_bucket *b,
01487 int enabled);
01488
01490 #ifdef __cplusplus
01491 }
01492 #endif
01493
01494 #endif