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_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 |
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.
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 | ) |
__ast_calloc_with_stringfields(n, sizeof(type), offsetof(type, __field_mgr), offsetof(type, __field_mgr_pool), \ size, __FILE__, __LINE__, __PRETTY_FUNCTION__)
Allocate a structure with embedded stringfields in a single allocation.
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 |
This function will allocate memory for one or more structures that use stringfields, and also allocate space for the stringfields and initialize the stringfield management structure embedded in the outer structure.
Definition at line 275 of file stringfields.h.
Referenced by append_mailbox_mapping(), ast_log(), AST_TEST_DEFINE(), build_extension(), build_profile(), 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 | ) |
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 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 |
Note that x must be a pointer to a byte-sized type -- normally (char *) -- or this calculation would break horribly
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_profile(), build_user(), caldav_write_event(), handle_request_subscribe(), init_acf_query(), load_config(), make_our_tag(), 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(), 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(), auth_http_callback(), build_user(), caldav_destructor(), calendar_destructor(), calendar_event_destructor(), delete_extension(), delete_file(), destroy_fast_originate_helper(), destroy_jack_data(), destroy_mailbox_mapping(), destroy_queue(), destroy_session_details(), destroy_station(), destroy_trunk(), ewscal_destructor(), exception_store_free(), exchangecal_destructor(), 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(), __ast_dummy_channel_alloc(), acf_retrieve_docs(), action_originate(), alloc_queue(), ast_calendar_event_alloc(), ast_manager_register2(), ast_pbx_outgoing_app(), ast_register_application2(), auth_http_callback(), 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_pvt(), new_iax(), new_outgoing(), 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 ast_parse_digest(), and 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 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(), disa_exec(), 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(), load_module(), local_call(), logger_print_normal(), mgcp_new(), misdn_facility_ie_handler(), moh_handle_digit(), monitor_dial(), nbs_new(), new_iax(), new_outgoing(), 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(), sip_alloc(), sip_call(), sip_monitor_instance_init(), sip_new(), sip_park(), sip_parse_register_line(), sip_poke_peer(), sip_reload(), 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(), 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 1888 of file utils.c.
References __ast_calloc(), allocation, ast_calloc, ast_string_field_pool::base, ast_string_field_mgr::embedded_pool, optimal_alloc_size(), ast_string_field_mgr::owner_file, ast_string_field_mgr::owner_func, ast_string_field_mgr::owner_line, and ast_string_field_pool::size.
01891 { 01892 struct ast_string_field_mgr *mgr; 01893 struct ast_string_field_pool *pool; 01894 struct ast_string_field_pool **pool_head; 01895 size_t pool_size_needed = sizeof(*pool) + pool_size; 01896 size_t size_to_alloc = optimal_alloc_size(struct_size + pool_size_needed); 01897 void *allocation; 01898 unsigned int x; 01899 01900 #if defined(__AST_DEBUG_MALLOC) 01901 if (!(allocation = __ast_calloc(num_structs, size_to_alloc, file, lineno, func))) { 01902 return NULL; 01903 } 01904 #else 01905 if (!(allocation = ast_calloc(num_structs, size_to_alloc))) { 01906 return NULL; 01907 } 01908 #endif 01909 01910 for (x = 0; x < num_structs; x++) { 01911 void *base = allocation + (size_to_alloc * x); 01912 const char **p; 01913 01914 mgr = base + field_mgr_offset; 01915 pool_head = base + field_mgr_pool_offset; 01916 pool = base + struct_size; 01917 01918 p = (const char **) pool_head + 1; 01919 while ((struct ast_string_field_mgr *) p != mgr) { 01920 *p++ = __ast_string_field_empty; 01921 } 01922 01923 mgr->embedded_pool = pool; 01924 *pool_head = pool; 01925 pool->size = size_to_alloc - struct_size - sizeof(*pool); 01926 #if defined(__AST_DEBUG_MALLOC) 01927 mgr->owner_file = file; 01928 mgr->owner_func = func; 01929 mgr->owner_line = lineno; 01930 #endif 01931 } 01932 01933 return allocation; 01934 }
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 1729 of file utils.c.
References add_string_pool(), ast_alignof, ast_assert, ast_make_room_for, AST_STRING_FIELD_ALLOCATION, ast_string_field_mgr::last_alloc, ast_string_field_mgr::owner_file, ast_string_field_mgr::owner_func, and ast_string_field_mgr::owner_line.
Referenced by __ast_string_field_ptr_build_va().
01731 { 01732 char *result = NULL; 01733 size_t space = (*pool_head)->size - (*pool_head)->used; 01734 size_t to_alloc; 01735 01736 /* Make room for ast_string_field_allocation and make it a multiple of that. */ 01737 to_alloc = ast_make_room_for(needed, ast_string_field_allocation); 01738 ast_assert(to_alloc % ast_alignof(ast_string_field_allocation) == 0); 01739 01740 if (__builtin_expect(to_alloc > space, 0)) { 01741 size_t new_size = (*pool_head)->size; 01742 01743 while (new_size < to_alloc) { 01744 new_size *= 2; 01745 } 01746 01747 #if defined(__AST_DEBUG_MALLOC) 01748 if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func)) 01749 return NULL; 01750 #else 01751 if (add_string_pool(mgr, pool_head, new_size, __FILE__, __LINE__, __FUNCTION__)) 01752 return NULL; 01753 #endif 01754 } 01755 01756 /* pool->base is always aligned (gcc aligned attribute). We ensure that 01757 * to_alloc is also a multiple of ast_alignof(ast_string_field_allocation) 01758 * causing result to always be aligned as well; which in turn fixes that 01759 * AST_STRING_FIELD_ALLOCATION(result) is aligned. */ 01760 result = (*pool_head)->base + (*pool_head)->used; 01761 (*pool_head)->used += to_alloc; 01762 (*pool_head)->active += needed; 01763 result += ast_alignof(ast_string_field_allocation); 01764 AST_STRING_FIELD_ALLOCATION(result) = needed; 01765 mgr->last_alloc = result; 01766 01767 return result; 01768 }
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 1662 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_mgr::owner_file, ast_string_field_mgr::owner_func, ast_string_field_mgr::owner_line, ast_string_field_pool::prev, and ast_string_field_pool::used.
01664 { 01665 const char **p = (const char **) pool_head + 1; 01666 struct ast_string_field_pool *cur = NULL; 01667 struct ast_string_field_pool *preserve = NULL; 01668 01669 /* clear fields - this is always necessary */ 01670 while ((struct ast_string_field_mgr *) p != mgr) { 01671 *p++ = __ast_string_field_empty; 01672 } 01673 01674 mgr->last_alloc = NULL; 01675 #if defined(__AST_DEBUG_MALLOC) 01676 mgr->owner_file = file; 01677 mgr->owner_func = func; 01678 mgr->owner_line = lineno; 01679 #endif 01680 if (needed > 0) { /* allocate the initial pool */ 01681 *pool_head = NULL; 01682 mgr->embedded_pool = NULL; 01683 return add_string_pool(mgr, pool_head, needed, file, lineno, func); 01684 } 01685 01686 /* if there is an embedded pool, we can't actually release *all* 01687 * pools, we must keep the embedded one. if the caller is about 01688 * to free the structure that contains the stringfield manager 01689 * and embedded pool anyway, it will be freed as part of that 01690 * operation. 01691 */ 01692 if ((needed < 0) && mgr->embedded_pool) { 01693 needed = 0; 01694 } 01695 01696 if (needed < 0) { /* reset all pools */ 01697 cur = *pool_head; 01698 } else if (mgr->embedded_pool) { /* preserve the embedded pool */ 01699 preserve = mgr->embedded_pool; 01700 cur = *pool_head; 01701 } else { /* preserve the last pool */ 01702 if (*pool_head == NULL) { 01703 ast_log(LOG_WARNING, "trying to reset empty pool\n"); 01704 return -1; 01705 } 01706 preserve = *pool_head; 01707 cur = preserve->prev; 01708 } 01709 01710 if (preserve) { 01711 preserve->prev = NULL; 01712 preserve->used = preserve->active = 0; 01713 } 01714 01715 while (cur) { 01716 struct ast_string_field_pool *prev = cur->prev; 01717 01718 if (cur != preserve) { 01719 ast_free(cur); 01720 } 01721 cur = prev; 01722 } 01723 01724 *pool_head = preserve; 01725 01726 return 0; 01727 }
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 1873 of file utils.c.
References __ast_string_field_ptr_build_va().
01876 { 01877 va_list ap1, ap2; 01878 01879 va_start(ap1, format); 01880 va_start(ap2, format); /* va_copy does not exist on FreeBSD */ 01881 01882 __ast_string_field_ptr_build_va(mgr, pool_head, ptr, format, ap1, ap2); 01883 01884 va_end(ap1); 01885 va_end(ap2); 01886 }
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 1813 of file utils.c.
References __ast_string_field_alloc_space(), __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().
01816 { 01817 size_t needed; 01818 size_t available; 01819 size_t space = (*pool_head)->size - (*pool_head)->used; 01820 ssize_t grow; 01821 char *target; 01822 01823 /* if the field already has space allocated, try to reuse it; 01824 otherwise, try to use the empty space at the end of the current 01825 pool 01826 */ 01827 if (*ptr != __ast_string_field_empty) { 01828 target = (char *) *ptr; 01829 available = AST_STRING_FIELD_ALLOCATION(*ptr); 01830 if (*ptr == mgr->last_alloc) { 01831 available += space; 01832 } 01833 } else { 01834 /* pool->used is always a multiple of ast_alignof(ast_string_field_allocation) 01835 * so we don't need to re-align anything here. 01836 */ 01837 target = (*pool_head)->base + (*pool_head)->used + ast_alignof(ast_string_field_allocation); 01838 available = space - ast_alignof(ast_string_field_allocation); 01839 } 01840 01841 needed = vsnprintf(target, available, format, ap1) + 1; 01842 01843 if (needed > available) { 01844 /* the allocation could not be satisfied using the field's current allocation 01845 (if it has one), or the space available in the pool (if it does not). allocate 01846 space for it, adding a new string pool if necessary. 01847 */ 01848 if (!(target = (char *) __ast_string_field_alloc_space(mgr, pool_head, needed))) { 01849 return; 01850 } 01851 vsprintf(target, format, ap2); 01852 __ast_string_field_release_active(*pool_head, *ptr); 01853 *ptr = target; 01854 } else if (*ptr != target) { 01855 /* the allocation was satisfied using available space in the pool, but not 01856 using the space already allocated to the field 01857 */ 01858 __ast_string_field_release_active(*pool_head, *ptr); 01859 mgr->last_alloc = *ptr = target; 01860 AST_STRING_FIELD_ALLOCATION(target) = needed; 01861 (*pool_head)->used += ast_make_room_for(needed, ast_string_field_allocation); 01862 (*pool_head)->active += needed; 01863 } else if ((grow = (needed - AST_STRING_FIELD_ALLOCATION(*ptr))) > 0) { 01864 /* the allocation was satisfied by using available space in the pool *and* 01865 the field was the last allocated field from the pool, so it grew 01866 */ 01867 AST_STRING_FIELD_ALLOCATION(*ptr) += grow; 01868 (*pool_head)->used += ast_align_for(grow, ast_string_field_allocation); 01869 (*pool_head)->active += grow; 01870 } 01871 }
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 1770 of file utils.c.
References AST_STRING_FIELD_ALLOCATION, and ast_string_field_mgr::last_alloc.
01773 { 01774 ssize_t grow = needed - AST_STRING_FIELD_ALLOCATION(*ptr); 01775 size_t space = (*pool_head)->size - (*pool_head)->used; 01776 01777 if (*ptr != mgr->last_alloc) { 01778 return 1; 01779 } 01780 01781 if (space < grow) { 01782 return 1; 01783 } 01784 01785 (*pool_head)->used += grow; 01786 (*pool_head)->active += grow; 01787 AST_STRING_FIELD_ALLOCATION(*ptr) += grow; 01788 01789 return 0; 01790 }
void __ast_string_field_release_active | ( | struct ast_string_field_pool * | pool_head, | |
const ast_string_field | ptr | |||
) |
Definition at line 1792 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().
01794 { 01795 struct ast_string_field_pool *pool, *prev; 01796 01797 if (ptr == __ast_string_field_empty) { 01798 return; 01799 } 01800 01801 for (pool = pool_head, prev = NULL; pool; prev = pool, pool = pool->prev) { 01802 if ((ptr >= pool->base) && (ptr <= (pool->base + pool->size))) { 01803 pool->active -= AST_STRING_FIELD_ALLOCATION(ptr); 01804 if ((pool->active == 0) && prev) { 01805 prev->prev = pool->prev; 01806 ast_free(pool); 01807 } 01808 break; 01809 } 01810 } 01811 }
const char* __ast_string_field_empty |