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