00001 /* Licensed to the Apache Software Foundation (ASF) under one or more 00002 * contributor license agreements. See the NOTICE file distributed with 00003 * this work for additional information regarding copyright ownership. 00004 * The ASF licenses this file to You under the Apache License, Version 2.0 00005 * (the "License"); you may not use this file except in compliance with 00006 * the License. You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #ifndef APR_TABLES_H 00018 #define APR_TABLES_H 00019 00020 /** 00021 * @file apr_tables.h 00022 * @brief APR Table library 00023 */ 00024 00025 #include "apr.h" 00026 #include "apr_pools.h" 00027 00028 #if APR_HAVE_STDARG_H 00029 #include <stdarg.h> /* for va_list */ 00030 #endif 00031 00032 #ifdef __cplusplus 00033 extern "C" { 00034 #endif /* __cplusplus */ 00035 00036 /** 00037 * @defgroup apr_tables Table and Array Functions 00038 * @ingroup APR 00039 * Arrays are used to store data which is referenced sequentially or 00040 * as a stack. Functions are provided to push and pop individual 00041 * elements as well as to operate on the entire array. 00042 * 00043 * Tables are used to store data which can be referenced by key. 00044 * Limited capabilities are provided for tables with multiple elements 00045 * which share a key; while key lookup will return only a single 00046 * element, iteration is available. Additionally, a table can be 00047 * compressed to resolve duplicates. 00048 * 00049 * Both arrays and tables may store string or binary data; some features, 00050 * such as concatenation or merging of elements, work only for string 00051 * data. 00052 * @{ 00053 */ 00054 00055 /** the table abstract data type */ 00056 typedef struct apr_table_t apr_table_t; 00057 00058 /** @see apr_array_header_t */ 00059 typedef struct apr_array_header_t apr_array_header_t; 00060 00061 /** An opaque array type */ 00062 struct apr_array_header_t { 00063 /** The pool the array is allocated out of */ 00064 apr_pool_t *pool; 00065 /** The amount of memory allocated for each element of the array */ 00066 int elt_size; 00067 /** The number of active elements in the array */ 00068 int nelts; 00069 /** The number of elements allocated in the array */ 00070 int nalloc; 00071 /** The elements in the array */ 00072 char *elts; 00073 }; 00074 00075 /** 00076 * The (opaque) structure for string-content tables. 00077 */ 00078 typedef struct apr_table_entry_t apr_table_entry_t; 00079 00080 /** The type for each entry in a string-content table */ 00081 struct apr_table_entry_t { 00082 /** The key for the current table entry */ 00083 char *key; /* maybe NULL in future; 00084 * check when iterating thru table_elts 00085 */ 00086 /** The value for the current table entry */ 00087 char *val; 00088 00089 /** A checksum for the key, for use by the apr_table internals */ 00090 apr_uint32_t key_checksum; 00091 }; 00092 00093 /** 00094 * Get the elements from a table. 00095 * @param t The table 00096 * @return An array containing the contents of the table 00097 */ 00098 APR_DECLARE(const apr_array_header_t *) apr_table_elts(const apr_table_t *t); 00099 00100 /** 00101 * Determine if the table is empty (either NULL or having no elements). 00102 * @param t The table to check 00103 * @return True if empty, False otherwise 00104 */ 00105 APR_DECLARE(int) apr_is_empty_table(const apr_table_t *t); 00106 00107 /** 00108 * Determine if the array is empty (either NULL or having no elements). 00109 * @param a The array to check 00110 * @return True if empty, False otherwise 00111 */ 00112 APR_DECLARE(int) apr_is_empty_array(const apr_array_header_t *a); 00113 00114 /** 00115 * Create an array. 00116 * @param p The pool to allocate the memory out of 00117 * @param nelts the number of elements in the initial array 00118 * @param elt_size The size of each element in the array. 00119 * @return The new array 00120 */ 00121 APR_DECLARE(apr_array_header_t *) apr_array_make(apr_pool_t *p, 00122 int nelts, int elt_size); 00123 00124 /** 00125 * Add a new element to an array (as a first-in, last-out stack). 00126 * @param arr The array to add an element to. 00127 * @return Location for the new element in the array. 00128 * @remark If there are no free spots in the array, then this function will 00129 * allocate new space for the new element. 00130 */ 00131 APR_DECLARE(void *) apr_array_push(apr_array_header_t *arr); 00132 00133 /** A helper macro for accessing a member of an APR array. 00134 * 00135 * @param ary the array 00136 * @param i the index into the array to return 00137 * @param type the type of the objects stored in the array 00138 * 00139 * @return the item at index i 00140 */ 00141 #define APR_ARRAY_IDX(ary,i,type) (((type *)(ary)->elts)[i]) 00142 00143 /** A helper macro for pushing elements into an APR array. 00144 * 00145 * @param ary the array 00146 * @param type the type of the objects stored in the array 00147 * 00148 * @return the location where the new object should be placed 00149 */ 00150 #define APR_ARRAY_PUSH(ary,type) (*((type *)apr_array_push(ary))) 00151 00152 /** 00153 * Remove an element from an array (as a first-in, last-out stack). 00154 * @param arr The array to remove an element from. 00155 * @return Location of the element in the array. 00156 * @remark If there are no elements in the array, NULL is returned. 00157 */ 00158 APR_DECLARE(void *) apr_array_pop(apr_array_header_t *arr); 00159 00160 /** 00161 * Remove all elements from an array. 00162 * @param arr The array to remove all elements from. 00163 * @remark As the underlying storage is allocated from a pool, no 00164 * memory is freed by this operation, but is available for reuse. 00165 */ 00166 APR_DECLARE(void) apr_array_clear(apr_array_header_t *arr); 00167 00168 /** 00169 * Concatenate two arrays together. 00170 * @param dst The destination array, and the one to go first in the combined 00171 * array 00172 * @param src The source array to add to the destination array 00173 */ 00174 APR_DECLARE(void) apr_array_cat(apr_array_header_t *dst, 00175 const apr_array_header_t *src); 00176 00177 /** 00178 * Copy the entire array. 00179 * @param p The pool to allocate the copy of the array out of 00180 * @param arr The array to copy 00181 * @return An exact copy of the array passed in 00182 * @remark The alternate apr_array_copy_hdr copies only the header, and arranges 00183 * for the elements to be copied if (and only if) the code subsequently 00184 * does a push or arraycat. 00185 */ 00186 APR_DECLARE(apr_array_header_t *) apr_array_copy(apr_pool_t *p, 00187 const apr_array_header_t *arr); 00188 /** 00189 * Copy the headers of the array, and arrange for the elements to be copied if 00190 * and only if the code subsequently does a push or arraycat. 00191 * @param p The pool to allocate the copy of the array out of 00192 * @param arr The array to copy 00193 * @return An exact copy of the array passed in 00194 * @remark The alternate apr_array_copy copies the *entire* array. 00195 */ 00196 APR_DECLARE(apr_array_header_t *) apr_array_copy_hdr(apr_pool_t *p, 00197 const apr_array_header_t *arr); 00198 00199 /** 00200 * Append one array to the end of another, creating a new array in the process. 00201 * @param p The pool to allocate the new array out of 00202 * @param first The array to put first in the new array. 00203 * @param second The array to put second in the new array. 00204 * @return A new array containing the data from the two arrays passed in. 00205 */ 00206 APR_DECLARE(apr_array_header_t *) apr_array_append(apr_pool_t *p, 00207 const apr_array_header_t *first, 00208 const apr_array_header_t *second); 00209 00210 /** 00211 * Generate a new string from the apr_pool_t containing the concatenated 00212 * sequence of substrings referenced as elements within the array. The string 00213 * will be empty if all substrings are empty or null, or if there are no 00214 * elements in the array. If sep is non-NUL, it will be inserted between 00215 * elements as a separator. 00216 * @param p The pool to allocate the string out of 00217 * @param arr The array to generate the string from 00218 * @param sep The separator to use 00219 * @return A string containing all of the data in the array. 00220 */ 00221 APR_DECLARE(char *) apr_array_pstrcat(apr_pool_t *p, 00222 const apr_array_header_t *arr, 00223 const char sep); 00224 00225 /** 00226 * Make a new table. 00227 * @param p The pool to allocate the pool out of 00228 * @param nelts The number of elements in the initial table. 00229 * @return The new table. 00230 * @warning This table can only store text data 00231 */ 00232 APR_DECLARE(apr_table_t *) apr_table_make(apr_pool_t *p, int nelts); 00233 00234 /** 00235 * Create a new table and copy another table into it. 00236 * @param p The pool to allocate the new table out of 00237 * @param t The table to copy 00238 * @return A copy of the table passed in 00239 * @warning The table keys and respective values are not copied 00240 */ 00241 APR_DECLARE(apr_table_t *) apr_table_copy(apr_pool_t *p, 00242 const apr_table_t *t); 00243 00244 /** 00245 * Create a new table whose contents are deep copied from the given 00246 * table. A deep copy operation copies all fields, and makes copies 00247 * of dynamically allocated memory pointed to by the fields. 00248 * @param p The pool to allocate the new table out of 00249 * @param t The table to clone 00250 * @return A deep copy of the table passed in 00251 */ 00252 APR_DECLARE(apr_table_t *) apr_table_clone(apr_pool_t *p, 00253 const apr_table_t *t); 00254 00255 /** 00256 * Delete all of the elements from a table. 00257 * @param t The table to clear 00258 */ 00259 APR_DECLARE(void) apr_table_clear(apr_table_t *t); 00260 00261 /** 00262 * Get the value associated with a given key from the table. After this call, 00263 * the data is still in the table. 00264 * @param t The table to search for the key 00265 * @param key The key to search for (case does not matter) 00266 * @return The value associated with the key, or NULL if the key does not exist. 00267 */ 00268 APR_DECLARE(const char *) apr_table_get(const apr_table_t *t, const char *key); 00269 00270 /** 00271 * Get values associated with a given key from the table. If more than one 00272 * value exists, return a comma separated list of values. After this call, the 00273 * data is still in the table. 00274 * @param p The pool to allocate the combined value from, if necessary 00275 * @param t The table to search for the key 00276 * @param key The key to search for (case does not matter) 00277 * @return The value associated with the key, or NULL if the key does not exist. 00278 */ 00279 APR_DECLARE(const char *) apr_table_getm(apr_pool_t *p, const apr_table_t *t, 00280 const char *key); 00281 00282 /** 00283 * Add a key/value pair to a table. If another element already exists with the 00284 * same key, this will overwrite the old data. 00285 * @param t The table to add the data to. 00286 * @param key The key to use (case does not matter) 00287 * @param val The value to add 00288 * @remark When adding data, this function makes a copy of both the key and the 00289 * value. 00290 */ 00291 APR_DECLARE(void) apr_table_set(apr_table_t *t, const char *key, 00292 const char *val); 00293 00294 /** 00295 * Add a key/value pair to a table. If another element already exists with the 00296 * same key, this will overwrite the old data. 00297 * @param t The table to add the data to. 00298 * @param key The key to use (case does not matter) 00299 * @param val The value to add 00300 * @warning When adding data, this function does not make a copy of the key or 00301 * the value, so care should be taken to ensure that the values will 00302 * not change after they have been added.. 00303 */ 00304 APR_DECLARE(void) apr_table_setn(apr_table_t *t, const char *key, 00305 const char *val); 00306 00307 /** 00308 * Remove data from the table. 00309 * @param t The table to remove data from 00310 * @param key The key of the data being removed (case does not matter) 00311 */ 00312 APR_DECLARE(void) apr_table_unset(apr_table_t *t, const char *key); 00313 00314 /** 00315 * Add data to a table by merging the value with data that has already been 00316 * stored. The merging is done by concatenating the two values, separated 00317 * by the string ", ". 00318 * @param t The table to search for the data 00319 * @param key The key to merge data for (case does not matter) 00320 * @param val The data to add 00321 * @remark If the key is not found, then this function acts like apr_table_add 00322 */ 00323 APR_DECLARE(void) apr_table_merge(apr_table_t *t, const char *key, 00324 const char *val); 00325 00326 /** 00327 * Add data to a table by merging the value with data that has already been 00328 * stored. The merging is done by concatenating the two values, separated 00329 * by the string ", ". 00330 * @param t The table to search for the data 00331 * @param key The key to merge data for (case does not matter) 00332 * @param val The data to add 00333 * @remark If the key is not found, then this function acts like apr_table_addn 00334 */ 00335 APR_DECLARE(void) apr_table_mergen(apr_table_t *t, const char *key, 00336 const char *val); 00337 00338 /** 00339 * Add data to a table, regardless of whether there is another element with the 00340 * same key. 00341 * @param t The table to add to 00342 * @param key The key to use 00343 * @param val The value to add. 00344 * @remark When adding data, this function makes a copy of both the key and the 00345 * value. 00346 */ 00347 APR_DECLARE(void) apr_table_add(apr_table_t *t, const char *key, 00348 const char *val); 00349 00350 /** 00351 * Add data to a table, regardless of whether there is another element with the 00352 * same key. 00353 * @param t The table to add to 00354 * @param key The key to use 00355 * @param val The value to add. 00356 * @remark When adding data, this function does not make a copy of the key or the 00357 * value, so care should be taken to ensure that the values will not 00358 * change after they have been added. 00359 */ 00360 APR_DECLARE(void) apr_table_addn(apr_table_t *t, const char *key, 00361 const char *val); 00362 00363 /** 00364 * Merge two tables into one new table. 00365 * @param p The pool to use for the new table 00366 * @param overlay The first table to put in the new table 00367 * @param base The table to add at the end of the new table 00368 * @return A new table containing all of the data from the two passed in 00369 */ 00370 APR_DECLARE(apr_table_t *) apr_table_overlay(apr_pool_t *p, 00371 const apr_table_t *overlay, 00372 const apr_table_t *base); 00373 00374 /** 00375 * Declaration prototype for the iterator callback function of apr_table_do() 00376 * and apr_table_vdo(). 00377 * @param rec The data passed as the first argument to apr_table_[v]do() 00378 * @param key The key from this iteration of the table 00379 * @param value The value from this iteration of the table 00380 * @remark Iteration continues while this callback function returns non-zero. 00381 * To export the callback function for apr_table_[v]do() it must be declared 00382 * in the _NONSTD convention. 00383 */ 00384 typedef int (apr_table_do_callback_fn_t)(void *rec, const char *key, 00385 const char *value); 00386 00387 /** 00388 * Iterate over a table running the provided function once for every 00389 * element in the table. The varargs array must be a list of zero or 00390 * more (char *) keys followed by a NULL pointer. If zero keys are 00391 * given, the @param comp function will be invoked for every element 00392 * in the table. Otherwise, the function is invoked only for those 00393 * elements matching the keys specified. 00394 * 00395 * If an invocation of the @param comp function returns zero, 00396 * iteration will continue using the next specified key, if any. 00397 * 00398 * @param comp The function to run 00399 * @param rec The data to pass as the first argument to the function 00400 * @param t The table to iterate over 00401 * @param ... A varargs array of zero or more (char *) keys followed by NULL 00402 * @return FALSE if one of the comp() iterations returned zero; TRUE if all 00403 * iterations returned non-zero 00404 * @see apr_table_do_callback_fn_t 00405 */ 00406 APR_DECLARE_NONSTD(int) apr_table_do(apr_table_do_callback_fn_t *comp, 00407 void *rec, const apr_table_t *t, ...) 00408 #if defined(__GNUC__) && __GNUC__ >= 4 00409 __attribute__((sentinel)) 00410 #endif 00411 ; 00412 00413 /** 00414 * Iterate over a table running the provided function once for every 00415 * element in the table. The @param vp varargs parameter must be a 00416 * list of zero or more (char *) keys followed by a NULL pointer. If 00417 * zero keys are given, the @param comp function will be invoked for 00418 * every element in the table. Otherwise, the function is invoked 00419 * only for those elements matching the keys specified. 00420 * 00421 * If an invocation of the @param comp function returns zero, 00422 * iteration will continue using the next specified key, if any. 00423 * 00424 * @param comp The function to run 00425 * @param rec The data to pass as the first argument to the function 00426 * @param t The table to iterate over 00427 * @param vp List of zero or more (char *) keys followed by NULL 00428 * @return FALSE if one of the comp() iterations returned zero; TRUE if all 00429 * iterations returned non-zero 00430 * @see apr_table_do_callback_fn_t 00431 */ 00432 APR_DECLARE(int) apr_table_vdo(apr_table_do_callback_fn_t *comp, 00433 void *rec, const apr_table_t *t, va_list vp); 00434 00435 /** flag for overlap to use apr_table_setn */ 00436 #define APR_OVERLAP_TABLES_SET (0) 00437 /** flag for overlap to use apr_table_mergen */ 00438 #define APR_OVERLAP_TABLES_MERGE (1) 00439 /** 00440 * For each element in table b, either use setn or mergen to add the data 00441 * to table a. Which method is used is determined by the flags passed in. 00442 * @param a The table to add the data to. 00443 * @param b The table to iterate over, adding its data to table a 00444 * @param flags How to add the table to table a. One of: 00445 * APR_OVERLAP_TABLES_SET Use apr_table_setn 00446 * APR_OVERLAP_TABLES_MERGE Use apr_table_mergen 00447 * @remark When merging duplicates, the two values are concatenated, 00448 * separated by the string ", ". 00449 * @remark This function is highly optimized, and uses less memory and CPU cycles 00450 * than a function that just loops through table b calling other functions. 00451 */ 00452 /** 00453 * Conceptually, apr_table_overlap does this: 00454 * 00455 * <pre> 00456 * apr_array_header_t *barr = apr_table_elts(b); 00457 * apr_table_entry_t *belt = (apr_table_entry_t *)barr->elts; 00458 * int i; 00459 * 00460 * for (i = 0; i < barr->nelts; ++i) { 00461 * if (flags & APR_OVERLAP_TABLES_MERGE) { 00462 * apr_table_mergen(a, belt[i].key, belt[i].val); 00463 * } 00464 * else { 00465 * apr_table_setn(a, belt[i].key, belt[i].val); 00466 * } 00467 * } 00468 * </pre> 00469 * 00470 * Except that it is more efficient (less space and cpu-time) especially 00471 * when b has many elements. 00472 * 00473 * Notice the assumptions on the keys and values in b -- they must be 00474 * in an ancestor of a's pool. In practice b and a are usually from 00475 * the same pool. 00476 */ 00477 00478 APR_DECLARE(void) apr_table_overlap(apr_table_t *a, const apr_table_t *b, 00479 unsigned flags); 00480 00481 /** 00482 * Eliminate redundant entries in a table by either overwriting 00483 * or merging duplicates. 00484 * 00485 * @param t Table. 00486 * @param flags APR_OVERLAP_TABLES_MERGE to merge, or 00487 * APR_OVERLAP_TABLES_SET to overwrite 00488 * @remark When merging duplicates, the two values are concatenated, 00489 * separated by the string ", ". 00490 */ 00491 APR_DECLARE(void) apr_table_compress(apr_table_t *t, unsigned flags); 00492 00493 /** @} */ 00494 00495 #ifdef __cplusplus 00496 } 00497 #endif 00498 00499 #endif /* ! APR_TABLES_H */