Main Page | Modules | Namespace List | Data Structures | File List | Data Fields | Globals | Related Pages

/home/oden/RPM/BUILD/apr-util-0.9.4/include/apr_buckets.h

Go to the documentation of this file.
00001 /* Copyright 2000-2004 The Apache Software Foundation 00002 * 00003 * Licensed under the Apache License, Version 2.0 (the "License"); 00004 * you may not use this file except in compliance with the License. 00005 * You may obtain a copy of the License at 00006 * 00007 * http://www.apache.org/licenses/LICENSE-2.0 00008 * 00009 * Unless required by applicable law or agreed to in writing, software 00010 * distributed under the License is distributed on an "AS IS" BASIS, 00011 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00012 * See the License for the specific language governing permissions and 00013 * limitations under the License. 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> /* for struct iovec */ 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 * Forward declaration of the main types. 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 * The apr_bucket_list structure doesn't actually need a name tag 00267 * because it has no existence independent of struct apr_bucket_brigade; 00268 * the ring macros are designed so that you can leave the name tag 00269 * argument empty in this situation but apparently the Windows compiler 00270 * doesn't like that. 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 * define APR_BUCKET_DEBUG if you want your brigades to be checked for 00285 * validity at every possible instant. this will slow your code down 00286 * substantially but is a very useful debugging tool. 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 00303 #define APR_BRIGADE_CHECK_CONSISTENCY(b) 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) 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 * General-purpose reference counting for the various bucket types. 00558 * 00559 * Any bucket type that keeps track of the resources it uses (i.e. 00560 * most of them except for IMMORTAL, TRANSIENT, and EOS) needs to 00561 * attach a reference count to the resource so that it can be freed 00562 * when the last bucket that uses it goes away. Resource-sharing may 00563 * occur because of bucket splits or buckets that refer to globally 00564 * cached data. */ 00565 00567 typedef struct apr_bucket_refcount apr_bucket_refcount; 00574 struct apr_bucket_refcount { 00576 int refcount; 00577 }; 00578 00579 /* ***** Reference-counted bucket types ***** */ 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 /* APR_HAS_MMAP */ 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 /* ***** Bucket Brigade Functions ***** */ 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 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 /* ***** Bucket freelist functions ***** */ 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 /* ***** Bucket Functions ***** */ 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 /* Bucket type handling */ 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 /* There is no apr_bucket_read_notimpl, because it is a required function 01093 */ 01094 01095 01096 /* All of the bucket types implemented by the core */ 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 01121 APU_DECLARE_DATA extern const apr_bucket_type_t apr_bucket_type_mmap; 01122 #endif 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 /* ***** Simple buckets ***** */ 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 /* ***** Shared, reference-counted buckets ***** */ 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 /* ***** Functions to Create Buckets of varying types ***** */ 01239 /* 01240 * Each bucket type foo has two initialization functions: 01241 * apr_bucket_foo_make which sets up some already-allocated memory as a 01242 * bucket of type foo; and apr_bucket_foo_create which allocates memory 01243 * for the bucket, calls apr_bucket_make_foo, and initializes the 01244 * bucket's list pointers. The apr_bucket_foo_make functions are used 01245 * inside the bucket code to change the type of buckets in place; 01246 * other code should call apr_bucket_foo_create. All the initialization 01247 * functions change nothing if they fail. 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 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 /* !APR_BUCKETS_H */

Generated on Wed Sep 15 18:51:15 2004 for Apache Portable Runtime Utility Library by doxygen 1.3.7