Apache Portable Runtime
|
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 * Add a key/value pair to a table. If another element already exists with the 00272 * same key, this will overwrite the old data. 00273 * @param t The table to add the data to. 00274 * @param key The key to use (case does not matter) 00275 * @param val The value to add 00276 * @remark When adding data, this function makes a copy of both the key and the 00277 * value. 00278 */ 00279 APR_DECLARE(void) apr_table_set(apr_table_t *t, const char *key, 00280 const char *val); 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 * @warning When adding data, this function does not make a copy of the key or 00289 * the value, so care should be taken to ensure that the values will 00290 * not change after they have been added.. 00291 */ 00292 APR_DECLARE(void) apr_table_setn(apr_table_t *t, const char *key, 00293 const char *val); 00294 00295 /** 00296 * Remove data from the table. 00297 * @param t The table to remove data from 00298 * @param key The key of the data being removed (case does not matter) 00299 */ 00300 APR_DECLARE(void) apr_table_unset(apr_table_t *t, const char *key); 00301 00302 /** 00303 * Add data to a table by merging the value with data that has already been 00304 * stored. The merging is done by concatenating the two values, separated 00305 * by the string ", ". 00306 * @param t The table to search for the data 00307 * @param key The key to merge data for (case does not matter) 00308 * @param val The data to add 00309 * @remark If the key is not found, then this function acts like apr_table_add 00310 */ 00311 APR_DECLARE(void) apr_table_merge(apr_table_t *t, const char *key, 00312 const char *val); 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_addn 00322 */ 00323 APR_DECLARE(void) apr_table_mergen(apr_table_t *t, const char *key, 00324 const char *val); 00325 00326 /** 00327 * Add data to a table, regardless of whether there is another element with the 00328 * same key. 00329 * @param t The table to add to 00330 * @param key The key to use 00331 * @param val The value to add. 00332 * @remark When adding data, this function makes a copy of both the key and the 00333 * value. 00334 */ 00335 APR_DECLARE(void) apr_table_add(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 does not make a copy of the key or the 00345 * value, so care should be taken to ensure that the values will not 00346 * change after they have been added. 00347 */ 00348 APR_DECLARE(void) apr_table_addn(apr_table_t *t, const char *key, 00349 const char *val); 00350 00351 /** 00352 * Merge two tables into one new table. 00353 * @param p The pool to use for the new table 00354 * @param overlay The first table to put in the new table 00355 * @param base The table to add at the end of the new table 00356 * @return A new table containing all of the data from the two passed in 00357 */ 00358 APR_DECLARE(apr_table_t *) apr_table_overlay(apr_pool_t *p, 00359 const apr_table_t *overlay, 00360 const apr_table_t *base); 00361 00362 /** 00363 * Declaration prototype for the iterator callback function of apr_table_do() 00364 * and apr_table_vdo(). 00365 * @param rec The data passed as the first argument to apr_table_[v]do() 00366 * @param key The key from this iteration of the table 00367 * @param value The value from this iteration of the table 00368 * @remark Iteration continues while this callback function returns non-zero. 00369 * To export the callback function for apr_table_[v]do() it must be declared 00370 * in the _NONSTD convention. 00371 */ 00372 typedef int (apr_table_do_callback_fn_t)(void *rec, const char *key, 00373 const char *value); 00374 00375 /** 00376 * Iterate over a table running the provided function once for every 00377 * element in the table. The varargs array must be a list of zero or 00378 * more (char *) keys followed by a NULL pointer. If zero keys are 00379 * given, the @param comp function will be invoked for every element 00380 * in the table. Otherwise, the function is invoked only for those 00381 * elements matching the keys specified. 00382 * 00383 * If an invocation of the @param comp function returns zero, 00384 * iteration will continue using the next specified key, if any. 00385 * 00386 * @param comp The function to run 00387 * @param rec The data to pass as the first argument to the function 00388 * @param t The table to iterate over 00389 * @param ... A varargs array of zero or more (char *) keys followed by NULL 00390 * @return FALSE if one of the comp() iterations returned zero; TRUE if all 00391 * iterations returned non-zero 00392 * @see apr_table_do_callback_fn_t 00393 */ 00394 APR_DECLARE_NONSTD(int) apr_table_do(apr_table_do_callback_fn_t *comp, 00395 void *rec, const apr_table_t *t, ...) 00396 #if defined(__GNUC__) && __GNUC__ >= 4 00397 __attribute__((sentinel)) 00398 #endif 00399 ; 00400 00401 /** 00402 * Iterate over a table running the provided function once for every 00403 * element in the table. The @param vp varargs parameter must be a 00404 * list of zero or more (char *) keys followed by a NULL pointer. If 00405 * zero keys are given, the @param comp function will be invoked for 00406 * every element in the table. Otherwise, the function is invoked 00407 * only for those elements matching the keys specified. 00408 * 00409 * If an invocation of the @param comp function returns zero, 00410 * iteration will continue using the next specified key, if any. 00411 * 00412 * @param comp The function to run 00413 * @param rec The data to pass as the first argument to the function 00414 * @param t The table to iterate over 00415 * @param vp List of zero or more (char *) keys followed by NULL 00416 * @return FALSE if one of the comp() iterations returned zero; TRUE if all 00417 * iterations returned non-zero 00418 * @see apr_table_do_callback_fn_t 00419 */ 00420 APR_DECLARE(int) apr_table_vdo(apr_table_do_callback_fn_t *comp, 00421 void *rec, const apr_table_t *t, va_list vp); 00422 00423 /** flag for overlap to use apr_table_setn */ 00424 #define APR_OVERLAP_TABLES_SET (0) 00425 /** flag for overlap to use apr_table_mergen */ 00426 #define APR_OVERLAP_TABLES_MERGE (1) 00427 /** 00428 * For each element in table b, either use setn or mergen to add the data 00429 * to table a. Which method is used is determined by the flags passed in. 00430 * @param a The table to add the data to. 00431 * @param b The table to iterate over, adding its data to table a 00432 * @param flags How to add the table to table a. One of: 00433 * APR_OVERLAP_TABLES_SET Use apr_table_setn 00434 * APR_OVERLAP_TABLES_MERGE Use apr_table_mergen 00435 * @remark When merging duplicates, the two values are concatenated, 00436 * separated by the string ", ". 00437 * @remark This function is highly optimized, and uses less memory and CPU cycles 00438 * than a function that just loops through table b calling other functions. 00439 */ 00440 /** 00441 * Conceptually, apr_table_overlap does this: 00442 * 00443 * <pre> 00444 * apr_array_header_t *barr = apr_table_elts(b); 00445 * apr_table_entry_t *belt = (apr_table_entry_t *)barr->elts; 00446 * int i; 00447 * 00448 * for (i = 0; i < barr->nelts; ++i) { 00449 * if (flags & APR_OVERLAP_TABLES_MERGE) { 00450 * apr_table_mergen(a, belt[i].key, belt[i].val); 00451 * } 00452 * else { 00453 * apr_table_setn(a, belt[i].key, belt[i].val); 00454 * } 00455 * } 00456 * </pre> 00457 * 00458 * Except that it is more efficient (less space and cpu-time) especially 00459 * when b has many elements. 00460 * 00461 * Notice the assumptions on the keys and values in b -- they must be 00462 * in an ancestor of a's pool. In practice b and a are usually from 00463 * the same pool. 00464 */ 00465 00466 APR_DECLARE(void) apr_table_overlap(apr_table_t *a, const apr_table_t *b, 00467 unsigned flags); 00468 00469 /** 00470 * Eliminate redundant entries in a table by either overwriting 00471 * or merging duplicates. 00472 * 00473 * @param t Table. 00474 * @param flags APR_OVERLAP_TABLES_MERGE to merge, or 00475 * APR_OVERLAP_TABLES_SET to overwrite 00476 * @remark When merging duplicates, the two values are concatenated, 00477 * separated by the string ", ". 00478 */ 00479 APR_DECLARE(void) apr_table_compress(apr_table_t *t, unsigned flags); 00480 00481 /** @} */ 00482 00483 #ifdef __cplusplus 00484 } 00485 #endif 00486 00487 #endif /* ! APR_TABLES_H */