String fields in structures. More...
#include "asterisk/inline_api.h"

Go to the source code of this file.
Data Structures | |
| struct | ast_string_field_mgr |
| struct | ast_string_field_pool |
Defines | |
| #define | AST_DECLARE_STRING_FIELDS(field_list) |
| Declare the fields needed in a structure. | |
| #define | AST_STRING_FIELD(name) const ast_string_field name |
| Declare a string field. | |
| #define | ast_string_field_build(x, field, fmt, args...) __ast_string_field_ptr_build(&(x)->__field_mgr, &(x)->__field_mgr_pool, (ast_string_field *) &(x)->field, fmt, args) |
| Set a field to a complex (built) value. | |
| #define | ast_string_field_build_va(x, field, fmt, args1, args2) __ast_string_field_ptr_build_va(&(x)->__field_mgr, &(x)->__field_mgr_pool, (ast_string_field *) &(x)->field, fmt, args1, args2) |
| Set a field to a complex (built) value. | |
| #define | ast_string_field_free_memory(x) __ast_string_field_init(&(x)->__field_mgr, &(x)->__field_mgr_pool, -1, __FILE__, __LINE__, __PRETTY_FUNCTION__) |
| free all memory - to be called before destroying the object | |
| #define | ast_string_field_init(x, size) __ast_string_field_init(&(x)->__field_mgr, &(x)->__field_mgr_pool, size, __FILE__, __LINE__, __PRETTY_FUNCTION__) |
| Initialize a field pool and fields. | |
| #define | ast_string_field_ptr_build(x, ptr, fmt, args...) __ast_string_field_ptr_build(&(x)->__field_mgr, &(x)->__field_mgr_pool, (ast_string_field *) ptr, fmt, args) |
| Set a field to a complex (built) value. | |
| #define | ast_string_field_ptr_build_va(x, ptr, fmt, args1, args2) __ast_string_field_ptr_build_va(&(x)->__field_mgr, &(x)->__field_mgr_pool, (ast_string_field *) ptr, fmt, args1, args2) |
| Set a field to a complex (built) value with prebuilt va_lists. | |
| #define | ast_string_field_ptr_set(x, ptr, data) |
| Set a field to a simple string value. | |
| #define | ast_string_field_set(x, field, data) |
| Set a field to a simple string value. | |
Typedefs | |
| typedef const char * | ast_string_field |
Functions | |
| ast_string_field | __ast_string_field_alloc_space (struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head, size_t needed) |
| int | __ast_string_field_init (struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head, int needed, const char *file, int lineno, const char *func) |
| void | __ast_string_field_ptr_build (struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head, ast_string_field *ptr, const char *format,...) |
| void | __ast_string_field_ptr_build_va (struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head, ast_string_field *ptr, const char *format, va_list a1, va_list a2) |
| int | __ast_string_field_ptr_grow (struct ast_string_field_mgr *mgr, size_t needed, const ast_string_field *ptr) |
Variables | |
| const char | __ast_string_field_empty [] |
String fields in structures.
This file contains objects and macros used to manage string fields in structures without requiring them to be allocated as fixed-size buffers or requiring individual allocations for for each field.
Using this functionality is quite simple. An example structure with three fields is defined like this:
struct sample_fields { int x1; AST_DECLARE_STRING_FIELDS( AST_STRING_FIELD(foo); AST_STRING_FIELD(bar); AST_STRING_FIELD(blah); ); long x2; };
When an instance of this structure is allocated (either statically or dynamically), the fields and the pool of storage for them must be initialized:
struct sample_fields *x; x = ast_calloc(1, sizeof(*x)); if (x == NULL || ast_string_field_init(x, 252)) { if (x) ast_free(x); x = NULL; ... handle error }
Fields will default to pointing to an empty string, and will revert to that when ast_string_field_set() is called with a NULL argument. A string field will never contain NULL (this feature is not used in this code, but comes from external requirements).
ast_string_field_init(x, 0) will reset fields to the initial value while keeping the pool allocated.
Reading the fields is much like using 'const char * const' fields in the structure: you cannot write to the field or to the memory it points to (XXX perhaps the latter is too much of a restriction since values are not shared).
Writing to the fields must be done using the wrapper macros listed below; and assignments are always by value (i.e. strings are copied): ast_string_field_set() stores a simple value; ast_string_field_build() builds the string using a printf-style; ast_string_field_build_va() is the varargs version of the above (for portability reasons it uses two vararg); variants of these function allow passing a pointer to the field as an argument.
ast_string_field_set(x, foo, "infinite loop"); ast_string_field_set(x, foo, NULL); // set to an empty string ast_string_field_ptr_set(x, &x->bar, "right way"); ast_string_field_build(x, blah, "%d %s", zipcode, city); ast_string_field_ptr_build(x, &x->blah, "%d %s", zipcode, city); ast_string_field_build_va(x, bar, fmt, args1, args2) ast_string_field_ptr_build_va(x, &x->bar, fmt, args1, args2)
When the structure instance is no longer needed, the fields and their storage pool must be freed:
ast_string_field_free_memory(x); ast_free(x);
This completes the API description.
Definition in file stringfields.h.
| #define AST_DECLARE_STRING_FIELDS | ( | field_list | ) |
struct ast_string_field_pool *__field_mgr_pool; \ field_list \ struct ast_string_field_mgr __field_mgr
Declare the fields needed in a structure.
| field_list | The list of fields to declare, using AST_STRING_FIELD() for each one. Internally, string fields are stored as a pointer to the head of the pool, followed by individual string fields, and then a struct ast_string_field_mgr which describes the space allocated. We split the two variables so they can be used as markers around the field_list, and this allows us to determine how many entries are in the field, and play with them. In particular, for writing to the fields, we rely on __field_mgr_pool to be a non-const pointer, so we know it has the same size as ast_string_field, and we can use it to locate the fields. |
Definition at line 227 of file stringfields.h.
| #define AST_STRING_FIELD | ( | name | ) | const ast_string_field name |
Declare a string field.
| name | The field name |
Definition at line 212 of file stringfields.h.
| #define ast_string_field_build | ( | x, | |||
| field, | |||||
| fmt, | |||||
| args... | ) | __ast_string_field_ptr_build(&(x)->__field_mgr, &(x)->__field_mgr_pool, (ast_string_field *) &(x)->field, fmt, args) |
Set a field to a complex (built) value.
| x | Pointer to a structure containing fields | |
| field | Name of the field to set | |
| fmt | printf-style format string | |
| args | Arguments for format string |
Definition at line 308 of file stringfields.h.
Referenced by __ast_channel_alloc_ap(), build_callid_pvt(), build_callid_registry(), build_contact(), build_profile(), build_rpid(), build_user(), create_addr_from_peer(), handle_request_subscribe(), handle_response(), mgcp_new(), parse_moved_contact(), parse_register_contact(), pri_fixup_principle(), set_nonce_randdata(), sip_sendhtml(), sip_sipredirect(), and unistim_new().
| #define ast_string_field_build_va | ( | x, | |||
| field, | |||||
| fmt, | |||||
| args1, | |||||
| args2 | ) | __ast_string_field_ptr_build_va(&(x)->__field_mgr, &(x)->__field_mgr_pool, (ast_string_field *) &(x)->field, fmt, args1, args2) |
Set a field to a complex (built) value.
| x | Pointer to a structure containing fields | |
| field | Name of the field to set | |
| fmt | printf-style format string | |
| args1 | argument one | |
| args2 | argument two |
Definition at line 332 of file stringfields.h.
Referenced by __ast_channel_alloc_ap().
| #define ast_string_field_free_memory | ( | x | ) | __ast_string_field_init(&(x)->__field_mgr, &(x)->__field_mgr_pool, -1, __FILE__, __LINE__, __PRETTY_FUNCTION__) |
free all memory - to be called before destroying the object
Definition at line 245 of file stringfields.h.
Referenced by __ast_channel_alloc_ap(), __sip_destroy(), ast_channel_free(), ast_unregister_groups(), build_user(), delete_extension(), delete_file(), destroy_jack_data(), destroy_mailbox_mapping(), destroy_queue(), destroy_station(), destroy_trunk(), exception_store_free(), load_module(), peer_destructor(), profile_destructor(), pvt_destructor(), route_destructor(), sip_registry_destroy(), tds_unload_module(), temp_pvt_cleanup(), and user_destructor().
| #define ast_string_field_init | ( | x, | |||
| size | ) | __ast_string_field_init(&(x)->__field_mgr, &(x)->__field_mgr_pool, size, __FILE__, __LINE__, __PRETTY_FUNCTION__) |
Initialize a field pool and fields.
| x | Pointer to a structure containing fields | |
| size | Amount of storage to allocate. Use 0 to reset fields to the default value, and release all but the most recent pool. size<0 (used internally) means free all pools. |
Definition at line 241 of file stringfields.h.
Referenced by __ast_channel_alloc_ap(), alloc_queue(), append_mailbox_mapping(), build_extension(), build_peer(), build_profile(), build_route(), build_user(), init_pvt(), jack_data_alloc(), load_module(), new_iax(), pbx_builtin_raise_exception(), register_group(), register_group_feature(), sip_alloc(), sip_register(), sla_build_station(), sla_build_trunk(), tds_load_module(), temp_pvt_init(), and transmit_response_using_temp().
| #define ast_string_field_ptr_build | ( | x, | |||
| ptr, | |||||
| fmt, | |||||
| args... | ) | __ast_string_field_ptr_build(&(x)->__field_mgr, &(x)->__field_mgr_pool, (ast_string_field *) ptr, fmt, args) |
Set a field to a complex (built) value.
| x | Pointer to a structure containing fields | |
| ptr | Pointer to a field within the structure | |
| fmt | printf-style format string | |
| args | Arguments for format string |
Definition at line 297 of file stringfields.h.
| #define ast_string_field_ptr_build_va | ( | x, | |||
| ptr, | |||||
| fmt, | |||||
| args1, | |||||
| args2 | ) | __ast_string_field_ptr_build_va(&(x)->__field_mgr, &(x)->__field_mgr_pool, (ast_string_field *) ptr, fmt, args1, args2) |
Set a field to a complex (built) value with prebuilt va_lists.
| x | Pointer to a structure containing fields | |
| ptr | Pointer to a field within the structure | |
| fmt | printf-style format string | |
| args1 | Arguments for format string in va_list format | |
| args2 | a second copy of the va_list for the sake of bsd, with no va_list copy operation |
Definition at line 320 of file stringfields.h.
| #define ast_string_field_ptr_set | ( | x, | |||
| ptr, | |||||
| data | ) |
Set a field to a simple string value.
| x | Pointer to a structure containing fields | |
| ptr | Pointer to a field within the structure | |
| data | String value to be copied into the field |
Definition at line 262 of file stringfields.h.
Referenced by reply_digest().
| #define ast_string_field_set | ( | x, | |||
| field, | |||||
| data | ) |
do { \ ast_string_field_ptr_set(x, &(x)->field, data); \ } while (0)
Set a field to a simple string value.
| x | Pointer to a structure containing fields | |
| field | Name of the field to set | |
| data | String value to be copied into the field |
Definition at line 285 of file stringfields.h.
Referenced by __ast_channel_alloc_ap(), __find_callno(), __oh323_new(), acf_channel_write(), agent_new(), alloc_queue(), alsa_new(), append_mailbox_mapping(), ast_call_forward(), ast_cdr_setaccount(), ast_change_name(), ast_do_masquerade(), ast_feature_request_and_dial(), ast_iax2_new(), authenticate_reply(), authenticate_request(), authenticate_verify(), begin_dial_channel(), build_extension(), build_peer(), build_profile(), build_route(), build_rpid(), build_user(), cache_get_callno_locked(), check_access(), check_peer_ok(), check_user_full(), conf_start_moh(), console_new(), create_addr(), create_addr_from_peer(), dahdi_new(), dial_exec_full(), disa_exec(), do_forward(), extract_uri(), get_also_info(), get_destination(), get_rdnis(), gtalk_new(), handle_incoming(), handle_options(), handle_request_bye(), handle_request_invite(), handle_request_options(), handle_request_refer(), handle_response(), handle_response_invite(), handle_response_notify(), iax2_call(), iax2_request(), init_pvt(), init_queue(), initreqprep(), jingle_new(), load_module(), local_call(), mgcp_new(), monitor_dial(), nbs_new(), new_iax(), oss_new(), parse_moved_contact(), parse_ok_contact(), parse_register_contact(), pbx_builtin_raise_exception(), phone_new(), queue_set_param(), read_config(), register_group(), register_group_feature(), register_verify(), registry_authrequest(), replace_cid(), reply_digest(), reqprep(), respprep(), ring_entry(), save_osptoken(), set_moh_exec(), set_pvt_defaults(), sip_alloc(), sip_call(), sip_new(), sip_poke_peer(), sip_register(), sip_request_call(), sip_set_redirstr(), skinny_new(), sla_build_station(), sla_build_trunk(), socket_process(), store_callerid(), tds_load_module(), transmit_refer(), transmit_register(), transmit_response_using_temp(), unistim_new(), usbradio_new(), vm_execmain(), and wait_for_answer().
| typedef const char* ast_string_field |
Definition at line 114 of file stringfields.h.
| ast_string_field __ast_string_field_alloc_space | ( | struct ast_string_field_mgr * | mgr, | |
| struct ast_string_field_pool ** | pool_head, | |||
| size_t | needed | |||
| ) |
Definition at line 1566 of file utils.c.
References add_string_pool(), ast_string_field_mgr::last_alloc, ast_string_field_mgr::owner_file, ast_string_field_mgr::owner_func, ast_string_field_mgr::owner_line, ast_string_field_mgr::size, and ast_string_field_mgr::used.
01568 { 01569 char *result = NULL; 01570 size_t space = mgr->size - mgr->used; 01571 01572 if (__builtin_expect(needed > space, 0)) { 01573 size_t new_size = mgr->size * 2; 01574 01575 while (new_size < needed) 01576 new_size *= 2; 01577 01578 #if defined(__AST_DEBUG_MALLOC) 01579 if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func)) 01580 return NULL; 01581 #else 01582 if (add_string_pool(mgr, pool_head, new_size, __FILE__, __LINE__, __FUNCTION__)) 01583 return NULL; 01584 #endif 01585 } 01586 01587 result = (*pool_head)->base + mgr->used; 01588 mgr->used += needed; 01589 mgr->last_alloc = result; 01590 return result; 01591 }
| int __ast_string_field_init | ( | struct ast_string_field_mgr * | mgr, | |
| struct ast_string_field_pool ** | pool_head, | |||
| int | needed, | |||
| const char * | file, | |||
| int | lineno, | |||
| const char * | func | |||
| ) |
Definition at line 1512 of file utils.c.
References __ast_string_field_empty, add_string_pool(), ast_free, ast_log(), ast_string_field_mgr::last_alloc, LOG_WARNING, ast_string_field_mgr::owner_file, ast_string_field_mgr::owner_func, ast_string_field_mgr::owner_line, ast_string_field_pool::prev, and ast_string_field_mgr::used.
01514 { 01515 const char **p = (const char **) pool_head + 1; 01516 struct ast_string_field_pool *cur = NULL; 01517 struct ast_string_field_pool *preserve = NULL; 01518 01519 /* clear fields - this is always necessary */ 01520 while ((struct ast_string_field_mgr *) p != mgr) 01521 *p++ = __ast_string_field_empty; 01522 mgr->last_alloc = NULL; 01523 #if defined(__AST_DEBUG_MALLOC) 01524 mgr->owner_file = file; 01525 mgr->owner_func = func; 01526 mgr->owner_line = lineno; 01527 #endif 01528 if (needed > 0) { /* allocate the initial pool */ 01529 *pool_head = NULL; 01530 return add_string_pool(mgr, pool_head, needed, file, lineno, func); 01531 } 01532 if (needed < 0) { /* reset all pools */ 01533 if (*pool_head == NULL) { 01534 ast_log(LOG_WARNING, "trying to reset empty pool\n"); 01535 return -1; 01536 } 01537 cur = *pool_head; 01538 } else { /* preserve the last pool */ 01539 if (*pool_head == NULL) { 01540 ast_log(LOG_WARNING, "trying to reset empty pool\n"); 01541 return -1; 01542 } 01543 mgr->used = 0; 01544 preserve = *pool_head; 01545 cur = preserve->prev; 01546 } 01547 01548 if (preserve) { 01549 preserve->prev = NULL; 01550 } 01551 01552 while (cur) { 01553 struct ast_string_field_pool *prev = cur->prev; 01554 01555 if (cur != preserve) { 01556 ast_free(cur); 01557 } 01558 cur = prev; 01559 } 01560 01561 *pool_head = preserve; 01562 01563 return 0; 01564 }
| void __ast_string_field_ptr_build | ( | struct ast_string_field_mgr * | mgr, | |
| struct ast_string_field_pool ** | pool_head, | |||
| ast_string_field * | ptr, | |||
| const char * | format, | |||
| ... | ||||
| ) |
Definition at line 1672 of file utils.c.
References __ast_string_field_ptr_build_va().
01675 { 01676 va_list ap1, ap2; 01677 01678 va_start(ap1, format); 01679 va_start(ap2, format); /* va_copy does not exist on FreeBSD */ 01680 01681 __ast_string_field_ptr_build_va(mgr, pool_head, ptr, format, ap1, ap2); 01682 01683 va_end(ap1); 01684 va_end(ap2); 01685 }
| void __ast_string_field_ptr_build_va | ( | struct ast_string_field_mgr * | mgr, | |
| struct ast_string_field_pool ** | pool_head, | |||
| ast_string_field * | ptr, | |||
| const char * | format, | |||
| va_list | a1, | |||
| va_list | a2 | |||
| ) |
Definition at line 1616 of file utils.c.
References add_string_pool(), available(), ast_string_field_mgr::last_alloc, ast_string_field_mgr::owner_file, ast_string_field_mgr::owner_func, ast_string_field_mgr::owner_line, ast_string_field_mgr::size, and ast_string_field_mgr::used.
Referenced by __ast_string_field_ptr_build().
01619 { 01620 size_t needed; 01621 size_t available; 01622 size_t space = mgr->size - mgr->used; 01623 char *target; 01624 01625 /* if the field already has space allocated, try to reuse it; 01626 otherwise, use the empty space at the end of the current 01627 pool 01628 */ 01629 if ((*ptr)[0] != '\0') { 01630 target = (char *) *ptr; 01631 available = strlen(target) + 1; 01632 } else { 01633 target = (*pool_head)->base + mgr->used; 01634 available = space; 01635 } 01636 01637 needed = vsnprintf(target, available, format, ap1) + 1; 01638 01639 va_end(ap1); 01640 01641 if (needed > available) { 01642 /* if the space needed can be satisfied by using the current 01643 pool (which could only occur if we tried to use the field's 01644 allocated space and failed), then use that space; otherwise 01645 allocate a new pool 01646 */ 01647 if (needed > space) { 01648 size_t new_size = mgr->size * 2; 01649 01650 while (new_size < needed) 01651 new_size *= 2; 01652 01653 #if defined(__AST_DEBUG_MALLOC) 01654 if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func)) 01655 return; 01656 #else 01657 if (add_string_pool(mgr, pool_head, new_size, NULL, 0, NULL)) 01658 return; 01659 #endif 01660 } 01661 01662 target = (*pool_head)->base + mgr->used; 01663 vsprintf(target, format, ap2); 01664 } 01665 01666 if (*ptr != target) { 01667 mgr->last_alloc = *ptr = target; 01668 mgr->used += needed; 01669 } 01670 }
| int __ast_string_field_ptr_grow | ( | struct ast_string_field_mgr * | mgr, | |
| size_t | needed, | |||
| const ast_string_field * | ptr | |||
| ) |
Definition at line 1593 of file utils.c.
References ast_string_field_mgr::last_alloc, ast_string_field_mgr::size, and ast_string_field_mgr::used.
01595 { 01596 int grow = needed - (strlen(*ptr) + 1); 01597 size_t space = mgr->size - mgr->used; 01598 01599 if (grow <= 0) { 01600 return 0; 01601 } 01602 01603 if (*ptr != mgr->last_alloc) { 01604 return 1; 01605 } 01606 01607 if (space < grow) { 01608 return 1; 01609 } 01610 01611 mgr->used += grow; 01612 01613 return 0; 01614 }
| const char __ast_string_field_empty[] |
1.6.1