#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 - __alignof__(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 275 of file stringfields.h.
Referenced by append_mailbox_mapping(), ast_log(), AST_TEST_DEFINE(), build_extension(), jack_data_alloc(), load_config(), load_module(), raise_exception(), register_group(), register_group_feature(), sip_register(), sip_subscribe_mwi(), sla_build_station(), and sla_build_trunk().
#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 235 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 220 of file stringfields.h.
#define AST_STRING_FIELD_ALLOCATION | ( | x | ) | *((ast_string_field_allocation *) (x - __alignof__(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 309 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 365 of file stringfields.h.
Referenced by __ast_channel_alloc_ap(), action_originate(), build_callid_pvt(), build_callid_registry(), build_contact(), build_user(), caldav_write_event(), handle_request_subscribe(), init_acf_query(), load_config(), parse_cdata(), parse_moved_contact(), parse_register_contact(), set_nonce_randdata(), sip_sendhtml(), sip_sipredirect(), and t30_phase_e_handler().
#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 389 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 253 of file stringfields.h.
Referenced by __sip_destroy(), action_destroy(), action_originate(), ast_channel_destructor(), ast_custom_function_unregister(), ast_dummy_channel_destructor(), ast_pbx_outgoing_app(), ast_pbx_run_app(), AST_TEST_DEFINE(), ast_unregister_application(), ast_unregister_groups(), build_user(), caldav_destructor(), calendar_destructor(), calendar_event_destructor(), delete_extension(), delete_file(), destroy_jack_data(), destroy_mailbox_mapping(), destroy_queue(), destroy_session_details(), destroy_station(), destroy_trunk(), ewscal_destructor(), exception_store_free(), exchangecal_destructor(), fast_originate(), free_acf_query(), free_outgoing(), icalendar_destructor(), init_acf_query(), load_module(), peer_destructor(), profile_destructor(), pvt_destructor(), realtime_multi_odbc(), realtime_odbc(), route_destructor(), sip_destroy_peer(), sip_monitor_instance_destructor(), sip_registry_destroy(), sip_subscribe_mwi_destroy(), tds_unload_module(), temp_pvt_cleanup(), update_odbc(), 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 249 of file stringfields.h.
Referenced by __ast_channel_alloc_ap(), acf_retrieve_docs(), action_originate(), alloc_queue(), ast_calendar_event_alloc(), ast_dummy_channel_alloc(), ast_manager_register2(), ast_pbx_outgoing_app(), ast_register_application2(), build_calendar(), build_peer(), build_profile(), build_route(), build_user(), caldav_load_calendar(), ewscal_load_calendar(), exchangecal_load_calendar(), ical_load_calendar(), init_acf_query(), init_outgoing(), init_pvt(), new_iax(), realtime_multi_odbc(), realtime_odbc(), session_details_new(), sip_alloc(), sip_monitor_instance_init(), tds_load_module(), temp_peer(), temp_pvt_init(), transmit_response_using_temp(), and update_odbc().
#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 354 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 377 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 318 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 342 of file stringfields.h.
Referenced by __ast_change_name_nolink(), __ast_channel_alloc_ap(), __find_callno(), __oh323_new(), __sip_subscribe_mwi_do(), acf_faxopt_write(), acf_retrieve_docs(), action_originate(), agent_new(), alloc_queue(), alsa_new(), analog_new_ast_channel(), 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_pbx_outgoing_app(), 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(), change_callid_pvt(), check_access(), check_peer_ok(), check_user_full(), conf_start_moh(), console_new(), copy_event_data(), create_addr(), create_addr_from_peer(), custom_prepare(), dahdi_new(), dial_exec_full(), do_forward(), endelm(), ewscal_load_calendar(), exchangecal_load_calendar(), extract_uri(), feature_request_and_dial(), findmeexec(), generic_fax_exec(), get_also_info(), get_destination(), get_pai(), get_realm(), get_rpid(), gtalk_new(), handle_cc_notify(), handle_incoming(), handle_options(), handle_request_bye(), handle_request_invite(), handle_request_options(), handle_request_publish(), handle_request_refer(), handle_response(), handle_response_invite(), handle_response_notify(), handle_response_publish(), handle_response_subscribe(), iax2_call(), iax2_request(), iax_park(), ical_load_calendar(), icalendar_add_event(), init_acf_query(), init_pvt(), init_queue(), initreqprep(), jingle_new(), load_config(), local_call(), logger_print_normal(), 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(), phone_new(), queue_set_param(), raise_exception(), read_config(), receivefax_exec(), reg_source_db(), register_group(), register_group_feature(), register_verify(), registry_authrequest(), reply_digest(), reqprep(), respprep(), ring_entry(), save_osptoken(), sendfax_exec(), set_moh_exec(), set_peer_defaults(), set_pvt_defaults(), sig_pri_handle_subcmds(), sip_alloc(), sip_call(), sip_monitor_instance_init(), sip_new(), sip_park(), sip_parse_register_line(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), sip_set_redirstr(), sip_subscribe_mwi(), skinny_new(), sla_build_station(), sla_build_trunk(), socket_process(), startelm(), store_callerid(), t30_phase_e_handler(), 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 115 of file stringfields.h.
typedef uint16_t ast_string_field_allocation |
Definition at line 119 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 1805 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.
01808 { 01809 struct ast_string_field_mgr *mgr; 01810 struct ast_string_field_pool *pool; 01811 struct ast_string_field_pool **pool_head; 01812 size_t pool_size_needed = sizeof(*pool) + pool_size; 01813 size_t size_to_alloc = optimal_alloc_size(struct_size + pool_size_needed); 01814 void *allocation; 01815 unsigned int x; 01816 01817 #if defined(__AST_DEBUG_MALLOC) 01818 if (!(allocation = __ast_calloc(num_structs, size_to_alloc, file, lineno, func))) { 01819 return NULL; 01820 } 01821 #else 01822 if (!(allocation = ast_calloc(num_structs, size_to_alloc))) { 01823 return NULL; 01824 } 01825 #endif 01826 01827 for (x = 0; x < num_structs; x++) { 01828 void *base = allocation + (size_to_alloc * x); 01829 const char **p; 01830 01831 mgr = base + field_mgr_offset; 01832 pool_head = base + field_mgr_pool_offset; 01833 pool = base + struct_size; 01834 01835 p = (const char **) pool_head + 1; 01836 while ((struct ast_string_field_mgr *) p != mgr) { 01837 *p++ = __ast_string_field_empty; 01838 } 01839 01840 mgr->embedded_pool = pool; 01841 *pool_head = pool; 01842 pool->size = size_to_alloc - struct_size - sizeof(*pool); 01843 #if defined(__AST_DEBUG_MALLOC) 01844 mgr->owner_file = file; 01845 mgr->owner_func = func; 01846 mgr->owner_line = lineno; 01847 #endif 01848 } 01849 01850 return allocation; 01851 }
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 1644 of file utils.c.
References add_string_pool(), ast_alignof, ast_assert, ast_make_room_for, AST_STRING_FIELD_ALLOCATION, and ast_string_field_mgr::last_alloc.
Referenced by __ast_string_field_ptr_build_va().
01646 { 01647 char *result = NULL; 01648 size_t space = (*pool_head)->size - (*pool_head)->used; 01649 size_t to_alloc; 01650 01651 /* Make room for ast_string_field_allocation and make it a multiple of that. */ 01652 to_alloc = ast_make_room_for(needed, ast_string_field_allocation); 01653 ast_assert(to_alloc % ast_alignof(ast_string_field_allocation) == 0); 01654 01655 if (__builtin_expect(to_alloc > space, 0)) { 01656 size_t new_size = (*pool_head)->size; 01657 01658 while (new_size < to_alloc) { 01659 new_size *= 2; 01660 } 01661 01662 #if defined(__AST_DEBUG_MALLOC) 01663 if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func)) 01664 return NULL; 01665 #else 01666 if (add_string_pool(mgr, pool_head, new_size, __FILE__, __LINE__, __FUNCTION__)) 01667 return NULL; 01668 #endif 01669 } 01670 01671 /* pool->base is always aligned (gcc aligned attribute). We ensure that 01672 * to_alloc is also a multiple of ast_alignof(ast_string_field_allocation) 01673 * causing result to always be aligned as well; which in turn fixes that 01674 * AST_STRING_FIELD_ALLOCATION(result) is aligned. */ 01675 result = (*pool_head)->base + (*pool_head)->used; 01676 (*pool_head)->used += to_alloc; 01677 (*pool_head)->active += needed; 01678 result += ast_alignof(ast_string_field_allocation); 01679 AST_STRING_FIELD_ALLOCATION(result) = needed; 01680 mgr->last_alloc = result; 01681 01682 return result; 01683 }
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 1577 of file utils.c.
References 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.
01579 { 01580 const char **p = (const char **) pool_head + 1; 01581 struct ast_string_field_pool *cur = NULL; 01582 struct ast_string_field_pool *preserve = NULL; 01583 01584 /* clear fields - this is always necessary */ 01585 while ((struct ast_string_field_mgr *) p != mgr) { 01586 *p++ = __ast_string_field_empty; 01587 } 01588 01589 mgr->last_alloc = NULL; 01590 #if defined(__AST_DEBUG_MALLOC) 01591 mgr->owner_file = file; 01592 mgr->owner_func = func; 01593 mgr->owner_line = lineno; 01594 #endif 01595 if (needed > 0) { /* allocate the initial pool */ 01596 *pool_head = NULL; 01597 mgr->embedded_pool = NULL; 01598 return add_string_pool(mgr, pool_head, needed, file, lineno, func); 01599 } 01600 01601 /* if there is an embedded pool, we can't actually release *all* 01602 * pools, we must keep the embedded one. if the caller is about 01603 * to free the structure that contains the stringfield manager 01604 * and embedded pool anyway, it will be freed as part of that 01605 * operation. 01606 */ 01607 if ((needed < 0) && mgr->embedded_pool) { 01608 needed = 0; 01609 } 01610 01611 if (needed < 0) { /* reset all pools */ 01612 cur = *pool_head; 01613 } else if (mgr->embedded_pool) { /* preserve the embedded pool */ 01614 preserve = mgr->embedded_pool; 01615 cur = *pool_head; 01616 } else { /* preserve the last pool */ 01617 if (*pool_head == NULL) { 01618 ast_log(LOG_WARNING, "trying to reset empty pool\n"); 01619 return -1; 01620 } 01621 preserve = *pool_head; 01622 cur = preserve->prev; 01623 } 01624 01625 if (preserve) { 01626 preserve->prev = NULL; 01627 preserve->used = preserve->active = 0; 01628 } 01629 01630 while (cur) { 01631 struct ast_string_field_pool *prev = cur->prev; 01632 01633 if (cur != preserve) { 01634 ast_free(cur); 01635 } 01636 cur = prev; 01637 } 01638 01639 *pool_head = preserve; 01640 01641 return 0; 01642 }
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 1790 of file utils.c.
References __ast_string_field_ptr_build_va().
01793 { 01794 va_list ap1, ap2; 01795 01796 va_start(ap1, format); 01797 va_start(ap2, format); /* va_copy does not exist on FreeBSD */ 01798 01799 __ast_string_field_ptr_build_va(mgr, pool_head, ptr, format, ap1, ap2); 01800 01801 va_end(ap1); 01802 va_end(ap2); 01803 }
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 1728 of file utils.c.
References __ast_string_field_alloc_space(), __ast_string_field_empty, __ast_string_field_release_active(), ast_align_for, ast_alignof, ast_make_room_for, AST_STRING_FIELD_ALLOCATION, available(), and ast_string_field_mgr::last_alloc.
Referenced by __ast_string_field_ptr_build().
01731 { 01732 size_t needed; 01733 size_t available; 01734 size_t space = (*pool_head)->size - (*pool_head)->used; 01735 ssize_t grow; 01736 char *target; 01737 01738 /* if the field already has space allocated, try to reuse it; 01739 otherwise, try to use the empty space at the end of the current 01740 pool 01741 */ 01742 if (*ptr != __ast_string_field_empty) { 01743 target = (char *) *ptr; 01744 available = AST_STRING_FIELD_ALLOCATION(*ptr); 01745 if (*ptr == mgr->last_alloc) { 01746 available += space; 01747 } 01748 } else { 01749 /* pool->used is always a multiple of ast_alignof(ast_string_field_allocation) 01750 * so we don't need to re-align anything here. 01751 */ 01752 target = (*pool_head)->base + (*pool_head)->used + ast_alignof(ast_string_field_allocation); 01753 available = space - ast_alignof(ast_string_field_allocation); 01754 } 01755 01756 needed = vsnprintf(target, available, format, ap1) + 1; 01757 01758 va_end(ap1); 01759 01760 if (needed > available) { 01761 /* the allocation could not be satisfied using the field's current allocation 01762 (if it has one), or the space available in the pool (if it does not). allocate 01763 space for it, adding a new string pool if necessary. 01764 */ 01765 if (!(target = (char *) __ast_string_field_alloc_space(mgr, pool_head, needed))) { 01766 return; 01767 } 01768 vsprintf(target, format, ap2); 01769 __ast_string_field_release_active(*pool_head, *ptr); 01770 *ptr = target; 01771 } else if (*ptr != target) { 01772 /* the allocation was satisfied using available space in the pool, but not 01773 using the space already allocated to the field 01774 */ 01775 __ast_string_field_release_active(*pool_head, *ptr); 01776 mgr->last_alloc = *ptr = target; 01777 AST_STRING_FIELD_ALLOCATION(target) = needed; 01778 (*pool_head)->used += ast_make_room_for(needed, ast_string_field_allocation); 01779 (*pool_head)->active += needed; 01780 } else if ((grow = (needed - AST_STRING_FIELD_ALLOCATION(*ptr))) > 0) { 01781 /* the allocation was satisfied by using available space in the pool *and* 01782 the field was the last allocated field from the pool, so it grew 01783 */ 01784 AST_STRING_FIELD_ALLOCATION(*ptr) += grow; 01785 (*pool_head)->used += ast_align_for(grow, ast_string_field_allocation); 01786 (*pool_head)->active += grow; 01787 } 01788 }
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 1685 of file utils.c.
References AST_STRING_FIELD_ALLOCATION, and ast_string_field_mgr::last_alloc.
01688 { 01689 ssize_t grow = needed - AST_STRING_FIELD_ALLOCATION(*ptr); 01690 size_t space = (*pool_head)->size - (*pool_head)->used; 01691 01692 if (*ptr != mgr->last_alloc) { 01693 return 1; 01694 } 01695 01696 if (space < grow) { 01697 return 1; 01698 } 01699 01700 (*pool_head)->used += grow; 01701 (*pool_head)->active += grow; 01702 AST_STRING_FIELD_ALLOCATION(*ptr) += grow; 01703 01704 return 0; 01705 }
void __ast_string_field_release_active | ( | struct ast_string_field_pool * | pool_head, | |
const ast_string_field | ptr | |||
) |
Definition at line 1707 of file utils.c.
References 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().
01709 { 01710 struct ast_string_field_pool *pool, *prev; 01711 01712 if (ptr == __ast_string_field_empty) { 01713 return; 01714 } 01715 01716 for (pool = pool_head, prev = NULL; pool; prev = pool, pool = pool->prev) { 01717 if ((ptr >= pool->base) && (ptr <= (pool->base + pool->size))) { 01718 pool->active -= AST_STRING_FIELD_ALLOCATION(ptr); 01719 if ((pool->active == 0) && prev) { 01720 prev->prev = pool->prev; 01721 ast_free(pool); 01722 } 01723 break; 01724 } 01725 } 01726 }
const char* __ast_string_field_empty |
Definition at line 1522 of file utils.c.
Referenced by __ast_calloc_with_stringfields(), and __ast_string_field_ptr_build_va().