stringfields.h File Reference

String fields in structures. More...

#include "asterisk/inline_api.h"

Include dependency graph for stringfields.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)   ast_string_field_ptr_set_by_fields((x)->__field_mgr_pool, (x)->__field_mgr, ptr, data)
 Set a field to a simple string value.
#define ast_string_field_ptr_set_by_fields(field_mgr_pool, field_mgr, ptr, data)
#define ast_string_field_set(x, field, data)   ast_string_field_ptr_set(x, &(x)->field, data)
 Set a field to a simple string value.
#define ast_string_fields_cmp(instance1, instance2)
 Compare the string fields in two instances of the same structure.
#define ast_string_fields_copy(copy, orig)
 Copy all string fields from one instance to another of the same structure.

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


Detailed Description

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; 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, args)
  ast_string_field_ptr_build_va(x, &x->bar, fmt, args)

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 Documentation

#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__)
Allocate a structure with embedded stringfields in a single allocation.

Parameters:
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.

Since:
1.8

Definition at line 273 of file stringfields.h.

Referenced by alloc_header(), append_mailbox_mapping(), ast_log_full(), AST_TEST_DEFINE(), build_extension(), build_profile(), jack_data_alloc(), load_config(), load_module(), raise_exception(), and sip_refer_alloc().

#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
Declare the fields needed in a structure.

Parameters:
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 233 of file stringfields.h.

Referenced by AST_TEST_DEFINE().

#define AST_STRING_FIELD ( name   )     const ast_string_field name

Declare a string field.

Parameters:
name The field name

Definition at line 218 of file stringfields.h.

Referenced by AST_TEST_DEFINE().

#define AST_STRING_FIELD_ALLOCATION (  )     *((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.

Parameters:
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 307 of file stringfields.h.

Referenced by __ast_string_field_alloc_space(), __ast_string_field_ptr_build_va(), __ast_string_field_ptr_grow(), __ast_string_field_release_active(), and AST_TEST_DEFINE().

#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)

#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.

Parameters:
x Pointer to a structure containing fields
field Name of the field to set
fmt printf-style format string
args Arguments for format string in va_list format
Returns:
nothing

Definition at line 394 of file stringfields.h.

Referenced by ast_msg_set_body(), ast_msg_set_context(), ast_msg_set_endpoint(), ast_msg_set_exten(), ast_msg_set_from(), ast_msg_set_tech(), and ast_msg_set_to().

#define ast_string_field_free_memory (  )     __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

Examples:
/tmp/asterisk-trunk/trunk/main/app.c.

Definition at line 251 of file stringfields.h.

