Thu Sep 7 01:03:39 2017

Asterisk developer's documentation


stringfields.h File Reference

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

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 (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 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 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(), and sip_subscribe_mwi().

#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 235 of file stringfields.h.

#define AST_STRING_FIELD ( name   )     const ast_string_field name

Declare a string field.

Parameters:
name The field name

Definition at line 220 of file stringfields.h.

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

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

Definition at line 367 of file stringfields.h.

Referenced by __ast_channel_alloc_ap(), action_originate(), build_callid_pvt(), build_callid_registry(), build_contact(), build_localtag_registry(), 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.

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

Definition at line 391 of file stringfields.h.

Referenced by __ast_channel_alloc_ap().

#define ast_string_field_free_memory (  )     __ast_string_field_init(&(x)->__field_mgr, &(x)->__field_mgr_pool, -1, __FILE__, __LINE__, __PRETTY_FUNCTION__)
#define ast_string_field_init ( x,
size   )     __ast_string_field_init(&(x)->__field_mgr, &(x)->__field_mgr_pool, size, __FILE__, __LINE__, __PRETTY_FUNCTION__)
#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 356 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.

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

Definition at line 379 of file stringfields.h.

#define ast_string_field_ptr_set ( x,
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
Returns:
nothing

Definition at line 318 of file stringfields.h.

Referenced by ast_parse_digest(), and reply_digest().

#define ast_string_field_set ( x,
field,
data   ) 
Value:
do {     \
   ast_string_field_ptr_set(x, &(x)->field, data);    \
   } while (0)

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

Definition at line 344 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_register(), 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 Documentation

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.


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

02029 {
02030    struct ast_string_field_mgr *mgr;
02031    struct ast_string_field_pool *pool;
02032    struct ast_string_field_pool **pool_head;
02033    size_t pool_size_needed = sizeof(*pool) + pool_size;
02034    size_t size_to_alloc = optimal_alloc_size(struct_size + pool_size_needed);
02035    void *allocation;
02036    unsigned int x;
02037 
02038 #if defined(__AST_DEBUG_MALLOC)  
02039    if (!(allocation = __ast_calloc(num_structs, size_to_alloc, file, lineno, func))) {
02040       return NULL;
02041    }
02042 #else
02043    if (!(allocation = ast_calloc(num_structs, size_to_alloc))) {
02044       return NULL;
02045    }
02046 #endif
02047 
02048    for (x = 0; x < num_structs; x++) {
02049       void *base = allocation + (size_to_alloc * x);
02050       const char **p;
02051 
02052       mgr = base + field_mgr_offset;
02053       pool_head = base + field_mgr_pool_offset;
02054       pool = base + struct_size;
02055 
02056       p = (const char **) pool_head + 1;
02057       while ((struct ast_string_field_mgr *) p != mgr) {
02058          *p++ = __ast_string_field_empty;
02059       }
02060 
02061       mgr->embedded_pool = pool;
02062       *pool_head = pool;
02063       pool->size = size_to_alloc - struct_size - sizeof(*pool);
02064 #if defined(__AST_DEBUG_MALLOC)
02065       mgr->owner_file = file;
02066       mgr->owner_func = func;
02067       mgr->owner_line = lineno;
02068 #endif
02069    }
02070 
02071    return allocation;
02072 }

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 1847 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().

01849 {
01850    char *result = NULL;
01851    size_t space = (*pool_head)->size - (*pool_head)->used;
01852    size_t to_alloc;
01853 
01854    /* Make room for ast_string_field_allocation and make it a multiple of that. */
01855    to_alloc = ast_make_room_for(needed, ast_string_field_allocation);
01856    ast_assert(to_alloc % ast_alignof(ast_string_field_allocation) == 0);
01857 
01858    if (__builtin_expect(to_alloc > space, 0)) {
01859       size_t new_size = (*pool_head)->size;
01860 
01861       while (new_size < to_alloc) {
01862          new_size *= 2;
01863       }
01864 
01865 #if defined(__AST_DEBUG_MALLOC)
01866       if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func))
01867          return NULL;
01868 #else
01869       if (add_string_pool(mgr, pool_head, new_size, __FILE__, __LINE__, __FUNCTION__))
01870          return NULL;
01871 #endif
01872    }
01873 
01874    /* pool->base is always aligned (gcc aligned attribute). We ensure that
01875     * to_alloc is also a multiple of ast_alignof(ast_string_field_allocation)
01876     * causing result to always be aligned as well; which in turn fixes that
01877     * AST_STRING_FIELD_ALLOCATION(result) is aligned. */
01878    result = (*pool_head)->base + (*pool_head)->used;
01879    (*pool_head)->used += to_alloc;
01880    (*pool_head)->active += needed;
01881    result += ast_alignof(ast_string_field_allocation);
01882    AST_STRING_FIELD_ALLOCATION(result) = needed;
01883    mgr->last_alloc = result;
01884 
01885    return result;
01886 }

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

