Annotation of win32/apache22/srclib/apr/include/apr_tables.h, revision 1.1
1.1 ! moko 1: /* Licensed to the Apache Software Foundation (ASF) under one or more
! 2: * contributor license agreements. See the NOTICE file distributed with
! 3: * this work for additional information regarding copyright ownership.
! 4: * The ASF licenses this file to You under the Apache License, Version 2.0
! 5: * (the "License"); you may not use this file except in compliance with
! 6: * the License. You may obtain a copy of the License at
! 7: *
! 8: * http://www.apache.org/licenses/LICENSE-2.0
! 9: *
! 10: * Unless required by applicable law or agreed to in writing, software
! 11: * distributed under the License is distributed on an "AS IS" BASIS,
! 12: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
! 13: * See the License for the specific language governing permissions and
! 14: * limitations under the License.
! 15: */
! 16:
! 17: #ifndef APR_TABLES_H
! 18: #define APR_TABLES_H
! 19:
! 20: /**
! 21: * @file apr_tables.h
! 22: * @brief APR Table library
! 23: */
! 24:
! 25: #include "apr.h"
! 26: #include "apr_pools.h"
! 27:
! 28: #if APR_HAVE_STDARG_H
! 29: #include <stdarg.h> /* for va_list */
! 30: #endif
! 31:
! 32: #ifdef __cplusplus
! 33: extern "C" {
! 34: #endif /* __cplusplus */
! 35:
! 36: /**
! 37: * @defgroup apr_tables Table and Array Functions
! 38: * @ingroup APR
! 39: * Arrays are used to store data which is referenced sequentially or
! 40: * as a stack. Functions are provided to push and pop individual
! 41: * elements as well as to operate on the entire array.
! 42: *
! 43: * Tables are used to store data which can be referenced by key.
! 44: * Limited capabilities are provided for tables with multiple elements
! 45: * which share a key; while key lookup will return only a single
! 46: * element, iteration is available. Additionally, a table can be
! 47: * compressed to resolve duplicates.
! 48: *
! 49: * Both arrays and tables may store string or binary data; some features,
! 50: * such as concatenation or merging of elements, work only for string
! 51: * data.
! 52: * @{
! 53: */
! 54:
! 55: /** the table abstract data type */
! 56: typedef struct apr_table_t apr_table_t;
! 57:
! 58: /** @see apr_array_header_t */
! 59: typedef struct apr_array_header_t apr_array_header_t;
! 60:
! 61: /** An opaque array type */
! 62: struct apr_array_header_t {
! 63: /** The pool the array is allocated out of */
! 64: apr_pool_t *pool;
! 65: /** The amount of memory allocated for each element of the array */
! 66: int elt_size;
! 67: /** The number of active elements in the array */
! 68: int nelts;
! 69: /** The number of elements allocated in the array */
! 70: int nalloc;
! 71: /** The elements in the array */
! 72: char *elts;
! 73: };
! 74:
! 75: /**
! 76: * The (opaque) structure for string-content tables.
! 77: */
! 78: typedef struct apr_table_entry_t apr_table_entry_t;
! 79:
! 80: /** The type for each entry in a string-content table */
! 81: struct apr_table_entry_t {
! 82: /** The key for the current table entry */
! 83: char *key; /* maybe NULL in future;
! 84: * check when iterating thru table_elts
! 85: */
! 86: /** The value for the current table entry */
! 87: char *val;
! 88:
! 89: /** A checksum for the key, for use by the apr_table internals */
! 90: apr_uint32_t key_checksum;
! 91: };
! 92:
! 93: /**
! 94: * Get the elements from a table.
! 95: * @param t The table
! 96: * @return An array containing the contents of the table
! 97: */
! 98: APR_DECLARE(const apr_array_header_t *) apr_table_elts(const apr_table_t *t);
! 99:
! 100: /**
! 101: * Determine if the table is empty (either NULL or having no elements).
! 102: * @param t The table to check
! 103: * @return True if empty, False otherwise
! 104: */
! 105: APR_DECLARE(int) apr_is_empty_table(const apr_table_t *t);
! 106:
! 107: /**
! 108: * Determine if the array is empty (either NULL or having no elements).
! 109: * @param a The array to check
! 110: * @return True if empty, False otherwise
! 111: */
! 112: APR_DECLARE(int) apr_is_empty_array(const apr_array_header_t *a);
! 113:
! 114: /**
! 115: * Create an array.
! 116: * @param p The pool to allocate the memory out of
! 117: * @param nelts the number of elements in the initial array
! 118: * @param elt_size The size of each element in the array.
! 119: * @return The new array
! 120: */
! 121: APR_DECLARE(apr_array_header_t *) apr_array_make(apr_pool_t *p,
! 122: int nelts, int elt_size);
! 123:
! 124: /**
! 125: * Add a new element to an array (as a first-in, last-out stack).
! 126: * @param arr The array to add an element to.
! 127: * @return Location for the new element in the array.
! 128: * @remark If there are no free spots in the array, then this function will
! 129: * allocate new space for the new element.
! 130: */
! 131: APR_DECLARE(void *) apr_array_push(apr_array_header_t *arr);
! 132:
! 133: /** A helper macro for accessing a member of an APR array.
! 134: *
! 135: * @param ary the array
! 136: * @param i the index into the array to return
! 137: * @param type the type of the objects stored in the array
! 138: *
! 139: * @return the item at index i
! 140: */
! 141: #define APR_ARRAY_IDX(ary,i,type) (((type *)(ary)->elts)[i])
! 142:
! 143: /** A helper macro for pushing elements into an APR array.
! 144: *
! 145: * @param ary the array
! 146: * @param type the type of the objects stored in the array
! 147: *
! 148: * @return the location where the new object should be placed
! 149: */
! 150: #define APR_ARRAY_PUSH(ary,type) (*((type *)apr_array_push(ary)))
! 151:
! 152: /**
! 153: * Remove an element from an array (as a first-in, last-out stack).
! 154: * @param arr The array to remove an element from.
! 155: * @return Location of the element in the array.
! 156: * @remark If there are no elements in the array, NULL is returned.
! 157: */
! 158: APR_DECLARE(void *) apr_array_pop(apr_array_header_t *arr);
! 159:
! 160: /**
! 161: * Remove all elements from an array.
! 162: * @param arr The array to remove all elements from.
! 163: * @remark As the underlying storage is allocated from a pool, no
! 164: * memory is freed by this operation, but is available for reuse.
! 165: */
! 166: APR_DECLARE(void) apr_array_clear(apr_array_header_t *arr);
! 167:
! 168: /**
! 169: * Concatenate two arrays together.
! 170: * @param dst The destination array, and the one to go first in the combined
! 171: * array
! 172: * @param src The source array to add to the destination array
! 173: */
! 174: APR_DECLARE(void) apr_array_cat(apr_array_header_t *dst,
! 175: const apr_array_header_t *src);
! 176:
! 177: /**
! 178: * Copy the entire array.
! 179: * @param p The pool to allocate the copy of the array out of
! 180: * @param arr The array to copy
! 181: * @return An exact copy of the array passed in
! 182: * @remark The alternate apr_array_copy_hdr copies only the header, and arranges
! 183: * for the elements to be copied if (and only if) the code subsequently
! 184: * does a push or arraycat.
! 185: */
! 186: APR_DECLARE(apr_array_header_t *) apr_array_copy(apr_pool_t *p,
! 187: const apr_array_header_t *arr);
! 188: /**
! 189: * Copy the headers of the array, and arrange for the elements to be copied if
! 190: * and only if the code subsequently does a push or arraycat.
! 191: * @param p The pool to allocate the copy of the array out of
! 192: * @param arr The array to copy
! 193: * @return An exact copy of the array passed in
! 194: * @remark The alternate apr_array_copy copies the *entire* array.
! 195: */
! 196: APR_DECLARE(apr_array_header_t *) apr_array_copy_hdr(apr_pool_t *p,
! 197: const apr_array_header_t *arr);
! 198:
! 199: /**
! 200: * Append one array to the end of another, creating a new array in the process.
! 201: * @param p The pool to allocate the new array out of
! 202: * @param first The array to put first in the new array.
! 203: * @param second The array to put second in the new array.
! 204: * @return A new array containing the data from the two arrays passed in.
! 205: */
! 206: APR_DECLARE(apr_array_header_t *) apr_array_append(apr_pool_t *p,
! 207: const apr_array_header_t *first,
! 208: const apr_array_header_t *second);
! 209:
! 210: /**
! 211: * Generate a new string from the apr_pool_t containing the concatenated
! 212: * sequence of substrings referenced as elements within the array. The string
! 213: * will be empty if all substrings are empty or null, or if there are no
! 214: * elements in the array. If sep is non-NUL, it will be inserted between
! 215: * elements as a separator.
! 216: * @param p The pool to allocate the string out of
! 217: * @param arr The array to generate the string from
! 218: * @param sep The separator to use
! 219: * @return A string containing all of the data in the array.
! 220: */
! 221: APR_DECLARE(char *) apr_array_pstrcat(apr_pool_t *p,
! 222: const apr_array_header_t *arr,
! 223: const char sep);
! 224:
! 225: /**
! 226: * Make a new table.
! 227: * @param p The pool to allocate the pool out of
! 228: * @param nelts The number of elements in the initial table.
! 229: * @return The new table.
! 230: * @warning This table can only store text data
! 231: */
! 232: APR_DECLARE(apr_table_t *) apr_table_make(apr_pool_t *p, int nelts);
! 233:
! 234: /**
! 235: * Create a new table and copy another table into it.
! 236: * @param p The pool to allocate the new table out of
! 237: * @param t The table to copy
! 238: * @return A copy of the table passed in
! 239: * @warning The table keys and respective values are not copied
! 240: */
! 241: APR_DECLARE(apr_table_t *) apr_table_copy(apr_pool_t *p,
! 242: const apr_table_t *t);
! 243:
! 244: /**
! 245: * Create a new table whose contents are deep copied from the given
! 246: * table. A deep copy operation copies all fields, and makes copies
! 247: * of dynamically allocated memory pointed to by the fields.
! 248: * @param p The pool to allocate the new table out of
! 249: * @param t The table to clone
! 250: * @return A deep copy of the table passed in
! 251: */
! 252: APR_DECLARE(apr_table_t *) apr_table_clone(apr_pool_t *p,
! 253: const apr_table_t *t);
! 254:
! 255: /**
! 256: * Delete all of the elements from a table.
! 257: * @param t The table to clear
! 258: */
! 259: APR_DECLARE(void) apr_table_clear(apr_table_t *t);
! 260:
! 261: /**
! 262: * Get the value associated with a given key from the table. After this call,
! 263: * the data is still in the table.
! 264: * @param t The table to search for the key
! 265: * @param key The key to search for (case does not matter)
! 266: * @return The value associated with the key, or NULL if the key does not exist.
! 267: */
! 268: APR_DECLARE(const char *) apr_table_get(const apr_table_t *t, const char *key);
! 269:
! 270: /**
! 271: * Add a key/value pair to a table. If another element already exists with the
! 272: * same key, this will overwrite the old data.
! 273: * @param t The table to add the data to.
! 274: * @param key The key to use (case does not matter)
! 275: * @param val The value to add
! 276: * @remark When adding data, this function makes a copy of both the key and the
! 277: * value.
! 278: */
! 279: APR_DECLARE(void) apr_table_set(apr_table_t *t, const char *key,
! 280: const char *val);
! 281:
! 282: /**
! 283: * Add a key/value pair to a table. If another element already exists with the
! 284: * same key, this will overwrite the old data.
! 285: * @param t The table to add the data to.
! 286: * @param key The key to use (case does not matter)
! 287: * @param val The value to add
! 288: * @warning When adding data, this function does not make a copy of the key or
! 289: * the value, so care should be taken to ensure that the values will
! 290: * not change after they have been added..
! 291: */
! 292: APR_DECLARE(void) apr_table_setn(apr_table_t *t, const char *key,
! 293: const char *val);
! 294:
! 295: /**
! 296: * Remove data from the table.
! 297: * @param t The table to remove data from
! 298: * @param key The key of the data being removed (case does not matter)
! 299: */
! 300: APR_DECLARE(void) apr_table_unset(apr_table_t *t, const char *key);
! 301:
! 302: /**
! 303: * Add data to a table by merging the value with data that has already been
! 304: * stored. The merging is done by concatenating the two values, separated
! 305: * by the string ", ".
! 306: * @param t The table to search for the data
! 307: * @param key The key to merge data for (case does not matter)
! 308: * @param val The data to add
! 309: * @remark If the key is not found, then this function acts like apr_table_add
! 310: */
! 311: APR_DECLARE(void) apr_table_merge(apr_table_t *t, const char *key,
! 312: const char *val);
! 313:
! 314: /**
! 315: * Add data to a table by merging the value with data that has already been
! 316: * stored. The merging is done by concatenating the two values, separated
! 317: * by the string ", ".
! 318: * @param t The table to search for the data
! 319: * @param key The key to merge data for (case does not matter)
! 320: * @param val The data to add
! 321: * @remark If the key is not found, then this function acts like apr_table_addn
! 322: */
! 323: APR_DECLARE(void) apr_table_mergen(apr_table_t *t, const char *key,
! 324: const char *val);
! 325:
! 326: /**
! 327: * Add data to a table, regardless of whether there is another element with the
! 328: * same key.
! 329: * @param t The table to add to
! 330: * @param key The key to use
! 331: * @param val The value to add.
! 332: * @remark When adding data, this function makes a copy of both the key and the
! 333: * value.
! 334: */
! 335: APR_DECLARE(void) apr_table_add(apr_table_t *t, const char *key,
! 336: const char *val);
! 337:
! 338: /**
! 339: * Add data to a table, regardless of whether there is another element with the
! 340: * same key.
! 341: * @param t The table to add to
! 342: * @param key The key to use
! 343: * @param val The value to add.
! 344: * @remark When adding data, this function does not make a copy of the key or the
! 345: * value, so care should be taken to ensure that the values will not
! 346: * change after they have been added.
! 347: */
! 348: APR_DECLARE(void) apr_table_addn(apr_table_t *t, const char *key,
! 349: const char *val);
! 350:
! 351: /**
! 352: * Merge two tables into one new table.
! 353: * @param p The pool to use for the new table
! 354: * @param overlay The first table to put in the new table
! 355: * @param base The table to add at the end of the new table
! 356: * @return A new table containing all of the data from the two passed in
! 357: */
! 358: APR_DECLARE(apr_table_t *) apr_table_overlay(apr_pool_t *p,
! 359: const apr_table_t *overlay,
! 360: const apr_table_t *base);
! 361:
! 362: /**
! 363: * Declaration prototype for the iterator callback function of apr_table_do()
! 364: * and apr_table_vdo().
! 365: * @param rec The data passed as the first argument to apr_table_[v]do()
! 366: * @param key The key from this iteration of the table
! 367: * @param value The value from this iteration of the table
! 368: * @remark Iteration continues while this callback function returns non-zero.
! 369: * To export the callback function for apr_table_[v]do() it must be declared
! 370: * in the _NONSTD convention.
! 371: */
! 372: typedef int (apr_table_do_callback_fn_t)(void *rec, const char *key,
! 373: const char *value);
! 374:
! 375: /**
! 376: * Iterate over a table running the provided function once for every
! 377: * element in the table. The varargs array must be a list of zero or
! 378: * more (char *) keys followed by a NULL pointer. If zero keys are
! 379: * given, the @param comp function will be invoked for every element
! 380: * in the table. Otherwise, the function is invoked only for those
! 381: * elements matching the keys specified.
! 382: *
! 383: * If an invocation of the @param comp function returns zero,
! 384: * iteration will continue using the next specified key, if any.
! 385: *
! 386: * @param comp The function to run
! 387: * @param rec The data to pass as the first argument to the function
! 388: * @param t The table to iterate over
! 389: * @param ... A varargs array of zero or more (char *) keys followed by NULL
! 390: * @return FALSE if one of the comp() iterations returned zero; TRUE if all
! 391: * iterations returned non-zero
! 392: * @see apr_table_do_callback_fn_t
! 393: */
! 394: APR_DECLARE_NONSTD(int) apr_table_do(apr_table_do_callback_fn_t *comp,
! 395: void *rec, const apr_table_t *t, ...)
! 396: #if defined(__GNUC__) && __GNUC__ >= 4
! 397: __attribute__((sentinel))
! 398: #endif
! 399: ;
! 400:
! 401: /**
! 402: * Iterate over a table running the provided function once for every
! 403: * element in the table. The @param vp varargs parameter must be a
! 404: * list of zero or more (char *) keys followed by a NULL pointer. If
! 405: * zero keys are given, the @param comp function will be invoked for
! 406: * every element in the table. Otherwise, the function is invoked
! 407: * only for those elements matching the keys specified.
! 408: *
! 409: * If an invocation of the @param comp function returns zero,
! 410: * iteration will continue using the next specified key, if any.
! 411: *
! 412: * @param comp The function to run
! 413: * @param rec The data to pass as the first argument to the function
! 414: * @param t The table to iterate over
! 415: * @param vp List of zero or more (char *) keys followed by NULL
! 416: * @return FALSE if one of the comp() iterations returned zero; TRUE if all
! 417: * iterations returned non-zero
! 418: * @see apr_table_do_callback_fn_t
! 419: */
! 420: APR_DECLARE(int) apr_table_vdo(apr_table_do_callback_fn_t *comp,
! 421: void *rec, const apr_table_t *t, va_list vp);
! 422:
! 423: /** flag for overlap to use apr_table_setn */
! 424: #define APR_OVERLAP_TABLES_SET (0)
! 425: /** flag for overlap to use apr_table_mergen */
! 426: #define APR_OVERLAP_TABLES_MERGE (1)
! 427: /**
! 428: * For each element in table b, either use setn or mergen to add the data
! 429: * to table a. Which method is used is determined by the flags passed in.
! 430: * @param a The table to add the data to.
! 431: * @param b The table to iterate over, adding its data to table a
! 432: * @param flags How to add the table to table a. One of:
! 433: * APR_OVERLAP_TABLES_SET Use apr_table_setn
! 434: * APR_OVERLAP_TABLES_MERGE Use apr_table_mergen
! 435: * @remark When merging duplicates, the two values are concatenated,
! 436: * separated by the string ", ".
! 437: * @remark This function is highly optimized, and uses less memory and CPU cycles
! 438: * than a function that just loops through table b calling other functions.
! 439: */
! 440: /**
! 441: * Conceptually, apr_table_overlap does this:
! 442: *
! 443: * <pre>
! 444: * apr_array_header_t *barr = apr_table_elts(b);
! 445: * apr_table_entry_t *belt = (apr_table_entry_t *)barr->elts;
! 446: * int i;
! 447: *
! 448: * for (i = 0; i < barr->nelts; ++i) {
! 449: * if (flags & APR_OVERLAP_TABLES_MERGE) {
! 450: * apr_table_mergen(a, belt[i].key, belt[i].val);
! 451: * }
! 452: * else {
! 453: * apr_table_setn(a, belt[i].key, belt[i].val);
! 454: * }
! 455: * }
! 456: * </pre>
! 457: *
! 458: * Except that it is more efficient (less space and cpu-time) especially
! 459: * when b has many elements.
! 460: *
! 461: * Notice the assumptions on the keys and values in b -- they must be
! 462: * in an ancestor of a's pool. In practice b and a are usually from
! 463: * the same pool.
! 464: */
! 465:
! 466: APR_DECLARE(void) apr_table_overlap(apr_table_t *a, const apr_table_t *b,
! 467: unsigned flags);
! 468:
! 469: /**
! 470: * Eliminate redundant entries in a table by either overwriting
! 471: * or merging duplicates.
! 472: *
! 473: * @param t Table.
! 474: * @param flags APR_OVERLAP_TABLES_MERGE to merge, or
! 475: * APR_OVERLAP_TABLES_SET to overwrite
! 476: * @remark When merging duplicates, the two values are concatenated,
! 477: * separated by the string ", ".
! 478: */
! 479: APR_DECLARE(void) apr_table_compress(apr_table_t *t, unsigned flags);
! 480:
! 481: /** @} */
! 482:
! 483: #ifdef __cplusplus
! 484: }
! 485: #endif
! 486:
! 487: #endif /* ! APR_TABLES_H */
E-mail: