change the required dependency for codec_dahdi to only be satisfied by DAHDI and...
[asterisk-bristuff.git] / include / asterisk / stringfields.h
blobd8d257f956e4531e87c536720901f6e9474d266f
1 /*
2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 2006, Digium, Inc.
6 * Kevin P. Fleming <kpfleming@digium.com>
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
19 /*! \file
20 \brief String fields in structures
22 This file contains objects and macros used to manage string
23 fields in structures without requiring them to be allocated
24 as fixed-size buffers or requiring individual allocations for
25 for each field.
27 Using this functionality is quite simple... an example structure
28 with three fields is defined like this:
30 \code
31 struct sample_fields {
32 int x1;
33 AST_DECLARE_STRING_FIELDS(
34 AST_STRING_FIELD(name);
35 AST_STRING_FIELD(address);
36 AST_STRING_FIELD(password);
38 long x2;
40 \endcode
42 When an instance of this structure is allocated, the fields
43 (and the pool of storage for them) must be initialized:
45 \code
46 struct sample_fields *sample;
48 sample = calloc(1, sizeof(*sample));
49 if (sample) {
50 if (ast_string_field_init(sample, 256)) {
51 free(sample);
52 sample = NULL;
56 if (!sample) {
57 ...
59 \endcode
61 Fields will default to pointing to an empty string, and will
62 revert to that when ast_string_field_free() is called. This means
63 that a string field will \b never contain NULL.
65 Using the fields is much like using regular 'char *' fields
66 in the structure, except that writing into them must be done
67 using wrapper macros defined in this file.
69 Storing simple values into fields can be done using ast_string_field_set();
70 more complex values (using printf-style format strings) can be stored
71 using ast_string_field_build().
73 When the structure instance is no longer needed, the fields
74 and their storage pool must be freed:
76 \code
77 ast_string_field_free_memory(sample);
78 free(sample);
79 \endcode
82 #ifndef _ASTERISK_STRINGFIELDS_H
83 #define _ASTERISK_STRINGFIELDS_H
85 #include <string.h>
86 #include <stdarg.h>
87 #include <stddef.h>
89 #include "asterisk/inline_api.h"
90 #include "asterisk/compiler.h"
91 #include "asterisk/compat.h"
93 /*!
94 \internal
95 \brief An opaque type for managed string fields in structures
97 Don't declare instances of this type directly; use the AST_STRING_FIELD()
98 macro instead.
100 typedef const char * ast_string_field;
103 \internal
104 \brief A constant empty string used for fields that have no other value
106 extern const char __ast_string_field_empty[];
109 \internal
110 \brief Structure used to hold a pool of space for string fields
112 struct ast_string_field_pool {
113 struct ast_string_field_pool *prev; /*!< pointer to the previous pool, if any */
114 char base[0]; /*!< storage space for the fields */
118 \internal
119 \brief Structure used to manage the storage for a set of string fields
121 struct ast_string_field_mgr {
122 struct ast_string_field_pool *pool; /*!< the address of the pool's structure */
123 size_t size; /*!< the total size of the current pool */
124 size_t space; /*!< the space available in the current pool */
125 size_t used; /*!< the space used in the current pool */
129 \internal
130 \brief Initialize a field pool manager and fields
131 \param mgr Pointer to the pool manager structure
132 \param size Amount of storage to allocate
133 \param fields Pointer to the first entry of the field array
134 \param num_fields Number of fields in the array
135 \return 0 on success, non-zero on failure
137 int __ast_string_field_init(struct ast_string_field_mgr *mgr, size_t size,
138 ast_string_field *fields, int num_fields);
141 \internal
142 \brief Allocate space for a field
143 \param mgr Pointer to the pool manager structure
144 \param needed Amount of space needed for this field
145 \param fields Pointer to the first entry of the field array
146 \param num_fields Number of fields in the array
147 \return NULL on failure, an address for the field on success
149 This function will allocate the requested amount of space from
150 the field pool. If the requested amount of space is not available,
151 an additional pool will be allocated.
153 ast_string_field __ast_string_field_alloc_space(struct ast_string_field_mgr *mgr, size_t needed,
154 ast_string_field *fields, int num_fields);
157 \internal
158 \brief Set a field to a complex (built) value
159 \param mgr Pointer to the pool manager structure
160 \param fields Pointer to the first entry of the field array
161 \param num_fields Number of fields in the array
162 \param index Index position of the field within the structure
163 \param format printf-style format string
164 \return nothing
166 void __ast_string_field_index_build(struct ast_string_field_mgr *mgr,
167 ast_string_field *fields, int num_fields,
168 int index, const char *format, ...);
171 \internal
172 \brief Set a field to a complex (built) value
173 \param mgr Pointer to the pool manager structure
174 \param fields Pointer to the first entry of the field array
175 \param num_fields Number of fields in the array
176 \param index Index position of the field within the structure
177 \param format printf-style format string
178 \param args va_list of the args for the format_string
179 \param args_again a copy of the first va_list for the sake of bsd not having a copy routine
180 \return nothing
182 void __ast_string_field_index_build_va(struct ast_string_field_mgr *mgr,
183 ast_string_field *fields, int num_fields,
184 int index, const char *format, va_list a1, va_list a2);
187 \brief Declare a string field
188 \param name The field name
190 #define AST_STRING_FIELD(name) const ast_string_field name
193 \brief Declare the fields needed in a structure
194 \param field_list The list of fields to declare, using AST_STRING_FIELD() for each one
196 #define AST_DECLARE_STRING_FIELDS(field_list) \
197 ast_string_field __begin_field[0]; \
198 field_list \
199 ast_string_field __end_field[0]; \
200 struct ast_string_field_mgr __field_mgr
203 \brief Get the number of string fields in a structure
204 \param x Pointer to a structure containing fields
205 \return the number of fields in the structure's definition
207 #define ast_string_field_count(x) \
208 (offsetof(typeof(*(x)), __end_field) - offsetof(typeof(*(x)), __begin_field)) / sizeof(ast_string_field)
211 \brief Get the index of a field in a structure
212 \param x Pointer to a structure containing fields
213 \param field Name of the field to locate
214 \return the position (index) of the field within the structure's
215 array of fields
217 #define ast_string_field_index(x, field) \
218 (offsetof(typeof(*x), field) - offsetof(typeof(*x), __begin_field)) / sizeof(ast_string_field)
221 \brief Initialize a field pool and fields
222 \param x Pointer to a structure containing fields
223 \param size Amount of storage to allocate
224 \return 0 on success, non-zero on failure
226 #define ast_string_field_init(x, size) \
227 __ast_string_field_init(&(x)->__field_mgr, size, &(x)->__begin_field[0], ast_string_field_count(x))
230 \brief Set a field to a simple string value
231 \param x Pointer to a structure containing fields
232 \param index Index position of the field within the structure
233 \param data String value to be copied into the field
234 \return nothing
236 #define ast_string_field_index_set(x, index, data) do { \
237 char *__zz__ = (char*) (x)->__begin_field[index]; \
238 size_t __dlen__ = strlen(data) + 1; \
239 if ( __dlen__ == 1 ) {\
240 (x)->__begin_field[index] = __ast_string_field_empty; \
241 } else { \
242 if ((__zz__[0] != 0) && (__dlen__ <= (strlen(__zz__) + 1))) { \
243 memcpy(__zz__, data, __dlen__); \
244 } else { \
245 if (((x)->__begin_field[index] = __ast_string_field_alloc_space(&(x)->__field_mgr, __dlen__, &(x)->__begin_field[0], ast_string_field_count(x)))) \
246 memcpy((char*) (x)->__begin_field[index], data, __dlen__); \
249 } while (0)
251 #define ast_string_field_index_logset(x, index, data, logstr) do { \
252 char *__zz__ = (char*) (x)->__begin_field[index]; \
253 size_t __dlen__ = strlen(data) + 1; \
254 if ( __dlen__ == 1 ) {\
255 (x)->__begin_field[index] = __ast_string_field_empty; \
256 } else { \
257 if ((__zz__[0] != 0) && (__dlen__ <= strlen(__zz__) + 1)) { \
258 ast_verbose("%s: ======replacing '%s' with '%s'\n", logstr, __zz__, data); \
259 memcpy(__zz__, data, __dlen__); \
260 } else { \
261 if (((x)->__begin_field[index] = __ast_string_field_alloc_space(&(x)->__field_mgr, __dlen__, &(x)->__begin_field[0], ast_string_field_count(x)))) \
262 ast_verbose("%s: ++++++allocating room for '%s' to replace '%s'\n", logstr, data, __zz__); \
263 memcpy((char*) (x)->__begin_field[index], data, __dlen__); \
266 } while (0)
269 \brief Set a field to a simple string value
270 \param x Pointer to a structure containing fields
271 \param field Name of the field to set
272 \param data String value to be copied into the field
273 \return nothing
275 #define ast_string_field_set(x, field, data) \
276 ast_string_field_index_set(x, ast_string_field_index(x, field), data)
278 #define ast_string_field_logset(x, field, data, logstr) \
279 ast_string_field_index_logset(x, ast_string_field_index(x, field), data, logstr)
282 \brief Set a field to a complex (built) value
283 \param x Pointer to a structure containing fields
284 \param index Index position of the field within the structure
285 \param fmt printf-style format string
286 \param args Arguments for format string
287 \return nothing
289 #define ast_string_field_index_build(x, index, fmt, args...) \
290 __ast_string_field_index_build(&(x)->__field_mgr, &(x)->__begin_field[0], ast_string_field_count(x), index, fmt, args)
293 \brief Set a field to a complex (built) value with prebuilt va_lists.
294 \param x Pointer to a structure containing fields
295 \param index Index position of the field within the structure
296 \param fmt printf-style format string
297 \param args1 Arguments for format string in va_list format
298 \param args2 a second copy of the va_list for the sake of bsd, with no va_list copy operation
299 \return nothing
301 #define ast_string_field_index_build_va(x, index, fmt, args1, args2) \
302 __ast_string_field_index_build_va(&(x)->__field_mgr, &(x)->__begin_field[0], ast_string_field_count(x), index, fmt, args1, args2)
305 \brief Set a field to a complex (built) value
306 \param x Pointer to a structure containing fields
307 \param field Name of the field to set
308 \param fmt printf-style format string
309 \param args Arguments for format string
310 \return nothing
312 #define ast_string_field_build(x, field, fmt, args...) \
313 ast_string_field_index_build(x, ast_string_field_index(x, field), fmt, args)
316 \brief Set a field to a complex (built) value
317 \param x Pointer to a structure containing fields
318 \param field Name of the field to set
319 \param fmt printf-style format string
320 \param argslist a va_list of the args
321 \return nothing
323 #define ast_string_field_build_va(x, field, fmt, args1, args2) \
324 ast_string_field_index_build_va(x, ast_string_field_index(x, field), fmt, args1, args2)
327 \brief Free a field's value.
328 \param x Pointer to a structure containing fields
329 \param index Index position of the field within the structure
330 \return nothing
332 \note Because of the storage pool used, the memory
333 occupied by the field's value is \b not recovered; the field
334 pointer is just changed to point to an empty string.
336 #define ast_string_field_index_free(x, index) do { \
337 (x)->__begin_field[index] = __ast_string_field_empty; \
338 } while(0)
341 \brief Free a field's value.
342 \param x Pointer to a structure containing fields
343 \param field Name of the field to free
344 \return nothing
346 \note Because of the storage pool used, the memory
347 occupied by the field's value is \b not recovered; the field
348 pointer is just changed to point to an empty string.
350 #define ast_string_field_free(x, field) \
351 ast_string_field_index_free(x, ast_string_field_index(x, field))
354 \brief Free the stringfield storage pools attached to a structure
355 \param x Pointer to a structure containing fields
356 \return nothing
358 After calling this macro, fields can no longer be accessed in
359 structure; it should only be called immediately before freeing
360 the structure itself.
362 #define ast_string_field_free_memory(x) do { \
363 struct ast_string_field_pool *this, *prev; \
364 for (this = (x)->__field_mgr.pool; this; this = prev) { \
365 prev = this->prev; \
366 free(this); \
368 } while(0)
371 \brief Free the stringfields in a structure
372 \param x Pointer to a structure containing fields
373 \return nothing
375 After calling this macro, the most recently allocated pool
376 attached to the structure will be available for use by
377 stringfields again.
379 #define ast_string_field_reset_all(x) do { \
380 int index; \
381 for (index = 0; index < ast_string_field_count(x); index++) \
382 ast_string_field_index_free(x, index); \
383 (x)->__field_mgr.used = 0; \
384 (x)->__field_mgr.space = (x)->__field_mgr.size; \
385 } while(0)
387 #endif /* _ASTERISK_STRINGFIELDS_H */