01782 {
01783    const char **p = (const char **) pool_head + 1;
01784    struct ast_string_field_pool *cur = NULL;
01785    struct ast_string_field_pool *preserve = NULL;
01786 
01787    /* clear fields - this is always necessary */
01788    while ((struct ast_string_field_mgr *) p != mgr) {
01789       *p++ = __ast_string_field_empty;
01790    }
01791 
01792    mgr->last_alloc = NULL;
01793 #if defined(__AST_DEBUG_MALLOC)
01794    mgr->owner_file = file;
01795    mgr->owner_func = func;
01796    mgr->owner_line = lineno;
01797 #endif
01798    if (needed > 0) {    /* allocate the initial pool */
01799       *pool_head = NULL;
01800       mgr->embedded_pool = NULL;
01801       return add_string_pool(mgr, pool_head, needed, file, lineno, func);
01802    }
01803 
01804    /* if there is an embedded pool, we can't actually release *all*
01805     * pools, we must keep the embedded one. if the caller is about
01806     * to free the structure that contains the stringfield manager
01807     * and embedded pool anyway, it will be freed as part of that
01808     * operation.
01809     */
01810    if ((needed < 0) && mgr->embedded_pool) {
01811       needed = 0;
01812    }
01813 
01814    if (needed < 0) {    /* reset all pools */
01815       cur = *pool_head;
01816    } else if (mgr->embedded_pool) { /* preserve the embedded pool */
01817       preserve = mgr->embedded_pool;
01818       cur = *pool_head;
01819    } else {       /* preserve the last pool */
01820       if (*pool_head == NULL) {
01821          ast_log(LOG_WARNING, "trying to reset empty pool\n");
01822          return -1;
01823       }
01824       preserve = *pool_head;
01825       cur = preserve->prev;
01826    }
01827 
01828    if (preserve) {
01829       preserve->prev = NULL;
01830       preserve->used = preserve->active = 0;
01831    }
01832 
01833    while (cur) {
01834       struct ast_string_field_pool *prev = cur->prev;
01835 
01836       if (cur != preserve) {
01837          ast_free(cur);
01838       }
01839       cur = prev;
01840    }
01841 
01842    *pool_head = preserve;
01843 
01844    return 0;
01845 }

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 2011 of file utils.c.

References __ast_string_field_ptr_build_va().

02014 {
02015    va_list ap1, ap2;
02016 
02017    va_start(ap1, format);
02018    va_start(ap2, format);     /* va_copy does not exist on FreeBSD */
02019 
02020    __ast_string_field_ptr_build_va(mgr, pool_head, ptr, format, ap1, ap2);
02021 
02022    va_end(ap1);
02023    va_end(ap2);
02024 }

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 1935 of file 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(), and ast_string_field_mgr::last_alloc.

Referenced by __ast_string_field_ptr_build().

