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 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 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 /** 00124 * Remove an element from an array (as a first-in, last-out stack) 00125 * @param arr The array to remove an element from. 00126 * @return Location of the element in the array. 00127 * @remark If there are no elements in the array, NULL is returned. 00128 */ 00129 APR_DECLARE(void *) apr_array_pop(apr_array_header_t *arr); 00130 00131 /** 00132 * Concatenate two arrays together 00133 * @param dst The destination array, and the one to go first in the combined 00134 * array 00135 * @param src The source array to add to the destination array 00136 */ 00137 APR_DECLARE(void) apr_array_cat(apr_array_header_t *dst, 00138 const apr_array_header_t *src); 00139 00140 /** 00141 * Copy the entire array 00142 * @param p The pool to allocate the copy of the array out of 00143 * @param arr The array to copy 00144 * @return An exact copy of the array passed in 00145 * @remark The alternate apr_array_copy_hdr copies only the header, and arranges 00146 * for the elements to be copied if (and only if) the code subsequently 00147 * does a push or arraycat. 00148 */ 00149 APR_DECLARE(apr_array_header_t *) apr_array_copy(apr_pool_t *p, 00150 const apr_array_header_t *arr); 00151 /** 00152 * Copy the headers of the array, and arrange for the elements to be copied if 00153 * and only if the code subsequently does a push or arraycat. 00154 * @param p The pool to allocate the copy of the array out of 00155 * @param arr The array to copy 00156 * @return An exact copy of the array passed in 00157 * @remark The alternate apr_array_copy copies the *entire* array. 00158 */ 00159 APR_DECLARE(apr_array_header_t *) apr_array_copy_hdr(apr_pool_t *p, 00160 const apr_array_header_t *arr); 00161 00162 /** 00163 * Append one array to the end of another, creating a new array in the process. 00164 * @param p The pool to allocate the new array out of 00165 * @param first The array to put first in the new array. 00166 * @param second The array to put second in the new array. 00167 * @return A new array containing the data from the two arrays passed in. 00168 */ 00169 APR_DECLARE(apr_array_header_t *) apr_array_append(apr_pool_t *p, 00170 const apr_array_header_t *first, 00171 const apr_array_header_t *second); 00172 00173 /** 00174 * Generates a new string from the apr_pool_t containing the concatenated 00175 * sequence of substrings referenced as elements within the array. The string 00176 * will be empty if all substrings are empty or null, or if there are no 00177 * elements in the array. If sep is non-NUL, it will be inserted between 00178 * elements as a separator. 00179 * @param p The pool to allocate the string out of 00180 * @param arr The array to generate the string from 00181 * @param sep The separator to use 00182 * @return A string containing all of the data in the array. 00183 */ 00184 APR_DECLARE(char *) apr_array_pstrcat(apr_pool_t *p, 00185 const apr_array_header_t *arr, 00186 const char sep); 00187 00188 /** 00189 * Make a new table 00190 * @param p The pool to allocate the pool out of 00191 * @param nelts The number of elements in the initial table. 00192 * @return The new table. 00193 * @warning This table can only store text data 00194 */ 00195 APR_DECLARE(apr_table_t *) apr_table_make(apr_pool_t *p, int nelts); 00196 00197 /** 00198 * Create a new table and copy another table into it 00199 * @param p The pool to allocate the new table out of 00200 * @param t The table to copy 00201 * @return A copy of the table passed in 00202 */ 00203 APR_DECLARE(apr_table_t *) apr_table_copy(apr_pool_t *p, 00204 const apr_table_t *t); 00205 00206 /** 00207 * Delete all of the elements from a table 00208 * @param t The table to clear 00209 */ 00210 APR_DECLARE(void) apr_table_clear(apr_table_t *t); 00211 00212 /** 00213 * Get the value associated with a given key from the table. After this call, 00214 * The data is still in the table 00215 * @param t The table to search for the key 00216 * @param key The key to search for 00217 * @return The value associated with the key, or NULL if the key does not exist. 00218 */ 00219 APR_DECLARE(const char *) apr_table_get(const apr_table_t *t, const char *key); 00220 00221 /** 00222 * Add a key/value pair to a table, if another element already exists with the 00223 * same key, this will over-write the old data. 00224 * @param t The table to add the data to. 00225 * @param key The key fo use 00226 * @param val The value to add 00227 * @remark When adding data, this function makes a copy of both the key and the 00228 * value. 00229 */ 00230 APR_DECLARE(void) apr_table_set(apr_table_t *t, const char *key, 00231 const char *val); 00232 00233 /** 00234 * Add a key/value pair to a table, if another element already exists with the 00235 * same key, this will over-write the old data. 00236 * @param t The table to add the data to. 00237 * @param key The key to use 00238 * @param val The value to add 00239 * @warning When adding data, this function does not make a copy of the key or 00240 * the value, so care should be taken to ensure that the values will 00241 * not change after they have been added.. 00242 */ 00243 APR_DECLARE(void) apr_table_setn(apr_table_t *t, const char *key, 00244 const char *val); 00245 00246 /** 00247 * Remove data from the table 00248 * @param t The table to remove data from 00249 * @param key The key of the data being removed 00250 */ 00251 APR_DECLARE(void) apr_table_unset(apr_table_t *t, const char *key); 00252 00253 /** 00254 * Add data to a table by merging the value with data that has already been 00255 * stored 00256 * @param t The table to search for the data 00257 * @param key The key to merge data for 00258 * @param val The data to add 00259 * @remark If the key is not found, then this function acts like apr_table_add 00260 */ 00261 APR_DECLARE(void) apr_table_merge(apr_table_t *t, const char *key, 00262 const char *val); 00263 00264 /** 00265 * Add data to a table by merging the value with data that has already been 00266 * stored 00267 * @param t The table to search for the data 00268 * @param key The key to merge data for 00269 * @param val The data to add 00270 * @remark If the key is not found, then this function acts like apr_table_addn 00271 */ 00272 APR_DECLARE(void) apr_table_mergen(apr_table_t *t, const char *key, 00273 const char *val); 00274 00275 /** 00276 * Add data to a table, regardless of whether there is another element with the 00277 * same key. 00278 * @param t The table to add to 00279 * @param key The key to use 00280 * @param val The value to add. 00281 * @remark When adding data, this function makes a copy of both the key and the 00282 * value. 00283 */ 00284 APR_DECLARE(void) apr_table_add(apr_table_t *t, const char *key, 00285 const char *val); 00286 00287 /** 00288 * Add data to a table, regardless of whether there is another element with the 00289 * same key. 00290 * @param t The table to add to 00291 * @param key The key to use 00292 * @param val The value to add. 00293 * @remark When adding data, this function does not make a copy of the key or the 00294 * value, so care should be taken to ensure that the values will not 00295 * change after they have been added.. 00296 */ 00297 APR_DECLARE(void) apr_table_addn(apr_table_t *t, const char *key, 00298 const char *val); 00299 00300 /** 00301 * Merge two tables into one new table 00302 * @param p The pool to use for the new table 00303 * @param overlay The first table to put in the new table 00304 * @param base The table to add at the end of the new table 00305 * @return A new table containing all of the data from the two passed in 00306 */ 00307 APR_DECLARE(apr_table_t *) apr_table_overlay(apr_pool_t *p, 00308 const apr_table_t *overlay, 00309 const apr_table_t *base); 00310 00311 /** 00312 * Declaration prototype for the iterator callback function of apr_table_do() 00313 * and apr_table_vdo(). 00314 * @param rec The data passed as the first argument to apr_table_[v]do() 00315 * @param key The key from this iteration of the table 00316 * @param value The value from this iteration of the table 00317 * @remark Iteration continues while this callback function returns non-zero. 00318 * To export the callback function for apr_table_[v]do() it must be declared 00319 * in the _NONSTD convention. 00320 */ 00321 typedef int (apr_table_do_callback_fn_t)(void *rec, const char *key, 00322 const char *value); 00323 00324 /** 00325 * Iterate over a table running the provided function once for every 00326 * element in the table. If there is data passed in as a vararg, then the 00327 * function is only run on those elements whose key matches something in 00328 * the vararg. If the vararg is NULL, then every element is run through the 00329 * function. Iteration continues while the function returns non-zero. 00330 * @param comp The function to run 00331 * @param rec The data to pass as the first argument to the function 00332 * @param t The table to iterate over 00333 * @param ... The vararg. If this is NULL, then all elements in the table are 00334 * run through the function, otherwise only those whose key matches 00335 * are run. 00336 * @return FALSE if one of the comp() iterations returned zero; TRUE if all 00337 * iterations returned non-zero 00338 * @see apr_table_do_callback_fn_t 00339 */ 00340 APR_DECLARE_NONSTD(int) apr_table_do(apr_table_do_callback_fn_t *comp, 00341 void *rec, const apr_table_t *t, ...); 00342 00343 /** 00344 * Iterate over a table running the provided function once for every 00345 * element in the table. If there is data passed in as a vararg, then the 00346 * function is only run on those element's whose key matches something in 00347 * the vararg. If the vararg is NULL, then every element is run through the 00348 * function. Iteration continues while the function returns non-zero. 00349 * @param comp The function to run 00350 * @param rec The data to pass as the first argument to the function 00351 * @param t The table to iterate over 00352 * @param vp The vararg table. If this is NULL, then all elements in the 00353 * table are run through the function, otherwise only those 00354 * whose key matches are run. 00355 * @return FALSE if one of the comp() iterations returned zero; TRUE if all 00356 * iterations returned non-zero 00357 * @see apr_table_do_callback_fn_t 00358 */ 00359 APR_DECLARE(int) apr_table_vdo(apr_table_do_callback_fn_t *comp, 00360 void *rec, const apr_table_t *t, va_list vp); 00361 00362 /** flag for overlap to use apr_table_setn */ 00363 #define APR_OVERLAP_TABLES_SET (0) 00364 /** flag for overlap to use apr_table_mergen */ 00365 #define APR_OVERLAP_TABLES_MERGE (1) 00366 /** 00367 * For each element in table b, either use setn or mergen to add the data 00368 * to table a. Which method is used is determined by the flags passed in. 00369 * @param a The table to add the data to. 00370 * @param b The table to iterate over, adding its data to table a 00371 * @param flags How to add the table to table a. One of: 00372 * APR_OVERLAP_TABLES_SET Use apr_table_setn 00373 * APR_OVERLAP_TABLES_MERGE Use apr_table_mergen 00374 * @remark This function is highly optimized, and uses less memory and CPU cycles 00375 * than a function that just loops through table b calling other functions. 00376 */ 00377 /** 00378 *<PRE> 00379 * Conceptually, apr_table_overlap does this: 00380 * 00381 * apr_array_header_t *barr = apr_table_elts(b); 00382 * apr_table_entry_t *belt = (apr_table_entry_t *)barr->elts; 00383 * int i; 00384 * 00385 * for (i = 0; i < barr->nelts; ++i) { 00386 * if (flags & APR_OVERLAP_TABLES_MERGE) { 00387 * apr_table_mergen(a, belt[i].key, belt[i].val); 00388 * } 00389 * else { 00390 * apr_table_setn(a, belt[i].key, belt[i].val); 00391 * } 00392 * } 00393 * 00394 * Except that it is more efficient (less space and cpu-time) especially 00395 * when b has many elements. 00396 * 00397 * Notice the assumptions on the keys and values in b -- they must be 00398 * in an ancestor of a's pool. In practice b and a are usually from 00399 * the same pool. 00400 * </PRE> 00401 */ 00402 00403 APR_DECLARE(void) apr_table_overlap(apr_table_t *a, const apr_table_t *b, 00404 unsigned flags); 00405 00406 /** 00407 * Eliminate redundant entries in a table by either overwriting 00408 * or merging duplicates 00409 * 00410 * @param t Table. 00411 * @param flags APR_OVERLAP_TABLES_MERGE to merge, or 00412 * APR_OVERLAP_TABLES_SET to overwrite 00413 */ 00414 APR_DECLARE(void) apr_table_compress(apr_table_t *t, unsigned flags); 00415 00416 /** @} */ 00417 00418 #ifdef __cplusplus 00419 } 00420 #endif 00421 00422 #endif /* ! APR_TABLES_H */