Referenced by __sip_destroy(), action_destroy(), agent_cfg_destructor(), agent_pvt_destructor(), aor_destroy(), ast_applicationmap_item_destructor(), ast_bridge_features_limits_destroy(), ast_channel_internal_cleanup(), ast_custom_function_unregister(), AST_TEST_DEFINE(), ast_unregister_application(), ast_xmpp_client_config_destructor(), asterisk_publication_config_destroy(), attended_transfer_properties_destructor(), auth_destroy(), auth_http_callback(), bridge_profile_sounds_destroy_cb(), bridge_role_destroy(), bridge_snapshot_dtor(), bucket_destroy(), build_user(), caldav_destructor(), calendar_destructor(), calendar_event_destructor(), cdr_object_dtor(), cel_general_config_dtor(), channel_snapshot_dtor(), conf_destructor(), contact_destroy(), copy_to_voicemail(), db_destructor(), delete_extension(), delete_file(), destroy_bridge(), destroy_fast_originate_helper(), destroy_header(), destroy_jack_data(), destroy_mailbox_mapping(), destroy_odbc(), destroy_queue(), destroy_session_details(), device_state_subscription_destroy(), domain_alias_destroy(), endpoint_destructor(), endpoint_dtor(), endpoint_snapshot_dtor(), ewscal_destructor(), exception_store_free(), exchangecal_destructor(), featuregroup_item_destructor(), featuremap_config_destructor(), free_acf_query(), free_outgoing(), general_destructor(), global_destructor(), hepv3_config_dtor(), icalendar_destructor(), info_configuration_destroy(), ip_identify_destroy(), jingle_endpoint_destructor(), jingle_session_destructor(), load_module(), manager_event_blob_dtor(), media_configuration_destroy(), media_index_dtor(), media_info_destroy(), media_variant_destroy(), mixmonitor_free(), msg_data_destructor(), msg_destructor(), mwi_state_dtor(), parked_call_payload_destructor(), parking_lot_cfg_destructor(), parking_lot_destructor(), peer_destructor(), pickup_destructor(), playback_dtor(), presence_state_dtor(), profile_destructor(), provider_destructor(), pvt_destructor(), queue_stasis_data_destructor(), realtime_multi_odbc(), realtime_odbc(), recording_options_dtor(), route_destructor(), sip_destroy_peer(), sip_monitor_instance_destructor(), sip_outbound_publish_destroy(), sip_outbound_registration_destroy(), sip_refer_destroy(), sip_registry_destroy(), sip_subscribe_mwi_destroy(), skel_global_config_destructor(), skel_level_destructor(), sla_station_destructor(), sla_trunk_destructor(), stasis_app_bridge_channel_wrapper_destructor(), store_odbc(), stored_recording_dtor(), subscription_change_dtor(), subscription_configuration_destroy(), tds_unload_module(), temp_pvt_cleanup(), test_item_destructor(), test_vm_api_destroy_mock_snapshot(), transport_destroy(), unbound_global_config_destructor(), update_odbc(), user_destructor(), vm_msg_snapshot_destroy(), and xfer_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.

Parameters:
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.
Returns:
0 on success, non-zero on failure
Examples:
/tmp/asterisk-trunk/trunk/main/app.c.

Definition at line 247 of file stringfields.h.

Referenced by __ast_channel_internal_alloc(), __features_config_alloc(), __sip_alloc(), acf_retrieve_docs(), action_originate(), agent_cfg_alloc(), agent_pvt_new(), alloc_new_parking_lot(), alloc_queue(), aor_alloc(), applicationmap_item_alloc(), ast_bridge_features_limits_construct(), ast_bridge_snapshot_create(), ast_calendar_event_alloc(), ast_cel_general_config_alloc(), ast_channel_snapshot_create(), ast_endpoint_snapshot_create(), ast_manager_event_blob_create(), ast_manager_register2(), ast_media_index_create(), ast_msg_alloc(), ast_mwi_create(), ast_parked_call_payload_create(), ast_phoneprov_provider_register(), ast_register_application2(), ast_sip_endpoint_alloc(), AST_TEST_DEFINE(), ast_xmpp_client_config_alloc(), asterisk_publication_config_alloc(), attended_transfer_properties_alloc(), auth_alloc(), auth_http_callback(), bridge_alloc(), bridge_moh_create(), bridge_profile_sounds_alloc(), bucket_alloc(), bucket_file_alloc(), build_calendar(), build_peer(), build_profile(), build_route(), build_user(), caldav_load_calendar(), cdr_object_alloc(), conf_alloc(), contact_alloc(), copy_to_voicemail(), destroy_odbc(), device_state_subscription_create(), domain_alias_alloc(), endpoint_internal_create(), ewscal_load_calendar(), exchangecal_load_calendar(), featuregroup_handler(), global_alloc(), global_config_alloc(), hepv3_config_alloc(), ical_load_calendar(), init_acf_query(), init_info_configuration(), init_media_configuration(), init_pvt(), init_subscription_configuration(), ip_identify_alloc(), jingle_alloc(), jingle_endpoint_alloc(), launch_monitor_thread(), media_info_alloc(), media_variant_alloc(), msg_data_alloc(), new_iax(), new_outgoing(), new_realtime_sqlite3_db(), parking_lot_cfg_alloc(), playback_create(), presence_state_alloc(), queue_stasis_data_alloc(), realtime_multi_odbc(), realtime_odbc(), recording_alloc(), session_details_new(), setup_bridge_role_option(), sip_monitor_instance_init(), sip_outbound_publish_alloc(), sip_outbound_registration_alloc(), sip_register(), sip_subscribe_mwi(), skel_config_alloc(), skel_level_alloc(), sla_build_station(), sla_build_trunk(), stasis_app_bridge_playback_channel_add(), stasis_app_recording_options_create(), store_odbc(), subscription_change_alloc(), tds_load_module(), temp_peer(), temp_pvt_init(), test_item_alloc(), test_vm_api_create_mock_snapshot(), transmit_response_using_temp(), transport_alloc(), unbound_config_alloc(), update_odbc(), vm_msg_snapshot_alloc(), and xmpp_client_alloc().

#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.

Parameters:
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
Returns:
nothing

Definition at line 361 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.

Parameters:
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 in va_list format
Returns:
nothing

Definition at line 383 of file stringfields.h.

Referenced by ast_manager_event_blob_create().

#define ast_string_field_ptr_set ( x,
ptr,
data   )     ast_string_field_ptr_set_by_fields((x)->__field_mgr_pool, (x)->__field_mgr, ptr, data)

Set a field to a simple string value.

Parameters:
x Pointer to a structure containing fields
ptr Pointer to a field within the structure
data String value to be copied into the field
Return values:
zero on success
non-zero on error

Definition at line 317 of file stringfields.h.

Referenced by ast_parse_digest(), and reply_digest().

#define ast_string_field_ptr_set_by_fields ( field_mgr_pool,
field_mgr,
ptr,
data   ) 

Definition at line 319 of file stringfields.h.

Referenced by stringfield_handler_fn().

#define ast_string_field_set ( x,
field,
data   )     ast_string_field_ptr_set(x, &(x)->field, data)

Set a field to a simple string value.

Parameters:
x Pointer to a structure containing fields
field Name of the field to set
data String value to be copied into the field
Return values:
zero on success
non-zero on error
Examples:
/tmp/asterisk-trunk/trunk/main/app.c.

Definition at line 351 of file stringfields.h.

Referenced by __find_callno(), __sip_alloc(), __sip_subscribe_mwi_do(), acf_faxopt_write(), acf_retrieve_docs(), action_originate(), agent_cfg_alloc(), agent_login_channel_config(), agent_pvt_new(), alloc_header(), alloc_new_parking_lot(), alloc_queue(), append_mailbox_mapping(), applicationmap_item_alloc(), apply_outgoing(), ast_bridge_snapshot_create(), ast_bucket_alloc(), ast_bucket_file_alloc(), ast_cdr_fork(), ast_channel_set_bridge_role_option(), ast_channel_snapshot_create(), ast_endpoint_snapshot_create(), ast_log_full(), ast_manager_register2(), ast_media_index_create(), ast_msg_alloc(), ast_mwi_create(), ast_parked_call_payload_create(), ast_parse_digest(), ast_phoneprov_provider_register(), ast_register_application2(), ast_sip_location_add_contact(), AST_TEST_DEFINE(), ast_xmpp_client_config_alloc(), attended_transfer_properties_alloc(), authenticate_reply(), authenticate_request(), authenticate_verify(), base_process_parked_channel(), base_process_party_a(), bridge_base_init(), bridge_candidate_add_to_cdr(), bridge_config_set_limits_warning_values(), bridge_moh_create(), bridge_template_handler(), 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(), cdr_object_alloc(), cdr_object_create_and_append(), change_callid_pvt(), check_access(), check_peer_ok(), check_user_full(), clone_parkinglot_cfg(), copy_event_data(), copy_to_voicemail(), create_addr(), create_addr_from_peer(), create_artificial_auth(), create_dynamic_lot_full(), custom_prepare(), device_state_subscription_create(), dial_state_process_bridge_enter(), digest_check_auth(), endelm(), endpoint_internal_create(), ewscal_load_calendar(), exchangecal_load_calendar(), extensionstate_update(), extract_uri(), fax_gateway_attach(), fax_gateway_detect_t38(), fax_gateway_framehook(), fax_gateway_start(), feature_attended_transfer(), featuregroup_handler(), featuremap_set(), forked_invite_init(), general_set(), generic_fax_exec(), get_also_info(), get_destination(), get_pai(), get_realm(), get_refer_info(), get_rpid(), handle_bridge_enter(), handle_bridge_leave_message(), handle_cc_notify(), handle_incoming(), handle_local_optimization_end(), 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_register(), handle_response_subscribe(), iax2_call(), iax2_request(), ical_load_calendar(), icalendar_add_event(), init_acf_query(), init_pvt(), init_queue(), initreqprep(), jingle_alloc(), jingle_endpoint_alloc(), jingle_interpret_description(), launch_monitor_thread(), load_config(), load_module(), logger_print_normal(), media_info_alloc(), media_variant_alloc(), msg_set_var_full(), new_iax(), new_outgoing(), new_realtime_sqlite3_db(), parking_lot_cfg_alloc(), parking_lot_cfg_remove_extensions(), parse_ok_contact(), parse_register_contact(), permanent_uri_handler(), pickup_set(), playback_create(), presence_state_alloc(), process_description_file(), queue_set_param(), queue_stasis_data_alloc(), raise_exception(), realtime_exec(), receive_message(), receivefax_exec(), reg_source_db(), register_verify(), registry_authrequest(), reply_digest(), reqprep(), respprep(), rx_task(), save_osptoken(), scan_file(), sendfax_exec(), set_peer_defaults(), set_pvt_defaults(), set_sound(), setup_bridge_role_option(), single_state_process_bridge_enter(), sip_call(), sip_monitor_instance_init(), sip_msg_send(), sip_parse_register_line(), sip_poke_peer(), sip_register(), sip_reload(), sip_request_call(), sip_send_mwi_to_peer(), sip_sendtext(), sip_set_redirstr(), sip_subscribe_mwi(), skel_level_alloc(), sla_build_station(), sla_build_trunk(), socket_process_helper(), startelm(), stasis_app_bridge_playback_channel_add(), stasis_app_control_play_uri(), stasis_app_recording_options_create(), stasis_app_stored_recording_find_by_name(), store_callerid(), subscription_change_alloc(), t30_phase_e_handler(), tds_load_module(), test_item_alloc(), test_vm_api_create_mock_snapshot(), test_vm_api_destroy_mailbox_voicemails(), test_vm_api_test_setup(), test_vm_api_update_test_snapshots(), transmit_refer(), transmit_register(), transmit_response_using_temp(), update_realtime_sqlite3_db(), verify_default_parking_lot(), vm_msg_snapshot_create(), xfer_set(), and xmpp_client_alloc().

#define ast_string_fields_cmp ( instance1,
instance2   ) 

Compare the string fields in two instances of the same structure.

Since:
12
Parameters:
instance1 The first instance of the structure to be compared
instance2 The second instance of the structure to be compared
Return values:
zero if all string fields are equal (does not compare non-string field data)
non-zero if the values of the string fields differ

Definition at line 405 of file stringfields.h.

Referenced by AST_TEST_DEFINE().

#define ast_string_fields_copy ( copy,
orig   ) 

Copy all string fields from one instance to another of the same structure.

Since:
12
Parameters:
copy The instance of the structure to be copied into
orig The instance of the structure to be copied from
Return values:
zero on success
non-zero on error

Definition at line 434 of file stringfields.h.

Referenced by AST_TEST_DEFINE(), bridge_features_limits_copy(), clone_parkinglot_cfg(), featuremap_copy(), general_copy(), pickup_copy(), and xfer_copy().


Typedef Documentation

typedef const char* ast_string_field

Definition at line 114 of file stringfields.h.

typedef uint16_t ast_string_field_allocation

Definition at line 118 of file stringfields.h.


Function Documentation

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 2207 of file main/utils.c.

References __ast_calloc(), allocation, ast_calloc, ast_string_field_pool::base, ast_string_field_mgr::embedded_pool, NULL, optimal_alloc_size(), pool, and ast_string_field_pool::size.

02210 {
02211    struct ast_string_field_mgr *mgr;
02212    struct ast_string_field_pool *pool;
02213    struct ast_string_field_pool **pool_head;
02214    size_t pool_size_needed = sizeof(*pool) + pool_size;
02215    size_t size_to_alloc = optimal_alloc_size(struct_size + pool_size_needed);
02216    void *allocation;
02217    unsigned int x;
02218 
02219 #if defined(__AST_DEBUG_MALLOC)
02220    if (!(allocation = __ast_calloc(num_structs, size_to_alloc, file, lineno, func))) {
02221       return NULL;
02222    }
02223 #else
02224    if (!(allocation = ast_calloc(num_structs, size_to_alloc))) {
02225       return NULL;
02226    }
02227 #endif
02228 
02229    for (x = 0; x < num_structs; x++) {
02230       void *base = allocation + (size_to_alloc * x);
02231       const char **p;
02232 
02233       mgr = base + field_mgr_offset;
02234       pool_head = base + field_mgr_pool_offset;
02235       pool = base + struct_size;
02236 
02237       p = (const char **) pool_head + 1;
02238       while ((struct ast_string_field_mgr *) p != mgr) {
02239          *p++ = __ast_string_field_empty;
02240       }
02241 
02242       mgr->embedded_pool = pool;
02243       *pool_head = pool;
02244       pool->size = size_to_alloc - struct_size - sizeof(*pool);
02245 #if defined(__AST_DEBUG_MALLOC)
02246       mgr->owner_file = file;
02247       mgr->owner_func = func;
02248       mgr->owner_line = lineno;
02249 #endif
02250    }
02251 
02252    return allocation;
02253 }

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 2027 of file main/utils.c.

References add_string_pool(), ast_alignof, ast_assert, ast_make_room_for, AST_STRING_FIELD_ALLOCATION, ast_string_field_mgr::last_alloc, NULL, and result.

Referenced by __ast_string_field_ptr_build_va().

02029 {
02030    char *result = NULL;
02031    size_t space = (*pool_head)->size - (*pool_head)->used;
02032    size_t to_alloc;
02033 
02034    /* Make room for ast_string_field_allocation and make it a multiple of that. */
02035    to_alloc = ast_make_room_for(needed, ast_string_field_allocation);
02036    ast_assert(to_alloc % ast_alignof(ast_string_field_allocation) == 0);
02037 
02038    if (__builtin_expect(to_alloc > space, 0)) {
02039       size_t new_size = (*pool_head)->size;
02040 
02041       while (new_size < to_alloc) {
02042          new_size *= 2;
02043       }
02044 
02045 #if defined(__AST_DEBUG_MALLOC)
02046       if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func))
02047          return NULL;
02048 #else
02049       if (add_string_pool(mgr, pool_head, new_size, __FILE__, __LINE__, __FUNCTION__))
02050          return NULL;
02051 #endif
02052    }
02053 
02054    /* pool->base is always aligned (gcc aligned attribute). We ensure that
02055     * to_alloc is also a multiple of ast_alignof(ast_string_field_allocation)
02056     * causing result to always be aligned as well; which in turn fixes that
02057     * AST_STRING_FIELD_ALLOCATION(result) is aligned. */
02058    result = (*pool_head)->base + (*pool_head)->used;
02059    (*pool_head)->used += to_alloc;
02060    (*pool_head)->active += needed;
02061    result += ast_alignof(ast_string_field_allocation);
02062    AST_STRING_FIELD_ALLOCATION(result) = needed;
02063    mgr->last_alloc = result;
02064 
02065    return result;
02066 }

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 1960 of file main/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, NULL, ast_string_field_pool::prev, and ast_string_field_pool::used.

