apr_tables.h revision 302408
178064Sume/* Licensed to the Apache Software Foundation (ASF) under one or more
262638Skris * contributor license agreements.  See the NOTICE file distributed with
355505Sshin * this work for additional information regarding copyright ownership.
455505Sshin * The ASF licenses this file to You under the Apache License, Version 2.0
555505Sshin * (the "License"); you may not use this file except in compliance with
655505Sshin * the License.  You may obtain a copy of the License at
755505Sshin *
855505Sshin *     http://www.apache.org/licenses/LICENSE-2.0
955505Sshin *
1055505Sshin * Unless required by applicable law or agreed to in writing, software
1155505Sshin * distributed under the License is distributed on an "AS IS" BASIS,
1255505Sshin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1355505Sshin * See the License for the specific language governing permissions and
1455505Sshin * limitations under the License.
1555505Sshin */
1655505Sshin
1755505Sshin#ifndef APR_TABLES_H
1855505Sshin#define APR_TABLES_H
1955505Sshin
2055505Sshin/**
2155505Sshin * @file apr_tables.h
2255505Sshin * @brief APR Table library
2355505Sshin */
2455505Sshin
2555505Sshin#include "apr.h"
2655505Sshin#include "apr_pools.h"
2755505Sshin
2855505Sshin#if APR_HAVE_STDARG_H
2955505Sshin#include <stdarg.h>     /* for va_list */
3055505Sshin#endif
3155505Sshin
3255505Sshin#ifdef __cplusplus
3355505Sshinextern "C" {
3455505Sshin#endif /* __cplusplus */
3555505Sshin
3655505Sshin/**
3755505Sshin * @defgroup apr_tables Table and Array Functions
3878064Sume * @ingroup APR
3955505Sshin * Arrays are used to store data which is referenced sequentially or
4055505Sshin * as a stack.  Functions are provided to push and pop individual
4155505Sshin * elements as well as to operate on the entire array.
4255505Sshin *
4362638Skris * Tables are used to store data which can be referenced by key.
4455505Sshin * Limited capabilities are provided for tables with multiple elements
4562638Skris * which share a key; while key lookup will return only a single
4655505Sshin * element, iteration is available.  Additionally, a table can be
4755505Sshin * compressed to resolve duplicates.
4855505Sshin *
4955505Sshin * Both arrays and tables may store string or binary data; some features,
5062638Skris * such as concatenation or merging of elements, work only for string
5162638Skris * data.
5262638Skris * @{
5355505Sshin */
5455505Sshin
5555505Sshin/** the table abstract data type */
5655505Sshintypedef struct apr_table_t apr_table_t;
5762638Skris
5855505Sshin/** @see apr_array_header_t */
5978064Sumetypedef struct apr_array_header_t apr_array_header_t;
60173412Skevlo
61173412Skevlo/** An opaque array type */
62173412Skevlostruct apr_array_header_t {
6355505Sshin    /** The pool the array is allocated out of */
6455505Sshin    apr_pool_t *pool;
65250227Sjkim    /** The amount of memory allocated for each element of the array */
66250227Sjkim    int elt_size;
6755505Sshin    /** The number of active elements in the array */
6855505Sshin    int nelts;
6955505Sshin    /** The number of elements allocated in the array */
7055505Sshin    int nalloc;
7155505Sshin    /** The elements in the array */
7255505Sshin    char *elts;
7355505Sshin};
7455505Sshin
7555505Sshin/**
7655505Sshin * The (opaque) structure for string-content tables.
7755505Sshin */
7855505Sshintypedef struct apr_table_entry_t apr_table_entry_t;
7955505Sshin
8055505Sshin/** The type for each entry in a string-content table */
8155505Sshinstruct apr_table_entry_t {
8255505Sshin    /** The key for the current table entry */
8355505Sshin    char *key;          /* maybe NULL in future;
8455505Sshin                         * check when iterating thru table_elts
8555505Sshin                         */
8655505Sshin    /** The value for the current table entry */
8755505Sshin    char *val;
8855505Sshin
8955505Sshin    /** A checksum for the key, for use by the apr_table internals */
9055505Sshin    apr_uint32_t key_checksum;
9155505Sshin};
9255505Sshin
9355505Sshin/**
9455505Sshin * Get the elements from a table.
9555505Sshin * @param t The table
9655505Sshin * @return An array containing the contents of the table
9755505Sshin */
9855505SshinAPR_DECLARE(const apr_array_header_t *) apr_table_elts(const apr_table_t *t);
9955505Sshin
10055505Sshin/**
10155505Sshin * Determine if the table is empty (either NULL or having no elements).
10255505Sshin * @param t The table to check
10355505Sshin * @return True if empty, False otherwise
10455505Sshin */
10555505SshinAPR_DECLARE(int) apr_is_empty_table(const apr_table_t *t);
10655505Sshin
10755505Sshin/**
10855505Sshin * Determine if the array is empty (either NULL or having no elements).
10955505Sshin * @param a The array to check
11055505Sshin * @return True if empty, False otherwise
11155505Sshin */
11255505SshinAPR_DECLARE(int) apr_is_empty_array(const apr_array_header_t *a);
11355505Sshin
11455505Sshin/**
11555505Sshin * Create an array.
11655505Sshin * @param p The pool to allocate the memory out of
11755505Sshin * @param nelts the number of elements in the initial array
11855505Sshin * @param elt_size The size of each element in the array.
11955505Sshin * @return The new array
12055505Sshin */
12155505SshinAPR_DECLARE(apr_array_header_t *) apr_array_make(apr_pool_t *p,
12255505Sshin                                                 int nelts, int elt_size);
12355505Sshin
12455505Sshin/**
12555505Sshin * Add a new element to an array (as a first-in, last-out stack).
12655505Sshin * @param arr The array to add an element to.
12755505Sshin * @return Location for the new element in the array.
12855505Sshin * @remark If there are no free spots in the array, then this function will
12955505Sshin *         allocate new space for the new element.
13055505Sshin */
13155505SshinAPR_DECLARE(void *) apr_array_push(apr_array_header_t *arr);
13255505Sshin
13355505Sshin/** A helper macro for accessing a member of an APR array.
13455505Sshin *
13555505Sshin * @param ary the array
13655505Sshin * @param i the index into the array to return
13755505Sshin * @param type the type of the objects stored in the array
13855505Sshin *
13955505Sshin * @return the item at index i
14055505Sshin */
14155505Sshin#define APR_ARRAY_IDX(ary,i,type) (((type *)(ary)->elts)[i])
14255505Sshin
14355505Sshin/** A helper macro for pushing elements into an APR array.
14455505Sshin *
14555505Sshin * @param ary the array
14655505Sshin * @param type the type of the objects stored in the array
14755505Sshin *
14855505Sshin * @return the location where the new object should be placed
14955505Sshin */
15055505Sshin#define APR_ARRAY_PUSH(ary,type) (*((type *)apr_array_push(ary)))
15155505Sshin
15255505Sshin/**
15355505Sshin * Remove an element from an array (as a first-in, last-out stack).
15455505Sshin * @param arr The array to remove an element from.
15555505Sshin * @return Location of the element in the array.
15655505Sshin * @remark If there are no elements in the array, NULL is returned.
15755505Sshin */
15855505SshinAPR_DECLARE(void *) apr_array_pop(apr_array_header_t *arr);
15955505Sshin
16055505Sshin/**
16155505Sshin * Remove all elements from an array.
16255505Sshin * @param arr The array to remove all elements from.
16355505Sshin * @remark As the underlying storage is allocated from a pool, no
16455505Sshin * memory is freed by this operation, but is available for reuse.
16555505Sshin */
16655505SshinAPR_DECLARE(void) apr_array_clear(apr_array_header_t *arr);
16755505Sshin
16855505Sshin/**
16955505Sshin * Concatenate two arrays together.
17055505Sshin * @param dst The destination array, and the one to go first in the combined
17155505Sshin *            array
17255505Sshin * @param src The source array to add to the destination array
17355505Sshin */
17455505SshinAPR_DECLARE(void) apr_array_cat(apr_array_header_t *dst,
17555505Sshin			        const apr_array_header_t *src);
17655505Sshin
17755505Sshin/**
17855505Sshin * Copy the entire array.
17955505Sshin * @param p The pool to allocate the copy of the array out of
18055505Sshin * @param arr The array to copy
18155505Sshin * @return An exact copy of the array passed in
18255505Sshin * @remark The alternate apr_array_copy_hdr copies only the header, and arranges
18355505Sshin *         for the elements to be copied if (and only if) the code subsequently
18455505Sshin *         does a push or arraycat.
18555505Sshin */
18655505SshinAPR_DECLARE(apr_array_header_t *) apr_array_copy(apr_pool_t *p,
18755505Sshin                                      const apr_array_header_t *arr);
18855505Sshin/**
18955505Sshin * Copy the headers of the array, and arrange for the elements to be copied if
19055505Sshin * and only if the code subsequently does a push or arraycat.
19155505Sshin * @param p The pool to allocate the copy of the array out of
19255505Sshin * @param arr The array to copy
19355505Sshin * @return An exact copy of the array passed in
19455505Sshin * @remark The alternate apr_array_copy copies the *entire* array.
19555505Sshin */
19655505SshinAPR_DECLARE(apr_array_header_t *) apr_array_copy_hdr(apr_pool_t *p,
19755505Sshin                                      const apr_array_header_t *arr);
19855505Sshin
19955505Sshin/**
20055505Sshin * Append one array to the end of another, creating a new array in the process.
20155505Sshin * @param p The pool to allocate the new array out of
20255505Sshin * @param first The array to put first in the new array.
20355505Sshin * @param second The array to put second in the new array.
20455505Sshin * @return A new array containing the data from the two arrays passed in.
20555505Sshin*/
20655505SshinAPR_DECLARE(apr_array_header_t *) apr_array_append(apr_pool_t *p,
20755505Sshin                                      const apr_array_header_t *first,
20855505Sshin                                      const apr_array_header_t *second);
20955505Sshin
21055505Sshin/**
21155505Sshin * Generate a new string from the apr_pool_t containing the concatenated
21255505Sshin * sequence of substrings referenced as elements within the array.  The string
21355505Sshin * will be empty if all substrings are empty or null, or if there are no
21455505Sshin * elements in the array.  If sep is non-NUL, it will be inserted between
21555505Sshin * elements as a separator.
21655505Sshin * @param p The pool to allocate the string out of
21755505Sshin * @param arr The array to generate the string from
21855505Sshin * @param sep The separator to use
21955505Sshin * @return A string containing all of the data in the array.
22055505Sshin */
22155505SshinAPR_DECLARE(char *) apr_array_pstrcat(apr_pool_t *p,
22255505Sshin				      const apr_array_header_t *arr,
22355505Sshin				      const char sep);
22455505Sshin
22555505Sshin/**
22662638Skris * Make a new table.
22762638Skris * @param p The pool to allocate the pool out of
22862638Skris * @param nelts The number of elements in the initial table.
22962638Skris * @return The new table.
23062638Skris * @warning This table can only store text data
23162638Skris */
23262638SkrisAPR_DECLARE(apr_table_t *) apr_table_make(apr_pool_t *p, int nelts);
23362638Skris
23462638Skris/**
23555505Sshin * Create a new table and copy another table into it.
23655505Sshin * @param p The pool to allocate the new table out of
23755505Sshin * @param t The table to copy
23855505Sshin * @return A copy of the table passed in
23955505Sshin * @warning The table keys and respective values are not copied
24055505Sshin */
24155505SshinAPR_DECLARE(apr_table_t *) apr_table_copy(apr_pool_t *p,
24255505Sshin                                          const apr_table_t *t);
24355505Sshin
24455505Sshin/**
24555505Sshin * Create a new table whose contents are deep copied from the given
24655505Sshin * table. A deep copy operation copies all fields, and makes copies
24755505Sshin * of dynamically allocated memory pointed to by the fields.
24855505Sshin * @param p The pool to allocate the new table out of
24955505Sshin * @param t The table to clone
25055505Sshin * @return A deep copy of the table passed in
25155505Sshin */
25255505SshinAPR_DECLARE(apr_table_t *) apr_table_clone(apr_pool_t *p,
25355505Sshin                                           const apr_table_t *t);
25455505Sshin
25555505Sshin/**
25655505Sshin * Delete all of the elements from a table.
25755505Sshin * @param t The table to clear
258173412Skevlo */
25978064SumeAPR_DECLARE(void) apr_table_clear(apr_table_t *t);
26055505Sshin
26155505Sshin/**
26278064Sume * Get the value associated with a given key from the table.  After this call,
26355505Sshin * the data is still in the table.
26455505Sshin * @param t The table to search for the key
26555505Sshin * @param key The key to search for (case does not matter)
26655505Sshin * @return The value associated with the key, or NULL if the key does not exist.
26755505Sshin */
26855505SshinAPR_DECLARE(const char *) apr_table_get(const apr_table_t *t, const char *key);
26955505Sshin
27055505Sshin/**
27155505Sshin * Get values associated with a given key from the table.      If more than one
27255505Sshin * value exists, return a comma separated list of values.  After this call, the
27355505Sshin * data is still in the table.
274 * @param p The pool to allocate the combined value from, if necessary
275 * @param t The table to search for the key
276 * @param key The key to search for (case does not matter)
277 * @return The value associated with the key, or NULL if the key does not exist.
278 */
279APR_DECLARE(const char *) apr_table_getm(apr_pool_t *p, const apr_table_t *t,
280                                         const char *key);
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 * @remark When adding data, this function makes a copy of both the key and the
289 *         value.
290 */
291APR_DECLARE(void) apr_table_set(apr_table_t *t, const char *key,
292                                const char *val);
293
294/**
295 * Add a key/value pair to a table.  If another element already exists with the
296 * same key, this will overwrite the old data.
297 * @param t The table to add the data to.
298 * @param key The key to use (case does not matter)
299 * @param val The value to add
300 * @warning When adding data, this function does not make a copy of the key or
301 *          the value, so care should be taken to ensure that the values will
302 *          not change after they have been added..
303 */
304APR_DECLARE(void) apr_table_setn(apr_table_t *t, const char *key,
305                                 const char *val);
306
307/**
308 * Remove data from the table.
309 * @param t The table to remove data from
310 * @param key The key of the data being removed (case does not matter)
311 */
312APR_DECLARE(void) apr_table_unset(apr_table_t *t, const char *key);
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_add
322 */
323APR_DECLARE(void) apr_table_merge(apr_table_t *t, const char *key,
324                                  const char *val);
325
326/**
327 * Add data to a table by merging the value with data that has already been
328 * stored. The merging is done by concatenating the two values, separated
329 * by the string ", ".
330 * @param t The table to search for the data
331 * @param key The key to merge data for (case does not matter)
332 * @param val The data to add
333 * @remark If the key is not found, then this function acts like apr_table_addn
334 */
335APR_DECLARE(void) apr_table_mergen(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 makes a copy of both the key and the
345 *         value.
346 */
347APR_DECLARE(void) apr_table_add(apr_table_t *t, const char *key,
348                                const char *val);
349
350/**
351 * Add data to a table, regardless of whether there is another element with the
352 * same key.
353 * @param t The table to add to
354 * @param key The key to use
355 * @param val The value to add.
356 * @remark When adding data, this function does not make a copy of the key or the
357 *         value, so care should be taken to ensure that the values will not
358 *         change after they have been added.
359 */
360APR_DECLARE(void) apr_table_addn(apr_table_t *t, const char *key,
361                                 const char *val);
362
363/**
364 * Merge two tables into one new table.
365 * @param p The pool to use for the new table
366 * @param overlay The first table to put in the new table
367 * @param base The table to add at the end of the new table
368 * @return A new table containing all of the data from the two passed in
369 */
370APR_DECLARE(apr_table_t *) apr_table_overlay(apr_pool_t *p,
371                                             const apr_table_t *overlay,
372                                             const apr_table_t *base);
373
374/**
375 * Declaration prototype for the iterator callback function of apr_table_do()
376 * and apr_table_vdo().
377 * @param rec The data passed as the first argument to apr_table_[v]do()
378 * @param key The key from this iteration of the table
379 * @param value The value from this iteration of the table
380 * @remark Iteration continues while this callback function returns non-zero.
381 * To export the callback function for apr_table_[v]do() it must be declared
382 * in the _NONSTD convention.
383 */
384typedef int (apr_table_do_callback_fn_t)(void *rec, const char *key,
385                                                    const char *value);
386
387/**
388 * Iterate over a table running the provided function once for every
389 * element in the table.  The varargs array must be a list of zero or
390 * more (char *) keys followed by a NULL pointer.  If zero keys are
391 * given, the @param comp function will be invoked for every element
392 * in the table.  Otherwise, the function is invoked only for those
393 * elements matching the keys specified.
394 *
395 * If an invocation of the @param comp function returns zero,
396 * iteration will continue using the next specified key, if any.
397 *
398 * @param comp The function to run
399 * @param rec The data to pass as the first argument to the function
400 * @param t The table to iterate over
401 * @param ... A varargs array of zero or more (char *) keys followed by NULL
402 * @return FALSE if one of the comp() iterations returned zero; TRUE if all
403 *            iterations returned non-zero
404 * @see apr_table_do_callback_fn_t
405 */
406APR_DECLARE_NONSTD(int) apr_table_do(apr_table_do_callback_fn_t *comp,
407                                     void *rec, const apr_table_t *t, ...)
408#if defined(__GNUC__) && __GNUC__ >= 4
409    __attribute__((sentinel))
410#endif
411    ;
412
413/**
414 * Iterate over a table running the provided function once for every
415 * element in the table.  The @param vp varargs parameter must be a
416 * list of zero or more (char *) keys followed by a NULL pointer.  If
417 * zero keys are given, the @param comp function will be invoked for
418 * every element in the table.  Otherwise, the function is invoked
419 * only for those elements matching the keys specified.
420 *
421 * If an invocation of the @param comp function returns zero,
422 * iteration will continue using the next specified key, if any.
423 *
424 * @param comp The function to run
425 * @param rec The data to pass as the first argument to the function
426 * @param t The table to iterate over
427 * @param vp List of zero or more (char *) keys followed by NULL
428 * @return FALSE if one of the comp() iterations returned zero; TRUE if all
429 *            iterations returned non-zero
430 * @see apr_table_do_callback_fn_t
431 */
432APR_DECLARE(int) apr_table_vdo(apr_table_do_callback_fn_t *comp,
433                               void *rec, const apr_table_t *t, va_list vp);
434
435/** flag for overlap to use apr_table_setn */
436#define APR_OVERLAP_TABLES_SET   (0)
437/** flag for overlap to use apr_table_mergen */
438#define APR_OVERLAP_TABLES_MERGE (1)
439/**
440 * For each element in table b, either use setn or mergen to add the data
441 * to table a.  Which method is used is determined by the flags passed in.
442 * @param a The table to add the data to.
443 * @param b The table to iterate over, adding its data to table a
444 * @param flags How to add the table to table a.  One of:
445 *          APR_OVERLAP_TABLES_SET        Use apr_table_setn
446 *          APR_OVERLAP_TABLES_MERGE      Use apr_table_mergen
447 * @remark  When merging duplicates, the two values are concatenated,
448 *          separated by the string ", ".
449 * @remark  This function is highly optimized, and uses less memory and CPU cycles
450 *          than a function that just loops through table b calling other functions.
451 */
452/**
453 * Conceptually, apr_table_overlap does this:
454 *
455 * <pre>
456 *  apr_array_header_t *barr = apr_table_elts(b);
457 *  apr_table_entry_t *belt = (apr_table_entry_t *)barr->elts;
458 *  int i;
459 *
460 *  for (i = 0; i < barr->nelts; ++i) {
461 *      if (flags & APR_OVERLAP_TABLES_MERGE) {
462 *          apr_table_mergen(a, belt[i].key, belt[i].val);
463 *      }
464 *      else {
465 *          apr_table_setn(a, belt[i].key, belt[i].val);
466 *      }
467 *  }
468 * </pre>
469 *
470 *  Except that it is more efficient (less space and cpu-time) especially
471 *  when b has many elements.
472 *
473 *  Notice the assumptions on the keys and values in b -- they must be
474 *  in an ancestor of a's pool.  In practice b and a are usually from
475 *  the same pool.
476 */
477
478APR_DECLARE(void) apr_table_overlap(apr_table_t *a, const apr_table_t *b,
479                                     unsigned flags);
480
481/**
482 * Eliminate redundant entries in a table by either overwriting
483 * or merging duplicates.
484 *
485 * @param t Table.
486 * @param flags APR_OVERLAP_TABLES_MERGE to merge, or
487 *              APR_OVERLAP_TABLES_SET to overwrite
488 * @remark When merging duplicates, the two values are concatenated,
489 *         separated by the string ", ".
490 */
491APR_DECLARE(void) apr_table_compress(apr_table_t *t, unsigned flags);
492
493/** @} */
494
495#ifdef __cplusplus
496}
497#endif
498
499#endif	/* ! APR_TABLES_H */
500