Apache Portable Runtime
apr_tables.h
Go to the documentation of this file.
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 */
60 
61 /** An opaque array type */
63  /** The pool the array is allocated out of */
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  */
79 
80 /** The type for each entry in a string-content table */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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  */
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 */
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  */
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  */
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  */
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  */
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  */
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  * Get values associated with a given key from the table. If more than one
272  * value exists, return a comma separated list of values. After this call, the
273  * 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  */
279 APR_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  */
291 APR_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  */
304 APR_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  */
312 APR_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  */
323 APR_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  */
335 APR_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  */
347 APR_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  */
360 APR_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  */
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  * @see apr_table_do @see apr_table_vdo
384  */
385 typedef int (apr_table_do_callback_fn_t)(void *rec, const char *key,
386  const char *value);
387 
388 /**
389  * Iterate over a table running the provided function once for every
390  * element in the table. The varargs array must be a list of zero or
391  * more (char *) keys followed by a NULL pointer. If zero keys are
392  * given, the @param comp function will be invoked for every element
393  * in the table. Otherwise, the function is invoked only for those
394  * elements matching the keys specified.
395  *
396  * If an invocation of the comp function returns zero,
397  * iteration will continue using the next specified key, if any.
398  *
399  * @param comp The function to run
400  * @param rec The data to pass as the first argument to the function
401  * @param t The table to iterate over
402  * @param ... A varargs array of zero or more (char *) keys followed by NULL
403  * @return FALSE if one of the comp() iterations returned zero; TRUE if all
404  * iterations returned non-zero
405  * @see apr_table_do_callback_fn_t @see apr_table_vdo
406  */
408  void *rec, const apr_table_t *t, ...)
409 #if defined(__GNUC__) && __GNUC__ >= 4
410  __attribute__((sentinel))
411 #endif
412  ;
413 
414 /**
415  * Iterate over a table running the provided function once for every
416  * element in the table. The vp varargs parameter must be a
417  * list of zero or more (char *) keys followed by a NULL pointer. If
418  * zero keys are given, the @param comp function will be invoked for
419  * every element in the table. Otherwise, the function is invoked
420  * only for those elements matching the keys specified.
421  *
422  * If an invocation of the comp function returns zero,
423  * iteration will continue using the next specified key, if any.
424  *
425  * @param comp The function to run
426  * @param rec The data to pass as the first argument to the function
427  * @param t The table to iterate over
428  * @param vp List of zero or more (char *) keys followed by NULL
429  * @return FALSE if one of the comp() iterations returned zero; TRUE if all
430  * iterations returned non-zero
431  * @see apr_table_do_callback_fn_t @see apr_table_do
432  */
434  void *rec, const apr_table_t *t, va_list vp);
435 
436 /** flag for overlap to use apr_table_setn */
437 #define APR_OVERLAP_TABLES_SET (0)
438 /** flag for overlap to use apr_table_mergen */
439 #define APR_OVERLAP_TABLES_MERGE (1)
440 /** flag for overlap to use apr_table_addn */
441 #define APR_OVERLAP_TABLES_ADD (2)
442 /**
443  * For each element in table b, either use setn or mergen to add the data
444  * to table a. Which method is used is determined by the flags passed in.
445  * @param a The table to add the data to.
446  * @param b The table to iterate over, adding its data to table a
447  * @param flags How to add the table to table a. One of:
448  * APR_OVERLAP_TABLES_SET Use apr_table_setn
449  * APR_OVERLAP_TABLES_MERGE Use apr_table_mergen
450  * APR_OVERLAP_TABLES_ADD Use apr_table_addn
451  * @remark When merging duplicates, the two values are concatenated,
452  * separated by the string ", ".
453  * @remark This function is highly optimized, and uses less memory and CPU cycles
454  * than a function that just loops through table b calling other functions.
455  */
456 /**
457  * Conceptually, apr_table_overlap does this:
458  *
459  * <pre>
460  * apr_array_header_t *barr = apr_table_elts(b);
461  * apr_table_entry_t *belt = (apr_table_entry_t *)barr->elts;
462  * int i;
463  *
464  * for (i = 0; i < barr->nelts; ++i) {
465  * if (flags & APR_OVERLAP_TABLES_MERGE) {
466  * apr_table_mergen(a, belt[i].key, belt[i].val);
467  * }
468  * else if (flags & APR_OVERLAP_TABLES_ADD) {
469  * apr_table_addn(a, belt[i].key, belt[i].val);
470  * }
471  * else {
472  * apr_table_setn(a, belt[i].key, belt[i].val);
473  * }
474  * }
475  * </pre>
476  *
477  * Except that it is more efficient (less space and cpu-time) especially
478  * when b has many elements.
479  *
480  * Notice the assumptions on the keys and values in b -- they must be
481  * in an ancestor of a's pool. In practice b and a are usually from
482  * the same pool.
483  */
484 
486  unsigned flags);
487 
488 /**
489  * Eliminate redundant entries in a table by either overwriting
490  * or merging duplicates.
491  *
492  * @param t Table.
493  * @param flags APR_OVERLAP_TABLES_MERGE to merge, or
494  * APR_OVERLAP_TABLES_SET to overwrite, or
495  * APR_OVERLAP_TABLES_ADD to add
496  * @remark When merging duplicates, the two values are concatenated,
497  * separated by the string ", ".
498  */
499 APR_DECLARE(void) apr_table_compress(apr_table_t *t, unsigned flags);
500 
501 /** @} */
502 
503 #ifdef __cplusplus
504 }
505 #endif
506 
507 #endif /* ! APR_TABLES_H */
apr_table_t * apr_table_copy(apr_pool_t *p, const apr_table_t *t)
apr_table_t * apr_table_make(apr_pool_t *p, int nelts)
Definition: apr_tables.h:62
apr_array_header_t * apr_array_make(apr_pool_t *p, int nelts, int elt_size)
#define APR_DECLARE_NONSTD(type)
Definition: apr.h:511
apr_array_header_t * apr_array_copy(apr_pool_t *p, const apr_array_header_t *arr)
int apr_is_empty_array(const apr_array_header_t *a)
int nalloc
Definition: apr_tables.h:70
void apr_array_cat(apr_array_header_t *dst, const apr_array_header_t *src)
int() apr_table_do_callback_fn_t(void *rec, const char *key, const char *value)
Definition: apr_tables.h:385
void apr_table_setn(apr_table_t *t, const char *key, const char *val)
void apr_table_add(apr_table_t *t, const char *key, const char *val)
void apr_table_overlap(apr_table_t *a, const apr_table_t *b, unsigned flags)
void apr_table_unset(apr_table_t *t, const char *key)
int nelts
Definition: apr_tables.h:68
void * apr_array_push(apr_array_header_t *arr)
#define APR_DECLARE(type)
Definition: apr.h:498
int apr_table_do(apr_table_do_callback_fn_t *comp, void *rec, const apr_table_t *t,...)
void apr_table_mergen(apr_table_t *t, const char *key, const char *val)
void apr_table_merge(apr_table_t *t, const char *key, const char *val)
char * key
Definition: apr_tables.h:83
apr_array_header_t * apr_array_copy_hdr(apr_pool_t *p, const apr_array_header_t *arr)
APR memory allocation.
void * apr_array_pop(apr_array_header_t *arr)
int apr_table_vdo(apr_table_do_callback_fn_t *comp, void *rec, const apr_table_t *t, va_list vp)
apr_uint32_t key_checksum
Definition: apr_tables.h:90
Definition: apr_tables.h:81
const char * apr_table_get(const apr_table_t *t, const char *key)
apr_array_header_t * apr_array_append(apr_pool_t *p, const apr_array_header_t *first, const apr_array_header_t *second)
APR Platform Definitions.
apr_table_t * apr_table_overlay(apr_pool_t *p, const apr_table_t *overlay, const apr_table_t *base)
int elt_size
Definition: apr_tables.h:66
void apr_table_clear(apr_table_t *t)
const apr_array_header_t * apr_table_elts(const apr_table_t *t)
const char * apr_table_getm(apr_pool_t *p, const apr_table_t *t, const char *key)
apr_pool_t * pool
Definition: apr_tables.h:64
char * val
Definition: apr_tables.h:87
struct apr_table_t apr_table_t
Definition: apr_tables.h:56
struct apr_pool_t apr_pool_t
Definition: apr_pools.h:60
void apr_table_addn(apr_table_t *t, const char *key, const char *val)
void apr_table_set(apr_table_t *t, const char *key, const char *val)
char * elts
Definition: apr_tables.h:72
char * apr_array_pstrcat(apr_pool_t *p, const apr_array_header_t *arr, const char sep)
void apr_table_compress(apr_table_t *t, unsigned flags)
apr_table_t * apr_table_clone(apr_pool_t *p, const apr_table_t *t)
int apr_is_empty_table(const apr_table_t *t)
void apr_array_clear(apr_array_header_t *arr)