01938 {
01939    size_t needed;
01940    size_t available;
01941    size_t space = (*pool_head)->size - (*pool_head)->used;
01942    int res;
01943    ssize_t grow;
01944    char *target;
01945 
01946    /* if the field already has space allocated, try to reuse it;
01947       otherwise, try to use the empty space at the end of the current
01948       pool
01949    */
01950    if (*ptr != __ast_string_field_empty) {
01951       target = (char *) *ptr;
01952       available = AST_STRING_FIELD_ALLOCATION(*ptr);
01953       if (*ptr == mgr->last_alloc) {
01954          available += space;
01955       }
01956    } else {
01957       /* pool->used is always a multiple of ast_alignof(ast_string_field_allocation)
01958        * so we don't need to re-align anything here.
01959        */
01960       target = (*pool_head)->base + (*pool_head)->used + ast_alignof(ast_string_field_allocation);
01961       if (space > ast_alignof(ast_string_field_allocation)) {
01962          available = space - ast_alignof(ast_string_field_allocation);
01963       } else {
01964          available = 0;
01965       }
01966    }
01967 
01968    res = vsnprintf(target, available, format, ap1);
01969    if (res < 0) {
01970       /* Are we out of memory? */
01971       return;
01972    }
01973    if (res == 0) {
01974       __ast_string_field_release_active(*pool_head, *ptr);
01975       *ptr = __ast_string_field_empty;
01976       return;
01977    }
01978    needed = (size_t)res + 1; /* NUL byte */
01979 
01980    if (needed > available) {
01981       /* the allocation could not be satisfied using the field's current allocation
01982          (if it has one), or the space available in the pool (if it does not). allocate
01983          space for it, adding a new string pool if necessary.
01984       */
01985       if (!(target = (char *) __ast_string_field_alloc_space(mgr, pool_head, needed))) {
01986          return;
01987       }
01988       vsprintf(target, format, ap2);
01989       __ast_string_field_release_active(*pool_head, *ptr);
01990       *ptr = target;
01991    } else if (*ptr != target) {
01992       /* the allocation was satisfied using available space in the pool, but not
01993          using the space already allocated to the field
01994       */
01995       __ast_string_field_release_active(*pool_head, *ptr);
01996       mgr->last_alloc = *ptr = target;
01997            ast_assert(needed < (ast_string_field_allocation)-1);
01998       AST_STRING_FIELD_ALLOCATION(target) = (ast_string_field_allocation)needed;
01999       (*pool_head)->used += ast_make_room_for(needed, ast_string_field_allocation);
02000       (*pool_head)->active += needed;
02001    } else if ((grow = (needed - AST_STRING_FIELD_ALLOCATION(*ptr))) > 0) {
02002       /* the allocation was satisfied by using available space in the pool *and*
02003          the field was the last allocated field from the pool, so it grew
02004       */
02005       AST_STRING_FIELD_ALLOCATION(*ptr) += grow;
02006       (*pool_head)->used += ast_align_for(grow, ast_string_field_allocation);
02007       (*pool_head)->active += grow;
02008    }
02009 }

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 1888 of file utils.c.

References AST_STRING_FIELD_ALLOCATION, and ast_string_field_mgr::last_alloc.

01891 {
01892    ssize_t grow = needed - AST_STRING_FIELD_ALLOCATION(*ptr);
01893    size_t space = (*pool_head)->size - (*pool_head)->used;
01894 
01895    if (*ptr != mgr->last_alloc) {
01896       return 1;
01897    }
01898 
01899    if (space < grow) {
01900       return 1;
01901    }
01902 
01903    (*pool_head)->used += grow;
01904    (*pool_head)->active += grow;
01905    AST_STRING_FIELD_ALLOCATION(*ptr) += grow;
01906 
01907    return 0;
01908 }

void __ast_string_field_release_active ( struct ast_string_field_pool pool_head,
const ast_string_field  ptr 
)

Definition at line 1910 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().

01912 {
01913    struct ast_string_field_pool *pool, *prev;
01914 
01915    if (ptr == __ast_string_field_empty) {
01916       return;
01917    }
01918 
01919    for (pool = pool_head, prev = NULL; pool; prev = pool, pool = pool->prev) {
01920       if ((ptr >= pool->base) && (ptr <= (pool->base + pool->size))) {
01921          pool->active -= AST_STRING_FIELD_ALLOCATION(ptr);
01922          if (pool->active == 0) {
01923             if (prev) {
01924                prev->prev = pool->prev;
01925                ast_free(pool);
01926             } else {
01927                pool->used = 0;
01928             }
01929          }
01930          break;
01931       }
01932    }
01933 }


Variable Documentation

Definition at line 1725 of file utils.c.


Generated on 7 Sep 2017 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1