01962 {
01963    const char **p = (const char **) pool_head + 1;
01964    struct ast_string_field_pool *cur = NULL;
01965    struct ast_string_field_pool *preserve = NULL;
01966 
01967    /* clear fields - this is always necessary */
01968    while ((struct ast_string_field_mgr *) p != mgr) {
01969       *p++ = __ast_string_field_empty;
01970    }
01971 
01972    mgr->last_alloc = NULL;
01973 #if defined(__AST_DEBUG_MALLOC)
01974    mgr->owner_file = file;
01975    mgr->owner_func = func;
01976    mgr->owner_line = lineno;
01977 #endif
01978    if (needed > 0) {    /* allocate the initial pool */
01979       *pool_head = NULL;
01980       mgr->embedded_pool = NULL;
01981       return add_string_pool(mgr, pool_head, needed, file, lineno, func);
01982    }
01983 
01984    /* if there is an embedded pool, we can't actually release *all*
01985     * pools, we must keep the embedded one. if the caller is about
01986     * to free the structure that contains the stringfield manager
01987     * and embedded pool anyway, it will be freed as part of that
01988     * operation.
01989     */
01990    if ((needed < 0) && mgr->embedded_pool) {
01991       needed = 0;
01992    }
01993 
01994    if (needed < 0) {    /* reset all pools */
01995       cur = *pool_head;
01996    } else if (mgr->embedded_pool) { /* preserve the embedded pool */
01997       preserve = mgr->embedded_pool;
01998       cur = *pool_head;
01999    } else {       /* preserve the last pool */
02000       if (*pool_head == NULL) {
02001          ast_log(LOG_WARNING, "trying to reset empty pool\n");
02002          return -1;
02003       }
02004       preserve = *pool_head;
02005       cur = preserve->prev;
02006    }
02007 
02008    if (preserve) {
02009       preserve->prev = NULL;
02010       preserve->used = preserve->active = 0;
02011    }
02012 
02013    while (cur) {
02014       struct ast_string_field_pool *prev = cur->prev;
02015 
02016       if (cur != preserve) {
02017          ast_free(cur);
02018       }
02019       cur = prev;
02020    }
02021 
02022    *pool_head = preserve;
02023 
02024    return 0;
02025 }

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 2196 of file main/utils.c.

References __ast_string_field_ptr_build_va().

02199 {
02200    va_list ap;
02201 
02202    va_start(ap, format);
02203    __ast_string_field_ptr_build_va(mgr, pool_head, ptr, format, ap);
02204    va_end(ap);
02205 }

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 2115 of file main/utils.c.

References __ast_string_field_alloc_space(), __ast_string_field_release_active(), ast_align_for, ast_alignof, ast_assert, ast_make_room_for, AST_STRING_FIELD_ALLOCATION, available(), grow(), and ast_string_field_mgr::last_alloc.

Referenced by __ast_string_field_ptr_build().

