Mon Aug 31 12:30:13 2015

Asterisk developer's documentation


stringfields.h

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 2006, Digium, Inc.
00005  *
00006  * Kevin P. Fleming <kpfleming@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020   \brief String fields in structures
00021 
00022   This file contains objects and macros used to manage string
00023   fields in structures without requiring them to be allocated
00024   as fixed-size buffers or requiring individual allocations for
00025   for each field.
00026 
00027   Using this functionality is quite simple. An example structure
00028   with three fields is defined like this:
00029   
00030   \code
00031   struct sample_fields {
00032      int x1;
00033      AST_DECLARE_STRING_FIELDS(
00034         AST_STRING_FIELD(foo);
00035         AST_STRING_FIELD(bar);
00036         AST_STRING_FIELD(blah);
00037      );
00038      long x2;
00039   };
00040   \endcode
00041   
00042   When an instance of this structure is allocated (either statically or
00043   dynamically), the fields and the pool of storage for them must be
00044   initialized:
00045   
00046   \code
00047   struct sample_fields *x;
00048   
00049   x = ast_calloc(1, sizeof(*x));
00050   if (x == NULL || ast_string_field_init(x, 252)) {
00051    if (x)
00052       ast_free(x);
00053    x = NULL;
00054    ... handle error
00055   }
00056   \endcode
00057 
00058   Fields will default to pointing to an empty string, and will revert to
00059   that when ast_string_field_set() is called with a NULL argument.
00060   A string field will \b never contain NULL.
00061 
00062   ast_string_field_init(x, 0) will reset fields to the
00063   initial value while keeping the pool allocated.
00064   
00065   Reading the fields is much like using 'const char * const' fields in the
00066   structure: you cannot write to the field or to the memory it points to.
00067 
00068   Writing to the fields must be done using the wrapper macros listed below;
00069   and assignments are always by value (i.e. strings are copied):
00070   * ast_string_field_set() stores a simple value;
00071   * ast_string_field_build() builds the string using a printf-style format;
00072   * ast_string_field_build_va() is the varargs version of the above (for
00073     portability reasons it uses two vararg arguments);
00074   * variants of these function allow passing a pointer to the field
00075     as an argument.
00076 
00077   \code
00078   ast_string_field_set(x, foo, "infinite loop");
00079   ast_string_field_set(x, foo, NULL); // set to an empty string
00080   ast_string_field_ptr_set(x, &x->bar, "right way");
00081 
00082   ast_string_field_build(x, blah, "%d %s", zipcode, city);
00083   ast_string_field_ptr_build(x, &x->blah, "%d %s", zipcode, city);
00084 
00085   ast_string_field_build_va(x, bar, fmt, args1, args2)
00086   ast_string_field_ptr_build_va(x, &x->bar, fmt, args1, args2)
00087   \endcode
00088 
00089   When the structure instance is no longer needed, the fields
00090   and their storage pool must be freed:
00091   
00092   \code
00093   ast_string_field_free_memory(x);
00094   ast_free(x);
00095   \endcode
00096 
00097   This completes the API description.
00098 */
00099 
00100 #ifndef _ASTERISK_STRINGFIELDS_H
00101 #define _ASTERISK_STRINGFIELDS_H
00102 
00103 #include "asterisk/inline_api.h"
00104 
00105 /*!
00106   \internal
00107   \brief An opaque type for managed string fields in structures
00108 
00109   Don't declare instances of this type directly; use the AST_STRING_FIELD()
00110   macro instead.
00111 
00112   In addition to the string itself, the amount of space allocated for the
00113   field is stored in the two bytes immediately preceding it.
00114 */
00115 typedef const char * ast_string_field;
00116 
00117 /* the type of storage used to track how many bytes were allocated for a field */
00118 
00119 typedef uint16_t ast_string_field_allocation;
00120 
00121 /*!
00122   \internal
00123   \brief A constant empty string used for fields that have no other value
00124 */
00125 extern const char *__ast_string_field_empty;
00126 
00127 /*!
00128   \internal
00129   \brief Structure used to hold a pool of space for string fields
00130   \note base is aligned so base+used can stay aligned by incrementing used with
00131         aligned numbers only
00132 */
00133 struct ast_string_field_pool {
00134    struct ast_string_field_pool *prev; /*!< pointer to the previous pool, if any */
00135    size_t size;            /*!< the total size of the pool */
00136    size_t used;            /*!< the space used in the pool */
00137    size_t active;          /*!< the amount of space actively in use by fields */
00138    char base[0] __attribute__((aligned(__alignof__(ast_string_field_allocation)))); /*!< storage space for the fields */
00139 };
00140 
00141 /*!
00142   \internal
00143   \brief Structure used to manage the storage for a set of string fields.
00144 */
00145 struct ast_string_field_mgr {
00146    ast_string_field last_alloc;        /*!< the last field allocated */
00147    struct ast_string_field_pool *embedded_pool; /*!< pointer to the embedded pool, if any */
00148 #if defined(__AST_DEBUG_MALLOC)
00149    const char *owner_file;          /*!< filename of owner */
00150    const char *owner_func;          /*!< function name of owner */
00151    int owner_line;               /*!< line number of owner */
00152 #endif
00153 };
00154 
00155 /*!
00156   \internal
00157   \brief Attempt to 'grow' an already allocated field to a larger size
00158   \param mgr Pointer to the pool manager structure
00159   \param needed Amount of space needed for this field
00160   \param ptr Pointer to a field within the structure
00161   \return 0 on success, non-zero on failure
00162 
00163   This function will attempt to increase the amount of space allocated to
00164   an existing field to the amount requested; this is only possible if the
00165   field was the last field allocated from the current storage pool and
00166   the pool has enough space available. If so, the additional space will be
00167   allocated to this field and the field's address will not be changed.
00168 */
00169 int __ast_string_field_ptr_grow(struct ast_string_field_mgr *mgr,
00170             struct ast_string_field_pool **pool_head, size_t needed,
00171             const ast_string_field *ptr);
00172 
00173 /*!
00174   \internal
00175   \brief Allocate space for a field
00176   \param mgr Pointer to the pool manager structure
00177   \param needed Amount of space needed for this field
00178   \param fields Pointer to the first entry of the field array
00179   \return NULL on failure, an address for the field on success.
00180 
00181   This function will allocate the requested amount of space from
00182   the field pool. If the requested amount of space is not available,
00183   an additional pool will be allocated.
00184 */
00185 ast_string_field __ast_string_field_alloc_space(struct ast_string_field_mgr *mgr,
00186                   struct ast_string_field_pool **pool_head, size_t needed);
00187 
00188 /*!
00189   \internal
00190   \brief Set a field to a complex (built) value
00191   \param mgr Pointer to the pool manager structure
00192   \param pool_head Pointer to the current pool
00193   \param ptr Pointer to a field within the structure
00194   \param format printf-style format string
00195   \return nothing
00196 */
00197 void __ast_string_field_ptr_build(struct ast_string_field_mgr *mgr,
00198               struct ast_string_field_pool **pool_head,
00199               ast_string_field *ptr, const char *format, ...) __attribute__((format(printf, 4, 5)));
00200 
00201 /*!
00202   \internal
00203   \brief Set a field to a complex (built) value
00204   \param mgr Pointer to the pool manager structure
00205   \param pool_head Pointer to the current pool
00206   \param ptr Pointer to a field within the structure
00207   \param format printf-style format string
00208   \param args va_list of the args for the format_string
00209   \param args_again a copy of the first va_list for the sake of bsd not having a copy routine
00210   \return nothing
00211 */
00212 void __ast_string_field_ptr_build_va(struct ast_string_field_mgr *mgr,
00213                  struct ast_string_field_pool **pool_head,
00214                  ast_string_field *ptr, const char *format, va_list a1, va_list a2) __attribute__((format(printf, 4, 0)));
00215 
00216 /*!
00217   \brief Declare a string field
00218   \param name The field name
00219 */
00220 #define AST_STRING_FIELD(name) const ast_string_field name
00221 
00222 /*!
00223   \brief Declare the fields needed in a structure
00224   \param field_list The list of fields to declare, using AST_STRING_FIELD() for each one.
00225   Internally, string fields are stored as a pointer to the head of the pool,
00226   followed by individual string fields, and then a struct ast_string_field_mgr
00227   which describes the space allocated.
00228   We split the two variables so they can be used as markers around the
00229   field_list, and this allows us to determine how many entries are in
00230   the field, and play with them.
00231   In particular, for writing to the fields, we rely on __field_mgr_pool to be
00232   a non-const pointer, so we know it has the same size as ast_string_field,
00233   and we can use it to locate the fields.
00234 */
00235 #define AST_DECLARE_STRING_FIELDS(field_list) \
00236    struct ast_string_field_pool *__field_mgr_pool; \
00237    field_list              \
00238    struct ast_string_field_mgr __field_mgr
00239 
00240 /*!
00241   \brief Initialize a field pool and fields
00242   \param x Pointer to a structure containing fields
00243   \param size Amount of storage to allocate.
00244    Use 0 to reset fields to the default value,
00245    and release all but the most recent pool.
00246    size<0 (used internally) means free all pools.
00247   \return 0 on success, non-zero on failure
00248 */
00249 #define ast_string_field_init(x, size) \
00250    __ast_string_field_init(&(x)->__field_mgr, &(x)->__field_mgr_pool, size, __FILE__, __LINE__, __PRETTY_FUNCTION__)
00251 
00252 /*! \brief free all memory - to be called before destroying the object */
00253 #define ast_string_field_free_memory(x)   \
00254    __ast_string_field_init(&(x)->__field_mgr, &(x)->__field_mgr_pool, -1, __FILE__, __LINE__, __PRETTY_FUNCTION__)
00255 
00256 /*!
00257  * \internal
00258  * \brief internal version of ast_string_field_init
00259  */
00260 int __ast_string_field_init(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head,
00261              int needed, const char *file, int lineno, const char *func);
00262 
00263 /*!
00264  * \brief Allocate a structure with embedded stringfields in a single allocation
00265  * \param n Number of structures to allocate (see ast_calloc)
00266  * \param type The type of structure to allocate
00267  * \param size The number of bytes of space (minimum) to allocate for stringfields to use
00268  *
00269  * This function will allocate memory for one or more structures that use stringfields, and
00270  * also allocate space for the stringfields and initialize the stringfield management
00271  * structure embedded in the outer structure.
00272  *
00273  * \since 1.8
00274  */
00275 #define ast_calloc_with_stringfields(n, type, size) \
00276    __ast_calloc_with_stringfields(n, sizeof(type), offsetof(type, __field_mgr), offsetof(type, __field_mgr_pool), \
00277                    size, __FILE__, __LINE__, __PRETTY_FUNCTION__)
00278 
00279 /*!
00280  * \internal
00281  * \brief internal version of ast_calloc_with_stringfields
00282  */
00283 void * attribute_malloc __ast_calloc_with_stringfields(unsigned int num_structs, size_t struct_size, size_t field_mgr_offset,
00284                          size_t field_mgr_pool_offset, size_t pool_size, const char *file,
00285                          int lineno, const char *func);
00286 
00287 /*!
00288   \internal
00289   \brief Release a field's allocation from a pool
00290   \param pool_head Pointer to the current pool
00291   \param ptr Field to be released
00292   \return nothing
00293 
00294   This function will search the pool list to find the pool that contains
00295   the allocation for the specified field, then remove the field's allocation
00296   from that pool's 'active' count. If the pool's active count reaches zero,
00297   and it is not the current pool, then it will be freed.
00298  */
00299 void __ast_string_field_release_active(struct ast_string_field_pool *pool_head,
00300                    const ast_string_field ptr);
00301 
00302 /*!
00303   \brief Macro to provide access to the allocation field that lives immediately in front of a string field
00304   \param x Pointer to the string field
00305 
00306   Note that x must be a pointer to a byte-sized type -- normally (char *) -- or this calculation
00307   would break horribly
00308 */
00309 #define AST_STRING_FIELD_ALLOCATION(x) *((ast_string_field_allocation *) (x - __alignof__(ast_string_field_allocation)))
00310 
00311 /*!
00312   \brief Set a field to a simple string value
00313   \param x Pointer to a structure containing fields
00314   \param ptr Pointer to a field within the structure
00315   \param data String value to be copied into the field 
00316   \return nothing
00317 */
00318 #define ast_string_field_ptr_set(x, ptr, data) do {                           \
00319    const char *__d__ = (data);                                 \
00320    size_t __dlen__ = (__d__) ? strlen(__d__) + 1 : 1;                      \
00321    ast_string_field *__p__ = (ast_string_field *) (ptr);                      \
00322    ast_string_field target = *__p__;                              \
00323    if (__dlen__ == 1) {                                  \
00324       __ast_string_field_release_active((x)->__field_mgr_pool, *__p__);             \
00325       *__p__ = __ast_string_field_empty;                          \
00326    } else if ((__dlen__ <= AST_STRING_FIELD_ALLOCATION(*__p__)) ||                     \
00327          (!__ast_string_field_ptr_grow(&(x)->__field_mgr, &(x)->__field_mgr_pool, __dlen__, __p__)) ||   \
00328          (target = __ast_string_field_alloc_space(&(x)->__field_mgr, &(x)->__field_mgr_pool, __dlen__))) {  \
00329       if (target != *__p__) {                               \
00330          __ast_string_field_release_active((x)->__field_mgr_pool, *__p__);          \
00331          *__p__ = target;                             \
00332       }                                      \
00333       memcpy(* (void **) __p__, __d__, __dlen__);                       \
00334    }                                         \
00335    } while (0)
00336 
00337 /*!
00338   \brief Set a field to a simple string value
00339   \param x Pointer to a structure containing fields
00340   \param field Name of the field to set
00341   \param data String value to be copied into the field
00342   \return nothing
00343 */
00344 #define ast_string_field_set(x, field, data) do {     \
00345    ast_string_field_ptr_set(x, &(x)->field, data);    \
00346    } while (0)
00347 
00348 /*!
00349   \brief Set a field to a complex (built) value
00350   \param x Pointer to a structure containing fields
00351   \param ptr Pointer to a field within the structure
00352   \param fmt printf-style format string
00353   \param args Arguments for format string
00354   \return nothing
00355 */
00356 #define ast_string_field_ptr_build(x, ptr, fmt, args...) \
00357    __ast_string_field_ptr_build(&(x)->__field_mgr, &(x)->__field_mgr_pool, (ast_string_field *) ptr, fmt, args)
00358 
00359 /*!
00360   \brief Set a field to a complex (built) value
00361   \param x Pointer to a structure containing fields
00362   \param field Name of the field to set
00363   \param fmt printf-style format string
00364   \param args Arguments for format string
00365   \return nothing
00366 */
00367 #define ast_string_field_build(x, field, fmt, args...) \
00368    __ast_string_field_ptr_build(&(x)->__field_mgr, &(x)->__field_mgr_pool, (ast_string_field *) &(x)->field, fmt, args)
00369 
00370 /*!
00371   \brief Set a field to a complex (built) value with prebuilt va_lists.
00372   \param x Pointer to a structure containing fields
00373   \param ptr Pointer to a field within the structure
00374   \param fmt printf-style format string
00375   \param args1 Arguments for format string in va_list format
00376   \param args2 a second copy of the va_list for the sake of bsd, with no va_list copy operation
00377   \return nothing
00378 */
00379 #define ast_string_field_ptr_build_va(x, ptr, fmt, args1, args2) \
00380    __ast_string_field_ptr_build_va(&(x)->__field_mgr, &(x)->__field_mgr_pool, (ast_string_field *) ptr, fmt, args1, args2)
00381 
00382 /*!
00383   \brief Set a field to a complex (built) value
00384   \param x Pointer to a structure containing fields
00385   \param field Name of the field to set
00386   \param fmt printf-style format string
00387   \param args1 argument one
00388   \param args2 argument two
00389   \return nothing
00390 */
00391 #define ast_string_field_build_va(x, field, fmt, args1, args2) \
00392    __ast_string_field_ptr_build_va(&(x)->__field_mgr, &(x)->__field_mgr_pool, (ast_string_field *) &(x)->field, fmt, args1, args2)
00393 
00394 #endif /* _ASTERISK_STRINGFIELDS_H */

Generated on 31 Aug 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1