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