serf_bucket_util.h revision 253895
1353944Sdim/* Copyright 2002-2004 Justin Erenkrantz and Greg Stein 2353944Sdim * 3353944Sdim * Licensed under the Apache License, Version 2.0 (the "License"); 4353944Sdim * you may not use this file except in compliance with the License. 5353944Sdim * You may obtain a copy of the License at 6353944Sdim * 7353944Sdim * http://www.apache.org/licenses/LICENSE-2.0 8353944Sdim * 9353944Sdim * Unless required by applicable law or agreed to in writing, software 10353944Sdim * distributed under the License is distributed on an "AS IS" BASIS, 11353944Sdim * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12353944Sdim * See the License for the specific language governing permissions and 13353944Sdim * limitations under the License. 14353944Sdim */ 15353944Sdim 16353944Sdim#ifndef SERF_BUCKET_UTIL_H 17353944Sdim#define SERF_BUCKET_UTIL_H 18353944Sdim 19353944Sdim/** 20353944Sdim * @file serf_bucket_util.h 21353944Sdim * @brief This header defines a set of functions and other utilities 22353944Sdim * for implementing buckets. It is not needed by users of the bucket 23353944Sdim * system. 24353944Sdim */ 25353944Sdim 26353944Sdim#include "serf.h" 27353944Sdim 28353944Sdim#ifdef __cplusplus 29353944Sdimextern "C" { 30353944Sdim#endif 31353944Sdim 32353944Sdim 33353944Sdim/** 34353944Sdim * Basic bucket creation function. 35353944Sdim * 36353944Sdim * This function will create a bucket of @a type, allocating the necessary 37353944Sdim * memory from @a allocator. The @a data bucket-private information will 38353944Sdim * be stored into the bucket. 39353944Sdim */ 40353944Sdimserf_bucket_t *serf_bucket_create( 41353944Sdim const serf_bucket_type_t *type, 42353944Sdim serf_bucket_alloc_t *allocator, 43353944Sdim void *data); 44353944Sdim 45353944Sdim/** 46353944Sdim * Default implementation of the @see read_iovec functionality. 47353944Sdim * 48353944Sdim * This function will use the @see read function to get a block of memory, 49353944Sdim * then return it in the iovec. 50353944Sdim */ 51353944Sdimapr_status_t serf_default_read_iovec( 52353944Sdim serf_bucket_t *bucket, 53353944Sdim apr_size_t requested, 54353944Sdim int vecs_size, 55353944Sdim struct iovec *vecs, 56353944Sdim int *vecs_used); 57353944Sdim 58353944Sdim/** 59353944Sdim * Default implementation of the @see read_for_sendfile functionality. 60353944Sdim * 61353944Sdim * This function will use the @see read function to get a block of memory, 62353944Sdim * then return it as a header. No file will be returned. 63353944Sdim */ 64353944Sdimapr_status_t serf_default_read_for_sendfile( 65353944Sdim serf_bucket_t *bucket, 66353944Sdim apr_size_t requested, 67353944Sdim apr_hdtr_t *hdtr, 68353944Sdim apr_file_t **file, 69353944Sdim apr_off_t *offset, 70353944Sdim apr_size_t *len); 71353944Sdim 72353944Sdim/** 73353944Sdim * Default implementation of the @see read_bucket functionality. 74353944Sdim * 75353944Sdim * This function will always return NULL, indicating that the @a type 76353944Sdim * of bucket cannot be found within @a bucket. 77353944Sdim */ 78353944Sdimserf_bucket_t *serf_default_read_bucket( 79353944Sdim serf_bucket_t *bucket, 80353944Sdim const serf_bucket_type_t *type); 81353944Sdim 82353944Sdim/** 83353944Sdim * Default implementation of the @see destroy functionality. 84353944Sdim * 85353944Sdim * This function will return the @a bucket to its allcoator. 86353944Sdim */ 87353944Sdimvoid serf_default_destroy( 88353944Sdim serf_bucket_t *bucket); 89353944Sdim 90353944Sdim 91353944Sdim/** 92353944Sdim * Default implementation of the @see destroy functionality. 93353944Sdim * 94353944Sdim * This function will return the @a bucket, and the data member to its 95353944Sdim * allocator. 96353944Sdim */ 97353944Sdimvoid serf_default_destroy_and_data( 98353944Sdim serf_bucket_t *bucket); 99353944Sdim 100353944Sdim 101353944Sdim/** 102353944Sdim * Allocate @a size bytes of memory using @a allocator. 103353944Sdim * 104353944Sdim * Returns NULL of the requested memory size could not be allocated. 105353944Sdim */ 106353944Sdimvoid *serf_bucket_mem_alloc( 107353944Sdim serf_bucket_alloc_t *allocator, 108353944Sdim apr_size_t size); 109353944Sdim 110353944Sdim/** 111353944Sdim * Allocate @a size bytes of memory using @a allocator and set all of the 112353944Sdim * memory to 0. 113353944Sdim * 114353944Sdim * Returns NULL of the requested memory size could not be allocated. 115353944Sdim */ 116353944Sdimvoid *serf_bucket_mem_calloc( 117353944Sdim serf_bucket_alloc_t *allocator, 118353944Sdim apr_size_t size); 119353944Sdim 120353944Sdim/** 121353944Sdim * Free the memory at @a block, returning it to @a allocator. 122353944Sdim */ 123353944Sdimvoid serf_bucket_mem_free( 124353944Sdim serf_bucket_alloc_t *allocator, 125353944Sdim void *block); 126353944Sdim 127353944Sdim 128353944Sdim/** 129353944Sdim * Analogous to apr_pstrmemdup, using a bucket allocator instead. 130353944Sdim */ 131353944Sdimchar *serf_bstrmemdup( 132353944Sdim serf_bucket_alloc_t *allocator, 133353944Sdim const char *str, 134353944Sdim apr_size_t size); 135353944Sdim 136353944Sdim/** 137353944Sdim * Analogous to apr_pmemdup, using a bucket allocator instead. 138353944Sdim */ 139353944Sdimvoid * serf_bmemdup( 140353944Sdim serf_bucket_alloc_t *allocator, 141353944Sdim const void *mem, 142353944Sdim apr_size_t size); 143353944Sdim 144353944Sdim/** 145353944Sdim * Analogous to apr_pstrdup, using a bucket allocator instead. 146353944Sdim */ 147353944Sdimchar * serf_bstrdup( 148353944Sdim serf_bucket_alloc_t *allocator, 149353944Sdim const char *str); 150353944Sdim 151353944Sdim/** 152353944Sdim * Analogous to apr_pstrcatv, using a bucket allocator instead. 153353944Sdim */ 154353944Sdimchar * serf_bstrcatv( 155353944Sdim serf_bucket_alloc_t *allocator, 156353944Sdim struct iovec *vec, 157353944Sdim int vecs, 158353944Sdim apr_size_t *bytes_written); 159353944Sdim 160353944Sdim/** 161353944Sdim * Read data up to a newline. 162353944Sdim * 163353944Sdim * @a acceptable contains the allowed forms of a newline, and @a found 164353944Sdim * will return the particular newline type that was found. If a newline 165353944Sdim * is not found, then SERF_NEWLINE_NONE will be placed in @a found. 166353944Sdim * 167353944Sdim * @a data should contain a pointer to the data to be scanned. @a len 168353944Sdim * should specify the length of that data buffer. On exit, @a data will 169353944Sdim * be advanced past the newline, and @a len will specify the remaining 170353944Sdim * amount of data in the buffer. 171353944Sdim * 172353944Sdim * Given this pattern of behavior, the caller should store the initial 173353944Sdim * value of @a data as the line start. The difference between the 174353944Sdim * returned value of @a data and the saved start is the length of the 175353944Sdim * line. 176353944Sdim * 177353944Sdim * Note that the newline character(s) will remain within the buffer. 178353944Sdim * This function scans at a byte level for the newline characters. Thus, 179353944Sdim * the data buffer may contain NUL characters. As a corollary, this 180353944Sdim * function only works on 8-bit character encodings. 181353944Sdim * 182353944Sdim * If the data is fully consumed (@a len gets set to zero) and a CR 183353944Sdim * character is found at the end and the CRLF sequence is allowed, then 184353944Sdim * this function may store SERF_NEWLINE_CRLF_SPLIT into @a found. The 185353944Sdim * caller should take particular consideration for the CRLF sequence 186353944Sdim * that may be split across data buffer boundaries. 187353944Sdim */ 188353944Sdimvoid serf_util_readline( 189353944Sdim const char **data, 190353944Sdim apr_size_t *len, 191353944Sdim int acceptable, 192353944Sdim int *found); 193353944Sdim 194353944Sdim 195353944Sdim/** The buffer size used within @see serf_databuf_t. */ 196353944Sdim#define SERF_DATABUF_BUFSIZE 8000 197353944Sdim 198353944Sdim/** Callback function which is used to refill the data buffer. 199353944Sdim * 200353944Sdim * The function takes @a baton, which is the @see read_baton value 201353944Sdim * from the serf_databuf_t structure. Data should be placed into 202353944Sdim * a buffer specified by @a buf, which is @a bufsize bytes long. 203353944Sdim * The amount of data read should be returned in @a len. 204353944Sdim * 205353944Sdim * APR_EOF should be returned if no more data is available. APR_EAGAIN 206353944Sdim * should be returned, rather than blocking. In both cases, @a buf 207353944Sdim * should be filled in and @a len set, as appropriate. 208353944Sdim */ 209353944Sdimtypedef apr_status_t (*serf_databuf_reader_t)( 210353944Sdim void *baton, 211353944Sdim apr_size_t bufsize, 212353944Sdim char *buf, 213353944Sdim apr_size_t *len); 214353944Sdim 215353944Sdim/** 216353944Sdim * This structure is used as an intermediate data buffer for some "external" 217353944Sdim * source of data. It works as a scratch pad area for incoming data to be 218353944Sdim * stored, and then returned as a ptr/len pair by the bucket read functions. 219353944Sdim * 220353944Sdim * This structure should be initialized by calling @see serf_databuf_init. 221353944Sdim * Users should not bother to zero the structure beforehand. 222353944Sdim */ 223353944Sdimtypedef struct { 224353944Sdim /** The current data position within the buffer. */ 225353944Sdim const char *current; 226353944Sdim 227353944Sdim /** Amount of data remaining in the buffer. */ 228353944Sdim apr_size_t remaining; 229353944Sdim 230353944Sdim /** Callback function. */ 231353944Sdim serf_databuf_reader_t read; 232353944Sdim 233353944Sdim /** A baton to hold context-specific data. */ 234353944Sdim void *read_baton; 235353944Sdim 236353944Sdim /** Records the status from the last @see read operation. */ 237353944Sdim apr_status_t status; 238353944Sdim 239353944Sdim /** Holds the data until it can be returned. */ 240353944Sdim char buf[SERF_DATABUF_BUFSIZE]; 241353944Sdim 242353944Sdim} serf_databuf_t; 243353944Sdim 244353944Sdim/** 245353944Sdim * Initialize the @see serf_databuf_t structure specified by @a databuf. 246353944Sdim */ 247353944Sdimvoid serf_databuf_init( 248353944Sdim serf_databuf_t *databuf); 249357095Sdim 250353944Sdim/** 251353944Sdim * Implement a bucket-style read function from the @see serf_databuf_t 252353944Sdim * structure given by @a databuf. 253353944Sdim * 254353944Sdim * The @a requested, @a data, and @a len fields are interpreted and used 255353944Sdim * as in the read function of @see serf_bucket_t. 256353944Sdim */ 257353944Sdimapr_status_t serf_databuf_read( 258353944Sdim serf_databuf_t *databuf, 259353944Sdim apr_size_t requested, 260353944Sdim const char **data, 261353944Sdim apr_size_t *len); 262353944Sdim 263353944Sdim/** 264353944Sdim * Implement a bucket-style readline function from the @see serf_databuf_t 265353944Sdim * structure given by @a databuf. 266353944Sdim * 267353944Sdim * The @a acceptable, @a found, @a data, and @a len fields are interpreted 268353944Sdim * and used as in the read function of @see serf_bucket_t. 269353944Sdim */ 270353944Sdimapr_status_t serf_databuf_readline( 271353944Sdim serf_databuf_t *databuf, 272353944Sdim int acceptable, 273353944Sdim int *found, 274353944Sdim const char **data, 275353944Sdim apr_size_t *len); 276353944Sdim 277353944Sdim/** 278353944Sdim * Implement a bucket-style peek function from the @see serf_databuf_t 279353944Sdim * structure given by @a databuf. 280353944Sdim * 281353944Sdim * The @a data, and @a len fields are interpreted and used as in the 282353944Sdim * peek function of @see serf_bucket_t. 283353944Sdim */ 284357095Sdimapr_status_t serf_databuf_peek( 285357095Sdim serf_databuf_t *databuf, 286357095Sdim const char **data, 287357095Sdim apr_size_t *len); 288353944Sdim 289353944Sdim 290353944Sdim#ifdef __cplusplus 291353944Sdim} 292353944Sdim#endif 293353944Sdim 294353944Sdim#endif /* !SERF_BUCKET_UTIL_H */ 295353944Sdim