1/* Copyright 2002-2004 Justin Erenkrantz and Greg Stein 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#ifndef SERF_BUCKET_UTIL_H 17#define SERF_BUCKET_UTIL_H 18 19/** 20 * @file serf_bucket_util.h 21 * @brief This header defines a set of functions and other utilities 22 * for implementing buckets. It is not needed by users of the bucket 23 * system. 24 */ 25 26#include "serf.h" 27 28#ifdef __cplusplus 29extern "C" { 30#endif 31 32 33/** 34 * Basic bucket creation function. 35 * 36 * This function will create a bucket of @a type, allocating the necessary 37 * memory from @a allocator. The @a data bucket-private information will 38 * be stored into the bucket. 39 */ 40serf_bucket_t *serf_bucket_create( 41 const serf_bucket_type_t *type, 42 serf_bucket_alloc_t *allocator, 43 void *data); 44 45/** 46 * Default implementation of the @see read_iovec functionality. 47 * 48 * This function will use the @see read function to get a block of memory, 49 * then return it in the iovec. 50 */ 51apr_status_t serf_default_read_iovec( 52 serf_bucket_t *bucket, 53 apr_size_t requested, 54 int vecs_size, 55 struct iovec *vecs, 56 int *vecs_used); 57 58/** 59 * Default implementation of the @see read_for_sendfile functionality. 60 * 61 * This function will use the @see read function to get a block of memory, 62 * then return it as a header. No file will be returned. 63 */ 64apr_status_t serf_default_read_for_sendfile( 65 serf_bucket_t *bucket, 66 apr_size_t requested, 67 apr_hdtr_t *hdtr, 68 apr_file_t **file, 69 apr_off_t *offset, 70 apr_size_t *len); 71 72/** 73 * Default implementation of the @see read_bucket functionality. 74 * 75 * This function will always return NULL, indicating that the @a type 76 * of bucket cannot be found within @a bucket. 77 */ 78serf_bucket_t *serf_default_read_bucket( 79 serf_bucket_t *bucket, 80 const serf_bucket_type_t *type); 81 82/** 83 * Default implementation of the @see destroy functionality. 84 * 85 * This function will return the @a bucket to its allcoator. 86 */ 87void serf_default_destroy( 88 serf_bucket_t *bucket); 89 90 91/** 92 * Default implementation of the @see destroy functionality. 93 * 94 * This function will return the @a bucket, and the data member to its 95 * allocator. 96 */ 97void serf_default_destroy_and_data( 98 serf_bucket_t *bucket); 99 100 101/** 102 * Allocate @a size bytes of memory using @a allocator. 103 * 104 * Returns NULL of the requested memory size could not be allocated. 105 */ 106void *serf_bucket_mem_alloc( 107 serf_bucket_alloc_t *allocator, 108 apr_size_t size); 109 110/** 111 * Allocate @a size bytes of memory using @a allocator and set all of the 112 * memory to 0. 113 * 114 * Returns NULL of the requested memory size could not be allocated. 115 */ 116void *serf_bucket_mem_calloc( 117 serf_bucket_alloc_t *allocator, 118 apr_size_t size); 119 120/** 121 * Free the memory at @a block, returning it to @a allocator. 122 */ 123void serf_bucket_mem_free( 124 serf_bucket_alloc_t *allocator, 125 void *block); 126 127 128/** 129 * Analogous to apr_pstrmemdup, using a bucket allocator instead. 130 */ 131char *serf_bstrmemdup( 132 serf_bucket_alloc_t *allocator, 133 const char *str, 134 apr_size_t size); 135 136/** 137 * Analogous to apr_pmemdup, using a bucket allocator instead. 138 */ 139void * serf_bmemdup( 140 serf_bucket_alloc_t *allocator, 141 const void *mem, 142 apr_size_t size); 143 144/** 145 * Analogous to apr_pstrdup, using a bucket allocator instead. 146 */ 147char * serf_bstrdup( 148 serf_bucket_alloc_t *allocator, 149 const char *str); 150 151/** 152 * Analogous to apr_pstrcatv, using a bucket allocator instead. 153 */ 154char * serf_bstrcatv( 155 serf_bucket_alloc_t *allocator, 156 struct iovec *vec, 157 int vecs, 158 apr_size_t *bytes_written); 159 160/** 161 * Read data up to a newline. 162 * 163 * @a acceptable contains the allowed forms of a newline, and @a found 164 * will return the particular newline type that was found. If a newline 165 * is not found, then SERF_NEWLINE_NONE will be placed in @a found. 166 * 167 * @a data should contain a pointer to the data to be scanned. @a len 168 * should specify the length of that data buffer. On exit, @a data will 169 * be advanced past the newline, and @a len will specify the remaining 170 * amount of data in the buffer. 171 * 172 * Given this pattern of behavior, the caller should store the initial 173 * value of @a data as the line start. The difference between the 174 * returned value of @a data and the saved start is the length of the 175 * line. 176 * 177 * Note that the newline character(s) will remain within the buffer. 178 * This function scans at a byte level for the newline characters. Thus, 179 * the data buffer may contain NUL characters. As a corollary, this 180 * function only works on 8-bit character encodings. 181 * 182 * If the data is fully consumed (@a len gets set to zero) and a CR 183 * character is found at the end and the CRLF sequence is allowed, then 184 * this function may store SERF_NEWLINE_CRLF_SPLIT into @a found. The 185 * caller should take particular consideration for the CRLF sequence 186 * that may be split across data buffer boundaries. 187 */ 188void serf_util_readline( 189 const char **data, 190 apr_size_t *len, 191 int acceptable, 192 int *found); 193 194 195/** The buffer size used within @see serf_databuf_t. */ 196#define SERF_DATABUF_BUFSIZE 8000 197 198/** Callback function which is used to refill the data buffer. 199 * 200 * The function takes @a baton, which is the @see read_baton value 201 * from the serf_databuf_t structure. Data should be placed into 202 * a buffer specified by @a buf, which is @a bufsize bytes long. 203 * The amount of data read should be returned in @a len. 204 * 205 * APR_EOF should be returned if no more data is available. APR_EAGAIN 206 * should be returned, rather than blocking. In both cases, @a buf 207 * should be filled in and @a len set, as appropriate. 208 */ 209typedef apr_status_t (*serf_databuf_reader_t)( 210 void *baton, 211 apr_size_t bufsize, 212 char *buf, 213 apr_size_t *len); 214 215/** 216 * This structure is used as an intermediate data buffer for some "external" 217 * source of data. It works as a scratch pad area for incoming data to be 218 * stored, and then returned as a ptr/len pair by the bucket read functions. 219 * 220 * This structure should be initialized by calling @see serf_databuf_init. 221 * Users should not bother to zero the structure beforehand. 222 */ 223typedef struct { 224 /** The current data position within the buffer. */ 225 const char *current; 226 227 /** Amount of data remaining in the buffer. */ 228 apr_size_t remaining; 229 230 /** Callback function. */ 231 serf_databuf_reader_t read; 232 233 /** A baton to hold context-specific data. */ 234 void *read_baton; 235 236 /** Records the status from the last @see read operation. */ 237 apr_status_t status; 238 239 /** Holds the data until it can be returned. */ 240 char buf[SERF_DATABUF_BUFSIZE]; 241 242} serf_databuf_t; 243 244/** 245 * Initialize the @see serf_databuf_t structure specified by @a databuf. 246 */ 247void serf_databuf_init( 248 serf_databuf_t *databuf); 249 250/** 251 * Implement a bucket-style read function from the @see serf_databuf_t 252 * structure given by @a databuf. 253 * 254 * The @a requested, @a data, and @a len fields are interpreted and used 255 * as in the read function of @see serf_bucket_t. 256 */ 257apr_status_t serf_databuf_read( 258 serf_databuf_t *databuf, 259 apr_size_t requested, 260 const char **data, 261 apr_size_t *len); 262 263/** 264 * Implement a bucket-style readline function from the @see serf_databuf_t 265 * structure given by @a databuf. 266 * 267 * The @a acceptable, @a found, @a data, and @a len fields are interpreted 268 * and used as in the read function of @see serf_bucket_t. 269 */ 270apr_status_t serf_databuf_readline( 271 serf_databuf_t *databuf, 272 int acceptable, 273 int *found, 274 const char **data, 275 apr_size_t *len); 276 277/** 278 * Implement a bucket-style peek function from the @see serf_databuf_t 279 * structure given by @a databuf. 280 * 281 * The @a data, and @a len fields are interpreted and used as in the 282 * peek function of @see serf_bucket_t. 283 */ 284apr_status_t serf_databuf_peek( 285 serf_databuf_t *databuf, 286 const char **data, 287 apr_size_t *len); 288 289 290#ifdef __cplusplus 291} 292#endif 293 294#endif /* !SERF_BUCKET_UTIL_H */ 295