02118 {
02119    size_t needed;
02120    size_t available;
02121    size_t space = (*pool_head)->size - (*pool_head)->used;
02122    int res;
02123    ssize_t grow;
02124    char *target;
02125    va_list ap2;
02126 
02127    /* if the field already has space allocated, try to reuse it;
02128       otherwise, try to use the empty space at the end of the current
02129       pool
02130    */
02131    if (*ptr != __ast_string_field_empty) {
02132       target = (char *) *ptr;
02133       available = AST_STRING_FIELD_ALLOCATION(*ptr);
02134       if (*ptr == mgr->last_alloc) {
02135          available += space;
02136       }
02137    } else {
02138       /* pool->used is always a multiple of ast_alignof(ast_string_field_allocation)
02139        * so we don't need to re-align anything here.
02140        */
02141       target = (*pool_head)->base + (*pool_head)->used + ast_alignof(ast_string_field_allocation);
02142       if (space > ast_alignof(ast_string_field_allocation)) {
02143          available = space - ast_alignof(ast_string_field_allocation);
02144       } else {
02145          available = 0;
02146       }
02147    }
02148 
02149    va_copy(ap2, ap);
02150    res = vsnprintf(target, available, format, ap2);
02151    va_end(ap2);
02152 
02153    if (res < 0) {
02154       /* Are we out of memory? */
02155       return;
02156    }
02157    if (res == 0) {
02158       __ast_string_field_release_active(*pool_head, *ptr);
02159       *ptr = __ast_string_field_empty;
02160       return;
02161    }
02162    needed = (size_t)res + 1; /* NUL byte */
02163 
02164    if (needed > available) {
02165       /* the allocation could not be satisfied using the field's current allocation
02166          (if it has one), or the space available in the pool (if it does not). allocate
02167          space for it, adding a new string pool if necessary.
02168       */
02169       if (!(target = (char *) __ast_string_field_alloc_space(mgr, pool_head, needed))) {
02170          return;
02171       }
02172       vsprintf(target, format, ap);
02173       va_end(ap); /* XXX va_end without va_start? */
02174       __ast_string_field_release_active(*pool_head, *ptr);
02175       *ptr = target;
02176    } else if (*ptr != target) {
02177       /* the allocation was satisfied using available space in the pool, but not
02178          using the space already allocated to the field
02179       */
02180       __ast_string_field_release_active(*pool_head, *ptr);
02181       mgr->last_alloc = *ptr = target;
02182            ast_assert(needed < (ast_string_field_allocation)-1);
02183       AST_STRING_FIELD_ALLOCATION(target) = (ast_string_field_allocation)needed;
02184       (*pool_head)->used += ast_make_room_for(needed, ast_string_field_allocation);
02185       (*pool_head)->active += needed;
02186    } else if ((grow = (needed - AST_STRING_FIELD_ALLOCATION(*ptr))) > 0) {
02187       /* the allocation was satisfied by using available space in the pool *and*
02188          the field was the last allocated field from the pool, so it grew
02189       */
02190       AST_STRING_FIELD_ALLOCATION(*ptr) += grow;
02191       (*pool_head)->used += ast_align_for(grow, ast_string_field_allocation);
02192       (*pool_head)->active += grow;
02193    }
02194 }

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 2068 of file main/utils.c.

References AST_STRING_FIELD_ALLOCATION, grow(), and ast_string_field_mgr::last_alloc.

02071 {
02072    ssize_t grow = needed - AST_STRING_FIELD_ALLOCATION(*ptr);
02073    size_t space = (*pool_head)->size - (*pool_head)->used;
02074 
02075    if (*ptr != mgr->last_alloc) {
02076       return 1;
02077    }
02078 
02079    if (space < grow) {
02080       return 1;
02081    }
02082 
02083    (*pool_head)->used += grow;
02084    (*pool_head)->active += grow;
02085    AST_STRING_FIELD_ALLOCATION(*ptr) += grow;
02086 
02087    return 0;
02088 }

void __ast_string_field_release_active ( struct ast_string_field_pool pool_head,
const ast_string_field  ptr 
)

Definition at line 2090 of file main/utils.c.

References ast_string_field_pool::active, ast_free, AST_STRING_FIELD_ALLOCATION, NULL, pool, and ast_string_field_pool::prev.

Referenced by __ast_string_field_ptr_build_va().

02092 {
02093    struct ast_string_field_pool *pool, *prev;
02094 
02095    if (ptr == __ast_string_field_empty) {
02096       return;
02097    }
02098 
02099    for (pool = pool_head, prev = NULL; pool; prev = pool, pool = pool->prev) {
02100       if ((ptr >= pool->base) && (ptr <= (pool->base + pool->size))) {
02101          pool->active -= AST_STRING_FIELD_ALLOCATION(ptr);
02102          if (pool->active == 0) {
02103             if (prev) {
02104                prev->prev = pool->prev;
02105                ast_free(pool);
02106             } else {
02107                pool->used = 0;
02108             }
02109          }
02110          break;
02111       }
02112    }
02113 }


Variable Documentation

Definition at line 1905 of file main/utils.c.

Referenced by AST_TEST_DEFINE().


Generated on Thu Apr 16 06:34:05 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6