#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, args) __ast_string_field_ptr_build_va(&(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_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, args) __ast_string_field_ptr_build_va(&(x)->__field_mgr, &(x)->__field_mgr_pool, (ast_string_field *) ptr, fmt, args) |
| 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 ap) |
| 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(), 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 | ) |
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 action_originate(), build_callid_pvt(), build_callid_registry(), build_contact(), build_profile(), build_user(), caldav_write_event(), fax_gateway_framehook(), handle_request_subscribe(), init_acf_query(), load_config(), parse_cdata(), parse_register_contact(), set_nonce_randdata(), sip_sendhtml(), sip_sipredirect(), spandsp_fax_gateway_cleanup(), and t30_phase_e_handler().
| #define ast_string_field_build_va | ( | x, | |||
| field, | |||||
| fmt, | |||||
| args | ) | __ast_string_field_ptr_build_va(&(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 | |
| args1 | argument one | |
| args2 | argument two |
Definition at line 389 of file stringfields.h.
| #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(), db_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(), msg_data_destructor(), 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(), 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_outgoing(), init_pvt(), msg_data_alloc(), new_iax(), new_realtime_sqlite3_db(), 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, | |||||
| args | ) | __ast_string_field_ptr_build_va(&(x)->__field_mgr, &(x)->__field_mgr_pool, (ast_string_field *) ptr, fmt, args) |
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 __find_callno(), __sip_subscribe_mwi_do(), acf_faxopt_write(), acf_retrieve_docs(), action_originate(), alloc_queue(), append_mailbox_mapping(), apply_outgoing(), ast_log(), ast_manager_register2(), ast_parse_digest(), ast_pbx_outgoing_app(), ast_register_application2(), authenticate_reply(), authenticate_request(), authenticate_verify(), 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(), copy_event_data(), create_addr(), create_addr_from_peer(), custom_prepare(), endelm(), ewscal_load_calendar(), exchangecal_load_calendar(), extract_uri(), fax_gateway_attach(), fax_gateway_detect_t38(), fax_gateway_framehook(), fax_gateway_start(), forked_invite_init(), generic_fax_exec(), get_also_info(), get_destination(), get_pai(), get_realm(), get_rpid(), 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(), ical_load_calendar(), icalendar_add_event(), init_acf_query(), init_pvt(), init_queue(), initreqprep(), load_config(), logger_print_normal(), msg_set_var_full(), new_iax(), new_realtime_sqlite3_db(), parse_ok_contact(), parse_register_contact(), queue_set_param(), raise_exception(), receive_message(), receivefax_exec(), reg_source_db(), register_group(), register_group_feature(), register_verify(), registry_authrequest(), reply_digest(), reqprep(), respprep(), save_osptoken(), sendfax_exec(), set_peer_defaults(), set_pvt_defaults(), sip_alloc(), sip_call(), sip_monitor_instance_init(), sip_msg_send(), sip_park_thread(), sip_parse_register_line(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), sip_sendtext(), sip_set_redirstr(), sip_subscribe_mwi(), 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(), and update_realtime_sqlite3_db().
| 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 1809 of file main/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.
01812 { 01813 struct ast_string_field_mgr *mgr; 01814 struct ast_string_field_pool *pool; 01815 struct ast_string_field_pool **pool_head; 01816 size_t pool_size_needed = sizeof(*pool) + pool_size; 01817 size_t size_to_alloc = optimal_alloc_size(struct_size + pool_size_needed); 01818 void *allocation; 01819 unsigned int x; 01820 01821 #if defined(__AST_DEBUG_MALLOC) 01822 if (!(allocation = __ast_calloc(num_structs, size_to_alloc, file, lineno, func))) { 01823 return NULL; 01824 } 01825 #else 01826 if (!(allocation = ast_calloc(num_structs, size_to_alloc))) { 01827 return NULL; 01828 } 01829 #endif 01830 01831 for (x = 0; x < num_structs; x++) { 01832 void *base = allocation + (size_to_alloc * x); 01833 const char **p; 01834 01835 mgr = base + field_mgr_offset; 01836 pool_head = base + field_mgr_pool_offset; 01837 pool = base + struct_size; 01838 01839 p = (const char **) pool_head + 1; 01840 while ((struct ast_string_field_mgr *) p != mgr) { 01841 *p++ = __ast_string_field_empty; 01842 } 01843 01844 mgr->embedded_pool = pool; 01845 *pool_head = pool; 01846 pool->size = size_to_alloc - struct_size - sizeof(*pool); 01847 #if defined(__AST_DEBUG_MALLOC) 01848 mgr->owner_file = file; 01849 mgr->owner_func = func; 01850 mgr->owner_line = lineno; 01851 #endif 01852 } 01853 01854 return allocation; 01855 }
| 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 1650 of file main/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().
01652 { 01653 char *result = NULL; 01654 size_t space = (*pool_head)->size - (*pool_head)->used; 01655 size_t to_alloc; 01656 01657 /* Make room for ast_string_field_allocation and make it a multiple of that. */ 01658 to_alloc = ast_make_room_for(needed, ast_string_field_allocation); 01659 ast_assert(to_alloc % ast_alignof(ast_string_field_allocation) == 0); 01660 01661 if (__builtin_expect(to_alloc > space, 0)) { 01662 size_t new_size = (*pool_head)->size; 01663 01664 while (new_size < to_alloc) { 01665 new_size *= 2; 01666 } 01667 01668 #if defined(__AST_DEBUG_MALLOC) 01669 if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func)) 01670 return NULL; 01671 #else 01672 if (add_string_pool(mgr, pool_head, new_size, __FILE__, __LINE__, __FUNCTION__)) 01673 return NULL; 01674 #endif 01675 } 01676 01677 /* pool->base is always aligned (gcc aligned attribute). We ensure that 01678 * to_alloc is also a multiple of ast_alignof(ast_string_field_allocation) 01679 * causing result to always be aligned as well; which in turn fixes that 01680 * AST_STRING_FIELD_ALLOCATION(result) is aligned. */ 01681 result = (*pool_head)->base + (*pool_head)->used; 01682 (*pool_head)->used += to_alloc; 01683 (*pool_head)->active += needed; 01684 result += ast_alignof(ast_string_field_allocation); 01685 AST_STRING_FIELD_ALLOCATION(result) = needed; 01686 mgr->last_alloc = result; 01687 01688 return result; 01689 }
| 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 1583 of file main/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.
01585 { 01586 const char **p = (const char **) pool_head + 1; 01587 struct ast_string_field_pool *cur = NULL; 01588 struct ast_string_field_pool *preserve = NULL; 01589 01590 /* clear fields - this is always necessary */ 01591 while ((struct ast_string_field_mgr *) p != mgr) { 01592 *p++ = __ast_string_field_empty; 01593 } 01594 01595 mgr->last_alloc = NULL; 01596 #if defined(__AST_DEBUG_MALLOC) 01597 mgr->owner_file = file; 01598 mgr->owner_func = func; 01599 mgr->owner_line = lineno; 01600 #endif 01601 if (needed > 0) { /* allocate the initial pool */ 01602 *pool_head = NULL; 01603 mgr->embedded_pool = NULL; 01604 return add_string_pool(mgr, pool_head, needed, file, lineno, func); 01605 } 01606 01607 /* if there is an embedded pool, we can't actually release *all* 01608 * pools, we must keep the embedded one. if the caller is about 01609 * to free the structure that contains the stringfield manager 01610 * and embedded pool anyway, it will be freed as part of that 01611 * operation. 01612 */ 01613 if ((needed < 0) && mgr->embedded_pool) { 01614 needed = 0; 01615 } 01616 01617 if (needed < 0) { /* reset all pools */ 01618 cur = *pool_head; 01619 } else if (mgr->embedded_pool) { /* preserve the embedded pool */ 01620 preserve = mgr->embedded_pool; 01621 cur = *pool_head; 01622 } else { /* preserve the last pool */ 01623 if (*pool_head == NULL) { 01624 ast_log(LOG_WARNING, "trying to reset empty pool\n"); 01625 return -1; 01626 } 01627 preserve = *pool_head; 01628 cur = preserve->prev; 01629 } 01630 01631 if (preserve) { 01632 preserve->prev = NULL; 01633 preserve->used = preserve->active = 0; 01634 } 01635 01636 while (cur) { 01637 struct ast_string_field_pool *prev = cur->prev; 01638 01639 if (cur != preserve) { 01640 ast_free(cur); 01641 } 01642 cur = prev; 01643 } 01644 01645 *pool_head = preserve; 01646 01647 return 0; 01648 }
| 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 1798 of file main/utils.c.
References __ast_string_field_ptr_build_va().
01801 { 01802 va_list ap; 01803 01804 va_start(ap, format); 01805 __ast_string_field_ptr_build_va(mgr, pool_head, ptr, format, ap); 01806 va_end(ap); 01807 }
| 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 | ap | |||
| ) |
Definition at line 1734 of file main/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().
01737 { 01738 size_t needed; 01739 size_t available; 01740 size_t space = (*pool_head)->size - (*pool_head)->used; 01741 ssize_t grow; 01742 char *target; 01743 va_list ap2; 01744 01745 /* if the field already has space allocated, try to reuse it; 01746 otherwise, try to use the empty space at the end of the current 01747 pool 01748 */ 01749 if (*ptr != __ast_string_field_empty) { 01750 target = (char *) *ptr; 01751 available = AST_STRING_FIELD_ALLOCATION(*ptr); 01752 if (*ptr == mgr->last_alloc) { 01753 available += space; 01754 } 01755 } else { 01756 /* pool->used is always a multiple of ast_alignof(ast_string_field_allocation) 01757 * so we don't need to re-align anything here. 01758 */ 01759 target = (*pool_head)->base + (*pool_head)->used + ast_alignof(ast_string_field_allocation); 01760 available = space - ast_alignof(ast_string_field_allocation); 01761 } 01762 01763 va_copy(ap2, ap); 01764 needed = vsnprintf(target, available, format, ap2) + 1; 01765 va_end(ap2); 01766 01767 if (needed > available) { 01768 /* the allocation could not be satisfied using the field's current allocation 01769 (if it has one), or the space available in the pool (if it does not). allocate 01770 space for it, adding a new string pool if necessary. 01771 */ 01772 if (!(target = (char *) __ast_string_field_alloc_space(mgr, pool_head, needed))) { 01773 return; 01774 } 01775 vsprintf(target, format, ap); 01776 va_end(ap); 01777 __ast_string_field_release_active(*pool_head, *ptr); 01778 *ptr = target; 01779 } else if (*ptr != target) { 01780 /* the allocation was satisfied using available space in the pool, but not 01781 using the space already allocated to the field 01782 */ 01783 __ast_string_field_release_active(*pool_head, *ptr); 01784 mgr->last_alloc = *ptr = target; 01785 AST_STRING_FIELD_ALLOCATION(target) = needed; 01786 (*pool_head)->used += ast_make_room_for(needed, ast_string_field_allocation); 01787 (*pool_head)->active += needed; 01788 } else if ((grow = (needed - AST_STRING_FIELD_ALLOCATION(*ptr))) > 0) { 01789 /* the allocation was satisfied by using available space in the pool *and* 01790 the field was the last allocated field from the pool, so it grew 01791 */ 01792 AST_STRING_FIELD_ALLOCATION(*ptr) += grow; 01793 (*pool_head)->used += ast_align_for(grow, ast_string_field_allocation); 01794 (*pool_head)->active += grow; 01795 } 01796 }
| 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 1691 of file main/utils.c.
References AST_STRING_FIELD_ALLOCATION, and ast_string_field_mgr::last_alloc.
01694 { 01695 ssize_t grow = needed - AST_STRING_FIELD_ALLOCATION(*ptr); 01696 size_t space = (*pool_head)->size - (*pool_head)->used; 01697 01698 if (*ptr != mgr->last_alloc) { 01699 return 1; 01700 } 01701 01702 if (space < grow) { 01703 return 1; 01704 } 01705 01706 (*pool_head)->used += grow; 01707 (*pool_head)->active += grow; 01708 AST_STRING_FIELD_ALLOCATION(*ptr) += grow; 01709 01710 return 0; 01711 }
| void __ast_string_field_release_active | ( | struct ast_string_field_pool * | pool_head, | |
| const ast_string_field | ptr | |||
| ) |
Definition at line 1713 of file main/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().
01715 { 01716 struct ast_string_field_pool *pool, *prev; 01717 01718 if (ptr == __ast_string_field_empty) { 01719 return; 01720 } 01721 01722 for (pool = pool_head, prev = NULL; pool; prev = pool, pool = pool->prev) { 01723 if ((ptr >= pool->base) && (ptr <= (pool->base + pool->size))) { 01724 pool->active -= AST_STRING_FIELD_ALLOCATION(ptr); 01725 if ((pool->active == 0) && prev) { 01726 prev->prev = pool->prev; 01727 ast_free(pool); 01728 } 01729 break; 01730 } 01731 } 01732 }
| const char* __ast_string_field_empty |
Definition at line 1528 of file main/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