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 (this feature is not used 00061 in this code, but comes from external requirements). 00062 00063 ast_string_field_init(x, 0) will reset fields to the 00064 initial value while keeping the pool allocated. 00065 00066 Reading the fields is much like using 'const char * const' fields in the 00067 structure: you cannot write to the field or to the memory it points to 00068 (XXX perhaps the latter is too much of a restriction since values 00069 are not shared). 00070 00071 Writing to the fields must be done using the wrapper macros listed below; 00072 and assignments are always by value (i.e. strings are copied): 00073 * ast_string_field_set() stores a simple value; 00074 * ast_string_field_build() builds the string using a printf-style; 00075 * ast_string_field_build_va() is the varargs version of the above (for 00076 portability reasons it uses two vararg); 00077 * variants of these function allow passing a pointer to the field 00078 as an argument. 00079 \code 00080 ast_string_field_set(x, foo, "infinite loop"); 00081 ast_string_field_set(x, foo, NULL); // set to an empty string 00082 ast_string_field_ptr_set(x, &x->bar, "right way"); 00083 00084 ast_string_field_build(x, blah, "%d %s", zipcode, city); 00085 ast_string_field_ptr_build(x, &x->blah, "%d %s", zipcode, city); 00086 00087 ast_string_field_build_va(x, bar, fmt, args1, args2) 00088 ast_string_field_ptr_build_va(x, &x->bar, fmt, args1, args2) 00089 \endcode 00090 00091 When the structure instance is no longer needed, the fields 00092 and their storage pool must be freed: 00093 00094 \code 00095 ast_string_field_free_memory(x); 00096 ast_free(x); 00097 \endcode 00098 00099 This completes the API description. 00100 */ 00101 00102 #ifndef _ASTERISK_STRINGFIELDS_H 00103 #define _ASTERISK_STRINGFIELDS_H 00104 00105 #include "asterisk/inline_api.h" 00106 00107 /*! 00108 \internal 00109 \brief An opaque type for managed string fields in structures 00110 00111 Don't declare instances of this type directly; use the AST_STRING_FIELD() 00112 macro instead. 00113 */ 00114 typedef const char * ast_string_field; 00115 00116 /*! 00117 \internal 00118 \brief A constant empty string used for fields that have no other value 00119 */ 00120 extern const char __ast_string_field_empty[]; 00121 00122 /*! 00123 \internal 00124 \brief Structure used to hold a pool of space for string fields 00125 */ 00126 struct ast_string_field_pool { 00127 struct ast_string_field_pool *prev; /*!< pointer to the previous pool, if any */ 00128 char base[0]; /*!< storage space for the fields */ 00129 }; 00130 00131 /*! 00132 \internal 00133 \brief Structure used to manage the storage for a set of string fields. 00134 Because of the way pools are managed, we can only allocate from the topmost 00135 pool, so the numbers here reflect just that. 00136 */ 00137 struct ast_string_field_mgr { 00138 size_t size; /*!< the total size of the current pool */ 00139 size_t used; /*!< the space used in the current pool */ 00140 ast_string_field last_alloc; /*!< the last field allocated */ 00141 }; 00142 00143 /*! 00144 \internal 00145 \brief Attempt to 'grow' an already allocated field to a larger size 00146 \param mgr Pointer to the pool manager structure 00147 \param needed Amount of space needed for this field 00148 \param ptr Pointer to a field within the structure 00149 \return 0 on success, non-zero on failure 00150 00151 This function will attempt to increase the amount of space allocated to 00152 an existing field to the amount requested; this is only possible if the 00153 field was the last field allocated from the current storage pool and 00154 the pool has enough space available. If so, the additional space will be 00155 allocated to this field and the field's address will not be changed. 00156 */ 00157 int __ast_string_field_ptr_grow(struct ast_string_field_mgr *mgr, size_t needed, 00158 const ast_string_field *ptr); 00159 00160 /*! 00161 \internal 00162 \brief Allocate space for a field 00163 \param mgr Pointer to the pool manager structure 00164 \param needed Amount of space needed for this field 00165 \param fields Pointer to the first entry of the field array 00166 \return NULL on failure, an address for the field on success. 00167 00168 This function will allocate the requested amount of space from 00169 the field pool. If the requested amount of space is not available, 00170 an additional pool will be allocated. 00171 */ 00172 ast_string_field __ast_string_field_alloc_space(struct ast_string_field_mgr *mgr, 00173 struct ast_string_field_pool **pool_head, size_t needed); 00174 00175 /*! 00176 \internal 00177 \brief Set a field to a complex (built) value 00178 \param mgr Pointer to the pool manager structure 00179 \param fields Pointer to the first entry of the field array 00180 \param ptr Pointer to a field within the structure 00181 \param format printf-style format string 00182 \return nothing 00183 */ 00184 void __ast_string_field_ptr_build(struct ast_string_field_mgr *mgr, 00185 struct ast_string_field_pool **pool_head, 00186 ast_string_field *ptr, const char *format, ...) __attribute__((format(printf, 4, 5))); 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 fields Pointer to the first entry of the field array 00193 \param ptr Pointer to a field within the structure 00194 \param format printf-style format string 00195 \param args va_list of the args for the format_string 00196 \param args_again a copy of the first va_list for the sake of bsd not having a copy routine 00197 \return nothing 00198 */ 00199 void __ast_string_field_ptr_build_va(struct ast_string_field_mgr *mgr, 00200 struct ast_string_field_pool **pool_head, 00201 ast_string_field *ptr, const char *format, va_list a1, va_list a2) __attribute__((format(printf, 4, 0))); 00202 00203 /*! 00204 \brief Declare a string field 00205 \param name The field name 00206 */ 00207 #define AST_STRING_FIELD(name) const ast_string_field name 00208 00209 /*! 00210 \brief Declare the fields needed in a structure 00211 \param field_list The list of fields to declare, using AST_STRING_FIELD() for each one. 00212 Internally, string fields are stored as a pointer to the head of the pool, 00213 followed by individual string fields, and then a struct ast_string_field_mgr 00214 which describes the space allocated. 00215 We split the two variables so they can be used as markers around the 00216 field_list, and this allows us to determine how many entries are in 00217 the field, and play with them. 00218 In particular, for writing to the fields, we rely on __field_mgr_pool to be 00219 a non-const pointer, so we know it has the same size as ast_string_field, 00220 and we can use it to locate the fields. 00221 */ 00222 #define AST_DECLARE_STRING_FIELDS(field_list) \ 00223 struct ast_string_field_pool *__field_mgr_pool; \ 00224 field_list \ 00225 struct ast_string_field_mgr __field_mgr 00226 00227 /*! 00228 \brief Initialize a field pool and fields 00229 \param x Pointer to a structure containing fields 00230 \param size Amount of storage to allocate. 00231 Use 0 to reset fields to the default value, 00232 and release all but the most recent pool. 00233 size<0 (used internally) means free all pools. 00234 \return 0 on success, non-zero on failure 00235 */ 00236 #define ast_string_field_init(x, size) \ 00237 __ast_string_field_init(&(x)->__field_mgr, &(x)->__field_mgr_pool, size) 00238 00239 /*! \brief free all memory - to be called before destroying the object */ 00240 #define ast_string_field_free_memory(x) \ 00241 __ast_string_field_init(&(x)->__field_mgr, &(x)->__field_mgr_pool, -1) 00242 00243 /*! \internal \brief internal version of ast_string_field_init */ 00244 int __ast_string_field_init(struct ast_string_field_mgr *mgr, 00245 struct ast_string_field_pool **pool_head, int needed); 00246 00247 /*! 00248 \brief Set a field to a simple string value 00249 \param x Pointer to a structure containing fields 00250 \param ptr Pointer to a field within the structure 00251 \param data String value to be copied into the field 00252 \return nothing 00253 */ 00254 #define ast_string_field_ptr_set(x, ptr, data) do { \ 00255 const char *__d__ = (data); \ 00256 size_t __dlen__ = (__d__) ? strlen(__d__) + 1 : 1; \ 00257 const char **__p__ = (const char **) (ptr); \ 00258 char *__q__; \ 00259 if (__dlen__ == 1) \ 00260 *__p__ = __ast_string_field_empty; \ 00261 else if (!__ast_string_field_ptr_grow(&(x)->__field_mgr, __dlen__, ptr)) { \ 00262 __q__ = (char *) *__p__; \ 00263 memcpy(__q__, __d__, __dlen__); \ 00264 } else if ((*__p__ = __ast_string_field_alloc_space(&(x)->__field_mgr, &(x)->__field_mgr_pool, __dlen__))) { \ 00265 __q__ = (char *) *__p__; \ 00266 memcpy(__q__, __d__, __dlen__); \ 00267 } \ 00268 } while (0) 00269 00270 /*! 00271 \brief Set a field to a simple string value 00272 \param x Pointer to a structure containing fields 00273 \param field Name of the field to set 00274 \param data String value to be copied into the field 00275 \return nothing 00276 */ 00277 #define ast_string_field_set(x, field, data) do { \ 00278 ast_string_field_ptr_set(x, &(x)->field, data); \ 00279 } while (0) 00280 00281 /*! 00282 \brief Set a field to a complex (built) value 00283 \param x Pointer to a structure containing fields 00284 \param ptr Pointer to a field within the structure 00285 \param fmt printf-style format string 00286 \param args Arguments for format string 00287 \return nothing 00288 */ 00289 #define ast_string_field_ptr_build(x, ptr, fmt, args...) \ 00290 __ast_string_field_ptr_build(&(x)->__field_mgr, &(x)->__field_mgr_pool, (ast_string_field *) ptr, fmt, args) 00291 00292 /*! 00293 \brief Set a field to a complex (built) value 00294 \param x Pointer to a structure containing fields 00295 \param field Name of the field to set 00296 \param fmt printf-style format string 00297 \param args Arguments for format string 00298 \return nothing 00299 */ 00300 #define ast_string_field_build(x, field, fmt, args...) \ 00301 __ast_string_field_ptr_build(&(x)->__field_mgr, &(x)->__field_mgr_pool, (ast_string_field *) &(x)->field, fmt, args) 00302 00303 /*! 00304 \brief Set a field to a complex (built) value with prebuilt va_lists. 00305 \param x Pointer to a structure containing fields 00306 \param ptr Pointer to a field within the structure 00307 \param fmt printf-style format string 00308 \param args1 Arguments for format string in va_list format 00309 \param args2 a second copy of the va_list for the sake of bsd, with no va_list copy operation 00310 \return nothing 00311 */ 00312 #define ast_string_field_ptr_build_va(x, ptr, fmt, args1, args2) \ 00313 __ast_string_field_ptr_build_va(&(x)->__field_mgr, &(x)->__field_mgr_pool, (ast_string_field *) ptr, fmt, args1, args2) 00314 00315 /*! 00316 \brief Set a field to a complex (built) value 00317 \param x Pointer to a structure containing fields 00318 \param field Name of the field to set 00319 \param fmt printf-style format string 00320 \param args1 argument one 00321 \param args2 argument two 00322 \return nothing 00323 */ 00324 #define ast_string_field_build_va(x, field, fmt, args1, args2) \ 00325 __ast_string_field_ptr_build_va(&(x)->__field_mgr, &(x)->__field_mgr_pool, (ast_string_field *) &(x)->field, fmt, args1, args2) 00326 00327 #endif /* _ASTERISK_STRINGFIELDS_H */