#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_calloc_with_stringfields(n, type, size) |
| Allocate a structure with embedded stringfields in a single allocation. | |
| #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_ALLOCATION(x) *((ast_string_field_allocation *) (x - sizeof(ast_string_field_allocation))) |
| Macro to provide access to the allocation field that lives immediately in front of 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 |
| typedef uint16_t | ast_string_field_allocation |
Functions | |
| void *attribute_malloc | __ast_calloc_with_stringfields (unsigned int num_structs, size_t struct_size, size_t field_mgr_offset, size_t field_mgr_pool_offset, size_t pool_size, const char *file, int lineno, const char *func) |
| 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, struct ast_string_field_pool **pool_head, size_t needed, const ast_string_field *ptr) |
| void | __ast_string_field_release_active (struct ast_string_field_pool *pool_head, const ast_string_field ptr) |
Variables | |
| const char * | __ast_string_field_empty |
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.
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.
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 format; ast_string_field_build_va() is the varargs version of the above (for portability reasons it uses two vararg arguments); 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_calloc_with_stringfields | ( | n, | |||
| type, | |||||
| size | ) |
Value:
__ast_calloc_with_stringfields(n, sizeof(type), offsetof(type, __field_mgr), offsetof(type, __field_mgr_pool), \ size, __FILE__, __LINE__, __PRETTY_FUNCTION__)
| n | Number of structures to allocate (see ast_calloc) | |
| type | The type of structure to allocate | |
| size | The number of bytes of space (minimum) to allocate for stringfields to use |
Definition at line 269 of file stringfields.h.
Referenced by __ast_verbose_ap(), ast_log(), and load_config().
| #define AST_DECLARE_STRING_FIELDS | ( | field_list | ) |
Value:
struct ast_string_field_pool *__field_mgr_pool; \ field_list \ struct ast_string_field_mgr __field_mgr
| 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 229 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 214 of file stringfields.h.
| #define AST_STRING_FIELD_ALLOCATION | ( | x | ) | *((ast_string_field_allocation *) (x - sizeof(ast_string_field_allocation))) |
Macro to provide access to the allocation field that lives immediately in front of a string field.
| x | Pointer to the string field |
Definition at line 304 of file stringfields.h.
Referenced by __ast_string_field_alloc_space(), __ast_string_field_ptr_build_va(), __ast_string_field_ptr_grow(), and __ast_string_field_release_active().
| #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 360 of file stringfields.h.
Referenced by __ast_channel_alloc_ap(), build_callid_pvt(), build_callid_registry(), build_contact(), build_profile(), build_user(), caldav_write_event(), create_addr_from_peer(), handle_request_subscribe(), handle_response(), init_acf_query(), load_config(), parse_cdata(), parse_moved_contact(), parse_register_contact(), set_nonce_randdata(), sip_sendhtml(), and sip_sipredirect().
| #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 384 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 247 of file stringfields.h.
Referenced by __ast_channel_alloc_ap(), __sip_destroy(), ast_channel_destructor(), ast_custom_function_unregister(), ast_dummy_channel_destructor(), ast_manager_unregister(), ast_unregister_application(), ast_unregister_groups(), auth_http_callback(), build_user(), caldav_destructor(), calendar_destructor(), calendar_event_destructor(), delete_extension(), delete_file(), destroy_jack_data(), destroy_mailbox_mapping(), destroy_queue(), destroy_station(), destroy_trunk(), exception_store_free(), exchangecal_destructor(), free_acf_query(), free_outgoing(), icalendar_destructor(), init_acf_query(), load_module(), peer_destructor(), profile_destructor(), pvt_destructor(), route_destructor(), sip_destroy_peer(), sip_registry_destroy(), sip_subscribe_mwi_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 243 of file stringfields.h.
Referenced by __ast_channel_alloc_ap(), acf_retrieve_docs(), alloc_queue(), append_mailbox_mapping(), ast_calendar_event_alloc(), ast_dummy_channel_alloc(), ast_manager_register2(), ast_register_application2(), auth_http_callback(), build_calendar(), build_extension(), build_peer(), build_profile(), build_route(), build_user(), caldav_load_calendar(), exchangecal_load_calendar(), ical_load_calendar(), init_acf_query(), init_outgoing(), init_pvt(), jack_data_alloc(), load_module(), new_iax(), pbx_builtin_raise_exception(), register_group(), register_group_feature(), sip_alloc(), sip_register(), sip_subscribe_mwi(), sla_build_station(), sla_build_trunk(), tds_load_module(), temp_peer(), 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 349 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 372 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 313 of file stringfields.h.
Referenced by reply_digest().
| #define ast_string_field_set | ( | x, | |||
| field, | |||||
| data | ) |
Value:
do { \ ast_string_field_ptr_set(x, &(x)->field, data); \ } while (0)
| 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 337 of file stringfields.h.
Referenced by __ast_change_name_nolink(), __ast_channel_alloc_ap(), __ast_verbose_ap(), __find_callno(), __oh323_new(), __sip_subscribe_mwi_do(), acf_channel_write(), acf_retrieve_docs(), agent_new(), alloc_queue(), alsa_new(), append_mailbox_mapping(), apply_outgoing(), ast_call_forward(), ast_cdr_setaccount(), ast_cdr_setpeeraccount(), ast_cel_fabricate_channel_from_event(), ast_channel_change_linkedid(), ast_do_masquerade(), ast_iax2_new(), ast_log(), ast_manager_register2(), ast_parse_digest(), ast_register_application2(), ast_set_hangupsource(), ast_set_owners_and_peers(), authenticate_reply(), authenticate_request(), authenticate_verify(), begin_dial_channel(), build_calendar(), build_extension(), build_peer(), build_profile(), build_route(), build_user(), cache_get_callno_locked(), caldav_add_event(), caldav_load_calendar(), calendar_write_exec(), check_access(), check_peer_ok(), check_user_full(), conf_start_moh(), console_new(), copy_event_data(), create_addr(), create_addr_from_peer(), dahdi_new(), dial_exec_full(), disa_exec(), do_forward(), exchangecal_load_calendar(), extract_uri(), feature_request_and_dial(), findmeexec(), get_also_info(), get_destination(), get_pai(), get_realm(), get_rpid(), 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(), handle_response_subscribe(), iax2_call(), iax2_request(), ical_load_calendar(), icalendar_add_event(), init_acf_query(), init_pvt(), init_queue(), initreqprep(), jingle_new(), load_config(), local_call(), mgcp_new(), misdn_facility_ie_handler(), moh_handle_digit(), 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(), reg_source_db(), register_group(), register_group_feature(), register_verify(), registry_authrequest(), reply_digest(), reqprep(), respprep(), ring_entry(), save_osptoken(), set_moh_exec(), set_peer_defaults(), set_pvt_defaults(), sip_alloc(), sip_call(), sip_new(), sip_park(), sip_poke_peer(), sip_register(), sip_request_call(), sip_send_mwi_to_peer(), sip_set_redirstr(), sip_subscribe_mwi(), 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(), update_redirecting(), usbradio_new(), vm_execmain(), and wait_for_answer().
| typedef const char* ast_string_field |
Definition at line 115 of file stringfields.h.
| typedef uint16_t ast_string_field_allocation |
Definition at line 298 of file stringfields.h.
| void* attribute_malloc __ast_calloc_with_stringfields | ( | unsigned int | num_structs, | |
| size_t | struct_size, | |||
| size_t | field_mgr_offset, | |||
| size_t | field_mgr_pool_offset, | |||
| size_t | pool_size, | |||
| const char * | file, | |||
| int | lineno, | |||
| const char * | func | |||
| ) |
Definition at line 1755 of file utils.c.
References __ast_calloc(), __ast_string_field_empty, allocation, ast_calloc, ast_string_field_pool::base, ast_string_field_mgr::embedded_pool, optimal_alloc_size(), and ast_string_field_pool::size.
01758 { 01759 struct ast_string_field_mgr *mgr; 01760 struct ast_string_field_pool *pool; 01761 struct ast_string_field_pool **pool_head; 01762 size_t pool_size_needed = sizeof(*pool) + pool_size; 01763 size_t size_to_alloc = optimal_alloc_size(struct_size + pool_size_needed); 01764 void *allocation; 01765 unsigned int x; 01766 01767 #if defined(__AST_DEBUG_MALLOC) 01768 if (!(allocation = __ast_calloc(num_structs, size_to_alloc, file, lineno, func))) { 01769 return NULL; 01770 } 01771 #else 01772 if (!(allocation = ast_calloc(num_structs, size_to_alloc))) { 01773 return NULL; 01774 } 01775 #endif 01776 01777 for (x = 0; x < num_structs; x++) { 01778 void *base = allocation + (size_to_alloc * x); 01779 const char **p; 01780 01781 mgr = base + field_mgr_offset; 01782 pool_head = base + field_mgr_pool_offset; 01783 pool = base + struct_size; 01784 01785 p = (const char **) pool_head + 1; 01786 while ((struct ast_string_field_mgr *) p != mgr) { 01787 *p++ = __ast_string_field_empty; 01788 } 01789 01790 mgr->embedded_pool = pool; 01791 *pool_head = pool; 01792 pool->size = size_to_alloc - struct_size - sizeof(*pool); 01793 } 01794 01795 return allocation; 01796 }
| 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 1605 of file utils.c.
References add_string_pool(), AST_STRING_FIELD_ALLOCATION, and ast_string_field_mgr::last_alloc.
Referenced by __ast_string_field_ptr_build_va().
01607 { 01608 char *result = NULL; 01609 size_t space = (*pool_head)->size - (*pool_head)->used; 01610 size_t to_alloc = needed + sizeof(ast_string_field_allocation); 01611 01612 if (__builtin_expect(to_alloc > space, 0)) { 01613 size_t new_size = (*pool_head)->size; 01614 01615 while (new_size < to_alloc) { 01616 new_size *= 2; 01617 } 01618 01619 #if defined(__AST_DEBUG_MALLOC) 01620 if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func)) 01621 return NULL; 01622 #else 01623 if (add_string_pool(mgr, pool_head, new_size, __FILE__, __LINE__, __FUNCTION__)) 01624 return NULL; 01625 #endif 01626 } 01627 01628 result = (*pool_head)->base + (*pool_head)->used; 01629 (*pool_head)->used += to_alloc; 01630 (*pool_head)->active += needed; 01631 result += sizeof(ast_string_field_allocation); 01632 AST_STRING_FIELD_ALLOCATION(result) = needed; 01633 mgr->last_alloc = result; 01634 01635 return result; 01636 }
| 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 1539 of file utils.c.
References __ast_string_field_empty, ast_string_field_pool::active, add_string_pool(), ast_free, ast_log(), ast_string_field_mgr::embedded_pool, ast_string_field_mgr::last_alloc, LOG_WARNING, ast_string_field_pool::prev, and ast_string_field_pool::used.
01541 { 01542 const char **p = (const char **) pool_head + 1; 01543 struct ast_string_field_pool *cur = NULL; 01544 struct ast_string_field_pool *preserve = NULL; 01545 01546 /* clear fields - this is always necessary */ 01547 while ((struct ast_string_field_mgr *) p != mgr) { 01548 *p++ = __ast_string_field_empty; 01549 } 01550 01551 mgr->last_alloc = NULL; 01552 #if defined(__AST_DEBUG_MALLOC) 01553 mgr->owner_file = file; 01554 mgr->owner_func = func; 01555 mgr->owner_line = lineno; 01556 #endif 01557 if (needed > 0) { /* allocate the initial pool */ 01558 *pool_head = NULL; 01559 return add_string_pool(mgr, pool_head, needed, file, lineno, func); 01560 } 01561 01562 /* if there is an embedded pool, we can't actually release *all* 01563 * pools, we must keep the embedded one. if the caller is about 01564 * to free the structure that contains the stringfield manager 01565 * and embedded pool anyway, it will be freed as part of that 01566 * operation. 01567 */ 01568 if ((needed < 0) && mgr->embedded_pool) { 01569 needed = 0; 01570 } 01571 01572 if (needed < 0) { /* reset all pools */ 01573 cur = *pool_head; 01574 } else if (mgr->embedded_pool) { /* preserve the embedded pool */ 01575 preserve = mgr->embedded_pool; 01576 cur = *pool_head; 01577 } else { /* preserve the last pool */ 01578 if (*pool_head == NULL) { 01579 ast_log(LOG_WARNING, "trying to reset empty pool\n"); 01580 return -1; 01581 } 01582 preserve = *pool_head; 01583 cur = preserve->prev; 01584 } 01585 01586 if (preserve) { 01587 preserve->prev = NULL; 01588 preserve->used = preserve->active = 0; 01589 } 01590 01591 while (cur) { 01592 struct ast_string_field_pool *prev = cur->prev; 01593 01594 if (cur != preserve) { 01595 ast_free(cur); 01596 } 01597 cur = prev; 01598 } 01599 01600 *pool_head = preserve; 01601 01602 return 0; 01603 }
| 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 1740 of file utils.c.
References __ast_string_field_ptr_build_va().
01743 { 01744 va_list ap1, ap2; 01745 01746 va_start(ap1, format); 01747 va_start(ap2, format); /* va_copy does not exist on FreeBSD */ 01748 01749 __ast_string_field_ptr_build_va(mgr, pool_head, ptr, format, ap1, ap2); 01750 01751 va_end(ap1); 01752 va_end(ap2); 01753 }
| 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 1681 of file utils.c.
References __ast_string_field_alloc_space(), __ast_string_field_empty, __ast_string_field_release_active(), AST_STRING_FIELD_ALLOCATION, available(), and ast_string_field_mgr::last_alloc.
Referenced by __ast_string_field_ptr_build().
01684 { 01685 size_t needed; 01686 size_t available; 01687 size_t space = (*pool_head)->size - (*pool_head)->used; 01688 ssize_t grow; 01689 char *target; 01690 01691 /* if the field already has space allocated, try to reuse it; 01692 otherwise, try to use the empty space at the end of the current 01693 pool 01694 */ 01695 if (*ptr != __ast_string_field_empty) { 01696 target = (char *) *ptr; 01697 available = AST_STRING_FIELD_ALLOCATION(*ptr); 01698 if (*ptr == mgr->last_alloc) { 01699 available += space; 01700 } 01701 } else { 01702 target = (*pool_head)->base + (*pool_head)->used + sizeof(ast_string_field_allocation); 01703 available = space - sizeof(ast_string_field_allocation); 01704 } 01705 01706 needed = vsnprintf(target, available, format, ap1) + 1; 01707 01708 va_end(ap1); 01709 01710 if (needed > available) { 01711 /* the allocation could not be satisfied using the field's current allocation 01712 (if it has one), or the space available in the pool (if it does not). allocate 01713 space for it, adding a new string pool if necessary. 01714 */ 01715 if (!(target = (char *) __ast_string_field_alloc_space(mgr, pool_head, needed))) { 01716 return; 01717 } 01718 vsprintf(target, format, ap2); 01719 __ast_string_field_release_active(*pool_head, *ptr); 01720 *ptr = target; 01721 } else if (*ptr != target) { 01722 /* the allocation was satisfied using available space in the pool, but not 01723 using the space already allocated to the field 01724 */ 01725 __ast_string_field_release_active(*pool_head, *ptr); 01726 mgr->last_alloc = *ptr = target; 01727 AST_STRING_FIELD_ALLOCATION(target) = needed; 01728 (*pool_head)->used += needed + sizeof(ast_string_field_allocation); 01729 (*pool_head)->active += needed; 01730 } else if ((grow = (needed - AST_STRING_FIELD_ALLOCATION(*ptr))) > 0) { 01731 /* the allocation was satisfied by using available space in the pool *and* 01732 the field was the last allocated field from the pool, so it grew 01733 */ 01734 (*pool_head)->used += grow; 01735 (*pool_head)->active += grow; 01736 AST_STRING_FIELD_ALLOCATION(*ptr) += grow; 01737 } 01738 }
| int __ast_string_field_ptr_grow | ( | struct ast_string_field_mgr * | mgr, | |
| struct ast_string_field_pool ** | pool_head, | |||
| size_t | needed, | |||
| const ast_string_field * | ptr | |||
| ) |
Definition at line 1638 of file utils.c.
References AST_STRING_FIELD_ALLOCATION, and ast_string_field_mgr::last_alloc.
01641 { 01642 ssize_t grow = needed - AST_STRING_FIELD_ALLOCATION(*ptr); 01643 size_t space = (*pool_head)->size - (*pool_head)->used; 01644 01645 if (*ptr != mgr->last_alloc) { 01646 return 1; 01647 } 01648 01649 if (space < grow) { 01650 return 1; 01651 } 01652 01653 (*pool_head)->used += grow; 01654 (*pool_head)->active += grow; 01655 AST_STRING_FIELD_ALLOCATION(*ptr) += grow; 01656 01657 return 0; 01658 }
| void __ast_string_field_release_active | ( | struct ast_string_field_pool * | pool_head, | |
| const ast_string_field | ptr | |||
| ) |
Definition at line 1660 of file utils.c.
References __ast_string_field_empty, ast_string_field_pool::active, ast_free, AST_STRING_FIELD_ALLOCATION, and ast_string_field_pool::prev.
Referenced by __ast_string_field_ptr_build_va().
01662 { 01663 struct ast_string_field_pool *pool, *prev; 01664 01665 if (ptr == __ast_string_field_empty) { 01666 return; 01667 } 01668 01669 for (pool = pool_head, prev = NULL; pool; prev = pool, pool = pool->prev) { 01670 if ((ptr >= pool->base) && (ptr <= (pool->base + pool->size))) { 01671 pool->active -= AST_STRING_FIELD_ALLOCATION(ptr); 01672 if ((pool->active == 0) && prev) { 01673 prev->prev = pool->prev; 01674 ast_free(pool); 01675 } 01676 break; 01677 } 01678 } 01679 }
| const char* __ast_string_field_empty |
Definition at line 1484 of file utils.c.
Referenced by __ast_calloc_with_stringfields(), __ast_string_field_init(), __ast_string_field_ptr_build_va(), and __ast_string_field_release_active().
1.5.6