00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00021 #ifndef APR_BUCKETS_H
00022 #define APR_BUCKETS_H
00023 
00024 #if defined(APR_BUCKET_DEBUG) && !defined(APR_RING_DEBUG)
00025 #define APR_RING_DEBUG
00026 #endif
00027 
00028 #include "apu.h"
00029 #include "apr_network_io.h"
00030 #include "apr_file_io.h"
00031 #include "apr_general.h"
00032 #include "apr_mmap.h"
00033 #include "apr_errno.h"
00034 #include "apr_ring.h"
00035 #include "apr.h"
00036 #if APR_HAVE_SYS_UIO_H
00037 #include <sys/uio.h>    
00038 #endif
00039 #if APR_HAVE_STDARG_H
00040 #include <stdarg.h>
00041 #endif
00042 
00043 #ifdef __cplusplus
00044 extern "C" {
00045 #endif
00046 
00054 #define APR_BUCKET_BUFF_SIZE 8000
00055 
00057 typedef enum {
00058     APR_BLOCK_READ,   
00059     APR_NONBLOCK_READ 
00060 } apr_read_type_e;
00061 
00114 
00115 
00116 
00117 
00119 typedef struct apr_bucket_brigade apr_bucket_brigade;
00121 typedef struct apr_bucket apr_bucket;
00123 typedef struct apr_bucket_alloc_t apr_bucket_alloc_t;
00124 
00126 typedef struct apr_bucket_type_t apr_bucket_type_t;
00127 
00131 struct apr_bucket_type_t {
00135     const char *name;
00140     int num_func;
00151     enum {
00153         APR_BUCKET_DATA = 0,
00155         APR_BUCKET_METADATA = 1
00156     } is_metadata;
00164     void (*destroy)(void *data);
00165 
00176     apr_status_t (*read)(apr_bucket *b, const char **str, apr_size_t *len, 
00177                          apr_read_type_e block);
00178     
00192     apr_status_t (*setaside)(apr_bucket *e, apr_pool_t *pool);
00193 
00203     apr_status_t (*split)(apr_bucket *e, apr_size_t point);
00204 
00211     apr_status_t (*copy)(apr_bucket *e, apr_bucket **c);
00212 
00213 };
00214 
00224 struct apr_bucket {
00226     APR_RING_ENTRY(apr_bucket) link;
00228     const apr_bucket_type_t *type;
00234     apr_size_t length;
00242     apr_off_t start;
00244     void *data; 
00252     void (*free)(void *e);
00254     apr_bucket_alloc_t *list;
00255 };
00256 
00258 struct apr_bucket_brigade {
00264     apr_pool_t *p;
00266     
00267 
00268 
00269 
00270 
00271 
00272 
00273     APR_RING_HEAD(apr_bucket_list, apr_bucket) list;
00275     apr_bucket_alloc_t *bucket_alloc;
00276 };
00277 
00278 
00282 typedef apr_status_t (*apr_brigade_flush)(apr_bucket_brigade *bb, void *ctx);
00283 
00284 
00285 
00286 
00287 
00288 
00289 #ifdef APR_BUCKET_DEBUG
00290 
00291 #define APR_BRIGADE_CHECK_CONSISTENCY(b)                                \
00292         APR_RING_CHECK_CONSISTENCY(&(b)->list, apr_bucket, link)
00293 
00294 #define APR_BUCKET_CHECK_CONSISTENCY(e)                                 \
00295         APR_RING_CHECK_ELEM_CONSISTENCY((e), apr_bucket, link)
00296 
00297 #else
00298 
00304 #define APR_BRIGADE_CHECK_CONSISTENCY(b)
00305 
00311 #define APR_BUCKET_CHECK_CONSISTENCY(e)
00312 #endif
00313 
00314 
00331 #define APR_BRIGADE_SENTINEL(b) APR_RING_SENTINEL(&(b)->list, apr_bucket, link)
00332 
00338 #define APR_BRIGADE_EMPTY(b)    APR_RING_EMPTY(&(b)->list, apr_bucket, link)
00339 
00345 #define APR_BRIGADE_FIRST(b)    APR_RING_FIRST(&(b)->list)
00346 
00351 #define APR_BRIGADE_LAST(b)     APR_RING_LAST(&(b)->list)
00352 
00358 #define APR_BRIGADE_INSERT_HEAD(b, e) do {                              \
00359         apr_bucket *ap__b = (e);                                        \
00360         APR_RING_INSERT_HEAD(&(b)->list, ap__b, apr_bucket, link);      \
00361         APR_BRIGADE_CHECK_CONSISTENCY((b));                             \
00362     } while (0)
00363 
00369 #define APR_BRIGADE_INSERT_TAIL(b, e) do {                              \
00370         apr_bucket *ap__b = (e);                                        \
00371         APR_RING_INSERT_TAIL(&(b)->list, ap__b, apr_bucket, link);      \
00372         APR_BRIGADE_CHECK_CONSISTENCY((b));                             \
00373     } while (0)
00374 
00380 #define APR_BRIGADE_CONCAT(a, b) do {                                   \
00381         APR_RING_CONCAT(&(a)->list, &(b)->list, apr_bucket, link);      \
00382         APR_BRIGADE_CHECK_CONSISTENCY((a));                             \
00383     } while (0)
00384 
00390 #define APR_BRIGADE_PREPEND(a, b) do {                                  \
00391         APR_RING_PREPEND(&(a)->list, &(b)->list, apr_bucket, link);     \
00392         APR_BRIGADE_CHECK_CONSISTENCY((a));                             \
00393     } while (0)
00394 
00400 #define APR_BUCKET_INSERT_BEFORE(a, b) do {                             \
00401         apr_bucket *ap__a = (a), *ap__b = (b);                          \
00402         APR_RING_INSERT_BEFORE(ap__a, ap__b, link);                     \
00403         APR_BUCKET_CHECK_CONSISTENCY(ap__a);                            \
00404     } while (0)
00405 
00411 #define APR_BUCKET_INSERT_AFTER(a, b) do {                              \
00412         apr_bucket *ap__a = (a), *ap__b = (b);                          \
00413         APR_RING_INSERT_AFTER(ap__a, ap__b, link);                      \
00414         APR_BUCKET_CHECK_CONSISTENCY(ap__a);                            \
00415     } while (0)
00416 
00422 #define APR_BUCKET_NEXT(e)      APR_RING_NEXT((e), link)
00423 
00428 #define APR_BUCKET_PREV(e)      APR_RING_PREV((e), link)
00429 
00434 #define APR_BUCKET_REMOVE(e)    APR_RING_REMOVE((e), link)
00435 
00440 #define APR_BUCKET_INIT(e)      APR_RING_ELEM_INIT((e), link)
00441 
00448 #define APR_BUCKET_IS_METADATA(e)    ((e)->type->is_metadata)
00449 
00455 #define APR_BUCKET_IS_FLUSH(e)       ((e)->type == &apr_bucket_type_flush)
00456 
00461 #define APR_BUCKET_IS_EOS(e)         ((e)->type == &apr_bucket_type_eos)
00462 
00467 #define APR_BUCKET_IS_FILE(e)        ((e)->type == &apr_bucket_type_file)
00468 
00473 #define APR_BUCKET_IS_PIPE(e)        ((e)->type == &apr_bucket_type_pipe)
00474 
00479 #define APR_BUCKET_IS_SOCKET(e)      ((e)->type == &apr_bucket_type_socket)
00480 
00485 #define APR_BUCKET_IS_HEAP(e)        ((e)->type == &apr_bucket_type_heap)
00486 
00491 #define APR_BUCKET_IS_TRANSIENT(e)   ((e)->type == &apr_bucket_type_transient)
00492 
00497 #define APR_BUCKET_IS_IMMORTAL(e)    ((e)->type == &apr_bucket_type_immortal)
00498 #if APR_HAS_MMAP
00499 
00504 #define APR_BUCKET_IS_MMAP(e)        ((e)->type == &apr_bucket_type_mmap)
00505 #endif
00506 
00511 #define APR_BUCKET_IS_POOL(e)        ((e)->type == &apr_bucket_type_pool)
00512 
00513 
00514 
00515 
00516 
00517 
00518 
00519 
00520 
00521 
00522 
00524 typedef struct apr_bucket_refcount apr_bucket_refcount;
00531 struct apr_bucket_refcount {
00533     int          refcount;
00534 };
00535 
00536 
00537 
00539 typedef struct apr_bucket_heap apr_bucket_heap;
00543 struct apr_bucket_heap {
00545     apr_bucket_refcount  refcount;
00549     char    *base;
00551     apr_size_t  alloc_len;
00553     void (*free_func)(void *data);
00554 };
00555 
00557 typedef struct apr_bucket_pool apr_bucket_pool;
00561 struct apr_bucket_pool {
00573     apr_bucket_heap  heap;
00579     const char *base;
00586     apr_pool_t *pool;
00590     apr_bucket_alloc_t *list;
00591 };
00592 
00593 #if APR_HAS_MMAP
00594 
00595 typedef struct apr_bucket_mmap apr_bucket_mmap;
00599 struct apr_bucket_mmap {
00601     apr_bucket_refcount  refcount;
00603     apr_mmap_t *mmap;
00604 };
00605 #endif
00606 
00608 typedef struct apr_bucket_file apr_bucket_file;
00612 struct apr_bucket_file {
00614     apr_bucket_refcount  refcount;
00616     apr_file_t *fd;
00619     apr_pool_t *readpool;
00620 #if APR_HAS_MMAP
00621 
00623     int can_mmap;
00624 #endif 
00625 };
00626 
00628 typedef union apr_bucket_structs apr_bucket_structs;
00633 union apr_bucket_structs {
00634     apr_bucket      b;      
00635     apr_bucket_heap heap;   
00636     apr_bucket_pool pool;   
00637 #if APR_HAS_MMAP
00638     apr_bucket_mmap mmap;   
00639 #endif
00640     apr_bucket_file file;   
00641 };
00642 
00648 #define APR_BUCKET_ALLOC_SIZE  APR_ALIGN_DEFAULT(2*sizeof(apr_bucket_structs))
00649 
00650 
00658 APU_DECLARE(apr_bucket_brigade *) apr_brigade_create(apr_pool_t *p,
00659                                                      apr_bucket_alloc_t *list);
00660 
00666 APU_DECLARE(apr_status_t) apr_brigade_destroy(apr_bucket_brigade *b);
00667 
00679 APU_DECLARE(apr_status_t) apr_brigade_cleanup(void *data);
00680 
00694 APU_DECLARE(apr_bucket_brigade *) apr_brigade_split_ex(apr_bucket_brigade *b,
00695                                                        apr_bucket *e,
00696                                                        apr_bucket_brigade *a);
00697 
00709 APU_DECLARE(apr_bucket_brigade *) apr_brigade_split(apr_bucket_brigade *b,
00710                                                     apr_bucket *e);
00711 
00724 APU_DECLARE(apr_status_t) apr_brigade_partition(apr_bucket_brigade *b,
00725                                                 apr_off_t point,
00726                                                 apr_bucket **after_point);
00727 
00736 APU_DECLARE(apr_status_t) apr_brigade_length(apr_bucket_brigade *bb,
00737                                              int read_all,
00738                                              apr_off_t *length);
00739 
00747 APU_DECLARE(apr_status_t) apr_brigade_flatten(apr_bucket_brigade *bb,
00748                                               char *c,
00749                                               apr_size_t *len);
00750 
00758 APU_DECLARE(apr_status_t) apr_brigade_pflatten(apr_bucket_brigade *bb, 
00759                                                char **c,
00760                                                apr_size_t *len,
00761                                                apr_pool_t *pool);
00762 
00771 APU_DECLARE(apr_status_t) apr_brigade_split_line(apr_bucket_brigade *bbOut,
00772                                                  apr_bucket_brigade *bbIn,
00773                                                  apr_read_type_e block,
00774                                                  apr_off_t maxbytes);
00775 
00785 APU_DECLARE(apr_status_t) apr_brigade_to_iovec(apr_bucket_brigade *b, 
00786                                                struct iovec *vec, int *nvec);
00787 
00796 APU_DECLARE(apr_status_t) apr_brigade_vputstrs(apr_bucket_brigade *b,
00797                                                apr_brigade_flush flush,
00798                                                void *ctx,
00799                                                va_list va);
00800 
00810 APU_DECLARE(apr_status_t) apr_brigade_write(apr_bucket_brigade *b,
00811                                             apr_brigade_flush flush, void *ctx,
00812                                             const char *str, apr_size_t nbyte);
00813 
00823 APU_DECLARE(apr_status_t) apr_brigade_writev(apr_bucket_brigade *b,
00824                                              apr_brigade_flush flush,
00825                                              void *ctx,
00826                                              const struct iovec *vec,
00827                                              apr_size_t nvec);
00828 
00837 APU_DECLARE(apr_status_t) apr_brigade_puts(apr_bucket_brigade *bb,
00838                                            apr_brigade_flush flush, void *ctx,
00839                                            const char *str);
00840 
00849 APU_DECLARE(apr_status_t) apr_brigade_putc(apr_bucket_brigade *b,
00850                                            apr_brigade_flush flush, void *ctx,
00851                                            const char c);
00852 
00861 APU_DECLARE_NONSTD(apr_status_t) apr_brigade_putstrs(apr_bucket_brigade *b,
00862                                                      apr_brigade_flush flush,
00863                                                      void *ctx, ...);
00864 
00875 APU_DECLARE_NONSTD(apr_status_t) apr_brigade_printf(apr_bucket_brigade *b, 
00876                                                     apr_brigade_flush flush,
00877                                                     void *ctx,
00878                                                     const char *fmt, ...)
00879         __attribute__((format(printf,4,5)));
00880 
00891 APU_DECLARE(apr_status_t) apr_brigade_vprintf(apr_bucket_brigade *b, 
00892                                               apr_brigade_flush flush,
00893                                               void *ctx,
00894                                               const char *fmt, va_list va);
00895 
00908 APU_DECLARE(apr_bucket *) apr_brigade_insert_file(apr_bucket_brigade *bb,
00909                                                   apr_file_t *f,
00910                                                   apr_off_t start,
00911                                                   apr_off_t len,
00912                                                   apr_pool_t *p);
00913 
00914 
00915 
00916 
00930 APU_DECLARE_NONSTD(apr_bucket_alloc_t *) apr_bucket_alloc_create(apr_pool_t *p);
00931 
00940 APU_DECLARE_NONSTD(apr_bucket_alloc_t *) apr_bucket_alloc_create_ex(apr_allocator_t *allocator);
00941 
00946 APU_DECLARE_NONSTD(void) apr_bucket_alloc_destroy(apr_bucket_alloc_t *list);
00947 
00953 APU_DECLARE_NONSTD(void *) apr_bucket_alloc(apr_size_t size, apr_bucket_alloc_t *list);
00954 
00959 APU_DECLARE_NONSTD(void) apr_bucket_free(void *block);
00960 
00961 
00962 
00969 #define apr_bucket_destroy(e) do {                                      \
00970         (e)->type->destroy((e)->data);                                  \
00971         (e)->free(e);                                                   \
00972     } while (0)
00973 
00985 #define apr_bucket_delete(e) do {                                       \
00986         APR_BUCKET_REMOVE(e);                                           \
00987         apr_bucket_destroy(e);                                          \
00988     } while (0)
00989 
01006 #define apr_bucket_read(e,str,len,block) (e)->type->read(e, str, len, block)
01007 
01014 #define apr_bucket_setaside(e,p) (e)->type->setaside(e,p)
01015 
01026 #define apr_bucket_split(e,point) (e)->type->split(e, point)
01027 
01033 #define apr_bucket_copy(e,c) (e)->type->copy(e, c)
01034 
01035 
01036 
01046 APU_DECLARE_NONSTD(apr_status_t) apr_bucket_setaside_noop(apr_bucket *data,
01047                                                           apr_pool_t *pool);
01048 
01056 APU_DECLARE_NONSTD(apr_status_t) apr_bucket_setaside_notimpl(apr_bucket *data,
01057                                                              apr_pool_t *pool);
01058 
01066 APU_DECLARE_NONSTD(apr_status_t) apr_bucket_split_notimpl(apr_bucket *data,
01067                                                           apr_size_t point);
01068 
01076 APU_DECLARE_NONSTD(apr_status_t) apr_bucket_copy_notimpl(apr_bucket *e,
01077                                                          apr_bucket **c);
01078 
01088 APU_DECLARE_NONSTD(void) apr_bucket_destroy_noop(void *data);
01089 
01096 
01097 
01098 
01099 
01100 
01105 APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_flush;
01111 APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_eos;
01115 APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_file;
01120 APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_heap;
01121 #if APR_HAS_MMAP
01122 
01125 APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_mmap;
01126 #endif
01127 
01132 APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_pool;
01136 APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_pipe;
01142 APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_immortal;
01148 APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_transient;
01152 APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_socket;
01153 
01154 
01155 
01156 
01168 APU_DECLARE_NONSTD(apr_status_t) apr_bucket_simple_split(apr_bucket *b,
01169                                                          apr_size_t point);
01170 
01181 APU_DECLARE_NONSTD(apr_status_t) apr_bucket_simple_copy(apr_bucket *a,
01182                                                         apr_bucket **b);
01183 
01184 
01185 
01186 
01201 APU_DECLARE(apr_bucket *) apr_bucket_shared_make(apr_bucket *b, void *data,
01202                                                  apr_off_t start, 
01203                                                  apr_size_t length);
01204 
01213 APU_DECLARE(int) apr_bucket_shared_destroy(void *data);
01214 
01226 APU_DECLARE_NONSTD(apr_status_t) apr_bucket_shared_split(apr_bucket *b,
01227                                                          apr_size_t point);
01228 
01238 APU_DECLARE_NONSTD(apr_status_t) apr_bucket_shared_copy(apr_bucket *a,
01239                                                         apr_bucket **b);
01240 
01241 
01242 
01243 
01244 
01245 
01246 
01247 
01248 
01249 
01250 
01251 
01252 
01253 
01260 APU_DECLARE(apr_bucket *) apr_bucket_eos_create(apr_bucket_alloc_t *list);
01261 
01269 APU_DECLARE(apr_bucket *) apr_bucket_eos_make(apr_bucket *b);
01270 
01278 APU_DECLARE(apr_bucket *) apr_bucket_flush_create(apr_bucket_alloc_t *list);
01279 
01287 APU_DECLARE(apr_bucket *) apr_bucket_flush_make(apr_bucket *b);
01288 
01296 APU_DECLARE(apr_bucket *) apr_bucket_immortal_create(const char *buf, 
01297                                                      apr_size_t nbyte,
01298                                                      apr_bucket_alloc_t *list);
01299 
01307 APU_DECLARE(apr_bucket *) apr_bucket_immortal_make(apr_bucket *b, 
01308                                                    const char *buf, 
01309                                                    apr_size_t nbyte);
01310 
01318 APU_DECLARE(apr_bucket *) apr_bucket_transient_create(const char *buf, 
01319                                                       apr_size_t nbyte,
01320                                                       apr_bucket_alloc_t *list);
01321 
01329 APU_DECLARE(apr_bucket *) apr_bucket_transient_make(apr_bucket *b, 
01330                                                     const char *buf,
01331                                                     apr_size_t nbyte);
01332 
01347 APU_DECLARE(apr_bucket *) apr_bucket_heap_create(const char *buf, 
01348                                                  apr_size_t nbyte,
01349                                                  void (*free_func)(void *data),
01350                                                  apr_bucket_alloc_t *list);
01360 APU_DECLARE(apr_bucket *) apr_bucket_heap_make(apr_bucket *b, const char *buf,
01361                                                apr_size_t nbyte,
01362                                                void (*free_func)(void *data));
01363 
01373 APU_DECLARE(apr_bucket *) apr_bucket_pool_create(const char *buf, 
01374                                                  apr_size_t length,
01375                                                  apr_pool_t *pool,
01376                                                  apr_bucket_alloc_t *list);
01377 
01386 APU_DECLARE(apr_bucket *) apr_bucket_pool_make(apr_bucket *b, const char *buf,
01387                                                apr_size_t length, 
01388                                                apr_pool_t *pool);
01389 
01390 #if APR_HAS_MMAP
01391 
01400 APU_DECLARE(apr_bucket *) apr_bucket_mmap_create(apr_mmap_t *mm, 
01401                                                  apr_off_t start,
01402                                                  apr_size_t length,
01403                                                  apr_bucket_alloc_t *list);
01404 
01414 APU_DECLARE(apr_bucket *) apr_bucket_mmap_make(apr_bucket *b, apr_mmap_t *mm,
01415                                                apr_off_t start, 
01416                                                apr_size_t length);
01417 #endif
01418 
01425 APU_DECLARE(apr_bucket *) apr_bucket_socket_create(apr_socket_t *thissock,
01426                                                    apr_bucket_alloc_t *list);
01433 APU_DECLARE(apr_bucket *) apr_bucket_socket_make(apr_bucket *b, 
01434                                                  apr_socket_t *thissock);
01435 
01442 APU_DECLARE(apr_bucket *) apr_bucket_pipe_create(apr_file_t *thispipe,
01443                                                  apr_bucket_alloc_t *list);
01444 
01451 APU_DECLARE(apr_bucket *) apr_bucket_pipe_make(apr_bucket *b, 
01452                                                apr_file_t *thispipe);
01453 
01470 APU_DECLARE(apr_bucket *) apr_bucket_file_create(apr_file_t *fd,
01471                                                  apr_off_t offset,
01472                                                  apr_size_t len, 
01473                                                  apr_pool_t *p,
01474                                                  apr_bucket_alloc_t *list);
01475 
01486 APU_DECLARE(apr_bucket *) apr_bucket_file_make(apr_bucket *b, apr_file_t *fd,
01487                                                apr_off_t offset,
01488                                                apr_size_t len, apr_pool_t *p);
01489 
01496 APU_DECLARE(apr_status_t) apr_bucket_file_enable_mmap(apr_bucket *b,
01497                                                       int enabled);
01498 
01500 #ifdef __cplusplus
01501 }
01502 #endif
01503 
01504 #endif