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 /*! 00118 \internal 00119 \brief A constant empty string used for fields that have no other value 00120 */ 00121 extern const char *__ast_string_field_empty; 00122 00123 /*! 00124 \internal 00125 \brief Structure used to hold a pool of space for string fields 00126 */ 00127 struct ast_string_field_pool { 00128 struct ast_string_field_pool *prev; /*!< pointer to the previous pool, if any */ 00129 size_t size; /*!< the total size of the pool */ 00130 size_t used; /*!< the space used in the pool */ 00131 size_t active; /*!< the amount of space actively in use by fields */ 00132 char base[0]; /*!< storage space for the fields */ 00133 }; 00134 00135 /*! 00136 \internal 00137 \brief Structure used to manage the storage for a set of string fields. 00138 */ 00139 struct ast_string_field_mgr { 00140 ast_string_field last_alloc; /*!< the last field allocated */ 00141 struct ast_string_field_pool *embedded_pool; /*!< pointer to the embedded pool, if any */ 00142 #if defined(__AST_DEBUG_MALLOC) 00143 const char *owner_file; /*!< filename of owner */ 00144 const char *owner_func; /*!< function name of owner */ 00145 int owner_line; /*!< line number of owner */ 00146 #endif 00147 }; 00148 00149 /*! 00150 \internal 00151 \brief Attempt to 'grow' an already allocated field to a larger size 00152 \param mgr Pointer to the pool manager structure 00153 \param needed Amount of space needed for this field 00154 \param ptr Pointer to a field within the structure 00155 \return 0 on success, non-zero on failure 00156 00157 This function will attempt to increase the amount of space allocated to 00158 an existing field to the amount requested; this is only possible if the 00159 field was the last field allocated from the current storage pool and 00160 the pool has enough space available. If so, the additional space will be 00161 allocated to this field and the field's address will not be changed. 00162 */ 00163 int __ast_string_field_ptr_grow(struct ast_string_field_mgr *mgr, 00164 struct ast_string_field_pool **pool_head, size_t needed, 00165 const ast_string_field *ptr); 00166 00167 /*! 00168 \internal 00169 \brief Allocate space for a field 00170 \param mgr Pointer to the pool manager structure 00171 \param needed Amount of space needed for this field 00172 \param fields Pointer to the first entry of the field array 00173 \return NULL on failure, an address for the field on success. 00174 00175 This function will allocate the requested amount of space from 00176 the field pool. If the requested amount of space is not available, 00177 an additional pool will be allocated. 00178 */ 00179 ast_string_field __ast_string_field_alloc_space(struct ast_string_field_mgr *mgr, 00180 struct ast_string_field_pool **pool_head, size_t needed); 00181 00182 /*! 00183 \internal 00184 \brief Set a field to a complex (built) value 00185 \param mgr Pointer to the pool manager structure 00186 \param pool_head Pointer to the current pool 00187 \param ptr Pointer to a field within the structure 00188 \param format printf-style format string 00189 \return nothing 00190 */ 00191 void __ast_string_field_ptr_build(struct ast_string_field_mgr *mgr, 00192 struct ast_string_field_pool **pool_head, 00193 ast_string_field *ptr, const char *format, ...) __attribute__((format(printf, 4, 5))); 00194 00195 /*! 00196 \internal 00197 \brief Set a field to a complex (built) value 00198 \param mgr Pointer to the pool manager structure 00199 \param pool_head Pointer to the current pool 00200 \param ptr Pointer to a field within the structure 00201 \param format printf-style format string 00202 \param args va_list of the args for the format_string 00203 \param args_again a copy of the first va_list for the sake of bsd not having a copy routine 00204 \return nothing 00205 */ 00206 void __ast_string_field_ptr_build_va(struct ast_string_field_mgr *mgr, 00207 struct ast_string_field_pool **pool_head, 00208 ast_string_field *ptr, const char *format, va_list a1, va_list a2) __attribute__((format(printf, 4, 0))); 00209 00210 /*! 00211 \brief Declare a string field 00212 \param name The field name 00213 */ 00214 #define AST_STRING_FIELD(name) const ast_string_field name 00215 00216 /*! 00217 \brief Declare the fields needed in a structure 00218 \param field_list The list of fields to declare, using AST_STRING_FIELD() for each one. 00219 Internally, string fields are stored as a pointer to the head of the pool, 00220 followed by individual string fields, and then a struct ast_string_field_mgr 00221 which describes the space allocated. 00222 We split the two variables so they can be used as markers around the 00223 field_list, and this allows us to determine how many entries are in 00224 the field, and play with them. 00225 In particular, for writing to the fields, we rely on __field_mgr_pool to be 00226 a non-const pointer, so we know it has the same size as ast_string_field, 00227 and we can use it to locate the fields. 00228 */ 00229 #define AST_DECLARE_STRING_FIELDS(field_list) \ 00230 struct ast_string_field_pool *__field_mgr_pool; \ 00231 field_list \ 00232 struct ast_string_field_mgr __field_mgr 00233 00234 /*! 00235 \brief Initialize a field pool and fields 00236 \param x Pointer to a structure containing fields 00237 \param size Amount of storage to allocate. 00238 Use 0 to reset fields to the default value, 00239 and release all but the most recent pool. 00240 size<0 (used internally) means free all pools. 00241 \return 0 on success, non-zero on failure 00242 */ 00243 #define ast_string_field_init(x, size) \ 00244 __ast_string_field_init(&(x)->__field_mgr, &(x)->__field_mgr_pool, size, __FILE__, __LINE__, __PRETTY_FUNCTION__) 00245 00246 /*! \brief free all memory - to be called before destroying the object */ 00247 #define ast_string_field_free_memory(x) \ 00248 __ast_string_field_init(&(x)->__field_mgr, &(x)->__field_mgr_pool, -1, __FILE__, __LINE__, __PRETTY_FUNCTION__) 00249 00250 /*! 00251 * \internal 00252 * \brief internal version of ast_string_field_init 00253 */ 00254 int __ast_string_field_init(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head, 00255 int needed, const char *file, int lineno, const char *func); 00256 00257 /*! 00258 * \brief Allocate a structure with embedded stringfields in a single allocation 00259 * \param n Number of structures to allocate (see ast_calloc) 00260 * \param type The type of structure to allocate 00261 * \param size The number of bytes of space (minimum) to allocate for stringfields to use 00262 * 00263 * This function will allocate memory for one or more structures that use stringfields, and 00264 * also allocate space for the stringfields and initialize the stringfield management 00265 * structure embedded in the outer structure. 00266 * 00267 * \since 1.8 00268 */ 00269 #define ast_calloc_with_stringfields(n, type, size) \ 00270 __ast_calloc_with_stringfields(n, sizeof(type), offsetof(type, __field_mgr), offsetof(type, __field_mgr_pool), \ 00271 size, __FILE__, __LINE__, __PRETTY_FUNCTION__) 00272 00273 /*! 00274 * \internal 00275 * \brief internal version of ast_calloc_with_stringfields 00276 */ 00277 void * attribute_malloc __ast_calloc_with_stringfields(unsigned int num_structs, size_t struct_size, size_t field_mgr_offset, 00278 size_t field_mgr_pool_offset, size_t pool_size, const char *file, 00279 int lineno, const char *func); 00280 00281 /*! 00282 \internal 00283 \brief Release a field's allocation from a pool 00284 \param pool_head Pointer to the current pool 00285 \param ptr Field to be released 00286 \return nothing 00287 00288 This function will search the pool list to find the pool that contains 00289 the allocation for the specified field, then remove the field's allocation 00290 from that pool's 'active' count. If the pool's active count reaches zero, 00291 and it is not the current pool, then it will be freed. 00292 */ 00293 void __ast_string_field_release_active(struct ast_string_field_pool *pool_head, 00294 const ast_string_field ptr); 00295 00296 /* the type of storage used to track how many bytes were allocated for a field */ 00297 00298 typedef uint16_t ast_string_field_allocation; 00299 00300 /*! 00301 \brief Macro to provide access to the allocation field that lives immediately in front of a string field 00302 \param x Pointer to the string field 00303 */ 00304 #define AST_STRING_FIELD_ALLOCATION(x) *((ast_string_field_allocation *) (x - sizeof(ast_string_field_allocation))) 00305 00306 /*! 00307 \brief Set a field to a simple string value 00308 \param x Pointer to a structure containing fields 00309 \param ptr Pointer to a field within the structure 00310 \param data String value to be copied into the field 00311 \return nothing 00312 */ 00313 #define ast_string_field_ptr_set(x, ptr, data) do { \ 00314 const char *__d__ = (data); \ 00315 size_t __dlen__ = (__d__) ? strlen(__d__) + 1 : 1; \ 00316 ast_string_field *__p__ = (ast_string_field *) (ptr); \ 00317 if (__dlen__ == 1) { \ 00318 __ast_string_field_release_active((x)->__field_mgr_pool, *__p__); \ 00319 *__p__ = __ast_string_field_empty; \ 00320 } else if ((__dlen__ <= AST_STRING_FIELD_ALLOCATION(*__p__)) || \ 00321 (!__ast_string_field_ptr_grow(&(x)->__field_mgr, &(x)->__field_mgr_pool, __dlen__, __p__)) || \ 00322 (*__p__ = __ast_string_field_alloc_space(&(x)->__field_mgr, &(x)->__field_mgr_pool, __dlen__))) { \ 00323 if (*__p__ != (*ptr)) { \ 00324 __ast_string_field_release_active((x)->__field_mgr_pool, (*ptr)); \ 00325 } \ 00326 memcpy(* (void **) __p__, __d__, __dlen__); \ 00327 } \ 00328 } while (0) 00329 00330 /*! 00331 \brief Set a field to a simple string value 00332 \param x Pointer to a structure containing fields 00333 \param field Name of the field to set 00334 \param data String value to be copied into the field 00335 \return nothing 00336 */ 00337 #define ast_string_field_set(x, field, data) do { \ 00338 ast_string_field_ptr_set(x, &(x)->field, data); \ 00339 } while (0) 00340 00341 /*! 00342 \brief Set a field to a complex (built) value 00343 \param x Pointer to a structure containing fields 00344 \param ptr Pointer to a field within the structure 00345 \param fmt printf-style format string 00346 \param args Arguments for format string 00347 \return nothing 00348 */ 00349 #define ast_string_field_ptr_build(x, ptr, fmt, args...) \ 00350 __ast_string_field_ptr_build(&(x)->__field_mgr, &(x)->__field_mgr_pool, (ast_string_field *) ptr, fmt, args) 00351 00352 /*! 00353 \brief Set a field to a complex (built) value 00354 \param x Pointer to a structure containing fields 00355 \param field Name of the field to set 00356 \param fmt printf-style format string 00357 \param args Arguments for format string 00358 \return nothing 00359 */ 00360 #define ast_string_field_build(x, field, fmt, args...) \ 00361 __ast_string_field_ptr_build(&(x)->__field_mgr, &(x)->__field_mgr_pool, (ast_string_field *) &(x)->field, fmt, args) 00362 00363 /*! 00364 \brief Set a field to a complex (built) value with prebuilt va_lists. 00365 \param x Pointer to a structure containing fields 00366 \param ptr Pointer to a field within the structure 00367 \param fmt printf-style format string 00368 \param args1 Arguments for format string in va_list format 00369 \param args2 a second copy of the va_list for the sake of bsd, with no va_list copy operation 00370 \return nothing 00371 */ 00372 #define ast_string_field_ptr_build_va(x, ptr, fmt, args1, args2) \ 00373 __ast_string_field_ptr_build_va(&(x)->__field_mgr, &(x)->__field_mgr_pool, (ast_string_field *) ptr, fmt, args1, args2) 00374 00375 /*! 00376 \brief Set a field to a complex (built) value 00377 \param x Pointer to a structure containing fields 00378 \param field Name of the field to set 00379 \param fmt printf-style format string 00380 \param args1 argument one 00381 \param args2 argument two 00382 \return nothing 00383 */ 00384 #define ast_string_field_build_va(x, field, fmt, args1, args2) \ 00385 __ast_string_field_ptr_build_va(&(x)->__field_mgr, &(x)->__field_mgr_pool, (ast_string_field *) &(x)->field, fmt, args1, args2) 00386 00387 #endif /* _ASTERISK_STRINGFIELDS_H */