Wed Jan 8 2020 09:50:21

Asterisk developer's documentation


stringfields.h File Reference

String fields in structures. More...

Go to the source code of this file.

Data Structures

struct  ast_string_field_mgr
 
struct  ast_string_field_pool
 

Macros

#define ast_calloc_with_stringfields(n, type, size)
 Allocate a structure with embedded stringfields in a single allocation. More...
 
#define AST_DECLARE_STRING_FIELDS(field_list)
 Declare the fields needed in a structure. More...
 
#define AST_STRING_FIELD(name)   const ast_string_field name
 Declare a string field. More...
 
#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. More...
 
#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. More...
 
#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. More...
 
#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 More...
 
#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. More...
 
#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. More...
 
#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. More...
 
#define ast_string_field_ptr_set(x, ptr, data)
 Set a field to a simple string value. More...
 
#define ast_string_field_set(x, field, data)
 Set a field to a simple string value. More...
 

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;
);
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)
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:

This completes the API description.

Definition in file stringfields.h.

Macro Definition 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__)
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: utils.c:2026
static const char type[]
Definition: chan_nbs.c:57

Allocate a structure with embedded stringfields in a single allocation.

Parameters
nNumber of structures to allocate (see ast_calloc)
typeThe type of structure to allocate
sizeThe 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(), 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_listThe 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
nameThe 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.

Parameters
xPointer 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
xPointer to a structure containing fields
fieldName of the field to set
fmtprintf-style format string
argsArguments 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_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
xPointer to a structure containing fields
fieldName of the field to set
fmtprintf-style format string
args1argument one
args2argument two
Returns
nothing

Definition at line 391 of file stringfields.h.

Referenced by __ast_channel_alloc_ap().

#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
xPointer to a structure containing fields
ptrPointer to a field within the structure
fmtprintf-style format string
argsArguments 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
xPointer to a structure containing fields
ptrPointer to a field within the structure
fmtprintf-style format string
args1Arguments for format string in va_list format
args2a 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
xPointer to a structure containing fields
ptrPointer to a field within the structure
dataString 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)
#define ast_string_field_ptr_set(x, ptr, data)
Set a field to a simple string value.
Definition: stringfields.h:318

Set a field to a simple string value.

Parameters
xPointer to a structure containing fields
fieldName of the field to set
dataString 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_peer(), 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(), sig_pri_handle_subcmds(), 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(), __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.

2029 {
2030  struct ast_string_field_mgr *mgr;
2031  struct ast_string_field_pool *pool;
2032  struct ast_string_field_pool **pool_head;
2033  size_t pool_size_needed = sizeof(*pool) + pool_size;
2034  size_t size_to_alloc = optimal_alloc_size(struct_size + pool_size_needed);
2035  void *allocation;
2036  unsigned int x;
2037 
2038 #if defined(__AST_DEBUG_MALLOC)
2039  if (!(allocation = __ast_calloc(num_structs, size_to_alloc, file, lineno, func))) {
2040  return NULL;
2041  }
2042 #else
2043  if (!(allocation = ast_calloc(num_structs, size_to_alloc))) {
2044  return NULL;
2045  }
2046 #endif
2047 
2048  for (x = 0; x < num_structs; x++) {
2049  void *base = allocation + (size_to_alloc * x);
2050  const char **p;
2051 
2052  mgr = base + field_mgr_offset;
2053  pool_head = base + field_mgr_pool_offset;
2054  pool = base + struct_size;
2055 
2056  p = (const char **) pool_head + 1;
2057  while ((struct ast_string_field_mgr *) p != mgr) {
2058  *p++ = __ast_string_field_empty;
2059  }
2060 
2061  mgr->embedded_pool = pool;
2062  *pool_head = pool;
2063  pool->size = size_to_alloc - struct_size - sizeof(*pool);
2064 #if defined(__AST_DEBUG_MALLOC)
2065  mgr->owner_file = file;
2066  mgr->owner_func = func;
2067  mgr->owner_line = lineno;
2068 #endif
2069  }
2070 
2071  return allocation;
2072 }
ast_string_field_allocation allocation
Definition: utils.c:1721
struct ast_string_field_pool * embedded_pool
Definition: stringfields.h:147
const char * __ast_string_field_empty
Definition: utils.c:1725
void * __ast_calloc(size_t nmemb, size_t size, const char *file, int lineno, const char *func)
static size_t optimal_alloc_size(size_t size)
Definition: utils.c:1729
#define ast_calloc(a, b)
Definition: astmm.h:82
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, and ast_string_field_mgr::last_alloc.

Referenced by __ast_string_field_ptr_build_va().

1849 {
1850  char *result = NULL;
1851  size_t space = (*pool_head)->size - (*pool_head)->used;
1852  size_t to_alloc;
1853 
1854  /* Make room for ast_string_field_allocation and make it a multiple of that. */
1855  to_alloc = ast_make_room_for(needed, ast_string_field_allocation);
1857 
1858  if (__builtin_expect(to_alloc > space, 0)) {
1859  size_t new_size = (*pool_head)->size;
1860 
1861  while (new_size < to_alloc) {
1862  new_size *= 2;
1863  }
1864 
1865 #if defined(__AST_DEBUG_MALLOC)
1866  if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func))
1867  return NULL;
1868 #else
1869  if (add_string_pool(mgr, pool_head, new_size, __FILE__, __LINE__, __FUNCTION__))
1870  return NULL;
1871 #endif
1872  }
1873 
1874  /* pool->base is always aligned (gcc aligned attribute). We ensure that
1875  * to_alloc is also a multiple of ast_alignof(ast_string_field_allocation)
1876  * causing result to always be aligned as well; which in turn fixes that
1877  * AST_STRING_FIELD_ALLOCATION(result) is aligned. */
1878  result = (*pool_head)->base + (*pool_head)->used;
1879  (*pool_head)->used += to_alloc;
1880  (*pool_head)->active += needed;
1882  AST_STRING_FIELD_ALLOCATION(result) = needed;
1883  mgr->last_alloc = result;
1884 
1885  return result;
1886 }
uint16_t ast_string_field_allocation
Definition: stringfields.h:119
#define ast_alignof(type)
Return the number of bytes used in the alignment of type.
Definition: utils.h:760
#define ast_assert(a)
Definition: utils.h:738
#define AST_STRING_FIELD_ALLOCATION(x)
Macro to provide access to the allocation field that lives immediately in front of a string field...
Definition: stringfields.h:309
#define ast_make_room_for(offset, type)
Increase offset by the required alignment of type and make sure it is a multiple of said alignment...
Definition: utils.h:803
ast_string_field last_alloc
Definition: stringfields.h:146
static int add_string_pool(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head, size_t size, const char *file, int lineno, const char *func)
add a new block to the pool. We can only allocate from the topmost pool, so the fields in *mgr reflec...
Definition: utils.c:1744
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_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.

1782 {
1783  const char **p = (const char **) pool_head + 1;
1784  struct ast_string_field_pool *cur = NULL;
1785  struct ast_string_field_pool *preserve = NULL;
1786 
1787  /* clear fields - this is always necessary */
1788  while ((struct ast_string_field_mgr *) p != mgr) {
1789  *p++ = __ast_string_field_empty;
1790  }
1791 
1792  mgr->last_alloc = NULL;
1793 #if defined(__AST_DEBUG_MALLOC)
1794  mgr->owner_file = file;
1795  mgr->owner_func = func;
1796  mgr->owner_line = lineno;
1797 #endif
1798  if (needed > 0) { /* allocate the initial pool */
1799  *pool_head = NULL;
1800  mgr->embedded_pool = NULL;
1801  return add_string_pool(mgr, pool_head, needed, file, lineno, func);
1802  }
1803 
1804  /* if there is an embedded pool, we can't actually release *all*
1805  * pools, we must keep the embedded one. if the caller is about
1806  * to free the structure that contains the stringfield manager
1807  * and embedded pool anyway, it will be freed as part of that
1808  * operation.
1809  */
1810  if ((needed < 0) && mgr->embedded_pool) {
1811  needed = 0;
1812  }
1813 
1814  if (needed < 0) { /* reset all pools */
1815  cur = *pool_head;
1816  } else if (mgr->embedded_pool) { /* preserve the embedded pool */
1817  preserve = mgr->embedded_pool;
1818  cur = *pool_head;
1819  } else { /* preserve the last pool */
1820  if (*pool_head == NULL) {
1821  ast_log(LOG_WARNING, "trying to reset empty pool\n");
1822  return -1;
1823  }
1824  preserve = *pool_head;
1825  cur = preserve->prev;
1826  }
1827 
1828  if (preserve) {
1829  preserve->prev = NULL;
1830  preserve->used = preserve->active = 0;
1831  }
1832 
1833  while (cur) {
1834  struct ast_string_field_pool *prev = cur->prev;
1835 
1836  if (cur != preserve) {
1837  ast_free(cur);
1838  }
1839  cur = prev;
1840  }
1841 
1842  *pool_head = preserve;
1843 
1844  return 0;
1845 }
struct ast_string_field_pool * embedded_pool
Definition: stringfields.h:147
#define LOG_WARNING
Definition: logger.h:144
const char * __ast_string_field_empty
Definition: utils.c:1725
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ast_free(a)
Definition: astmm.h:97
struct ast_string_field_pool * prev
Definition: stringfields.h:134
ast_string_field last_alloc
Definition: stringfields.h:146
static int add_string_pool(struct ast_string_field_mgr *mgr, struct ast_string_field_pool **pool_head, size_t size, const char *file, int lineno, const char *func)
add a new block to the pool. We can only allocate from the topmost pool, so the fields in *mgr reflec...
Definition: utils.c:1744
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().

2014 {
2015  va_list ap1, ap2;
2016 
2017  va_start(ap1, format);
2018  va_start(ap2, format); /* va_copy does not exist on FreeBSD */
2019 
2020  __ast_string_field_ptr_build_va(mgr, pool_head, ptr, format, ap1, ap2);
2021 
2022  va_end(ap1);
2023  va_end(ap2);
2024 }
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: utils.c:1935
static snd_pcm_format_t format
Definition: chan_alsa.c:93
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_empty, __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().

1938 {
1939  size_t needed;
1940  size_t available;
1941  size_t space = (*pool_head)->size - (*pool_head)->used;
1942  int res;
1943  ssize_t grow;
1944  char *target;
1945 
1946  /* if the field already has space allocated, try to reuse it;
1947  otherwise, try to use the empty space at the end of the current
1948  pool
1949  */
1950  if (*ptr != __ast_string_field_empty) {
1951  target = (char *) *ptr;
1952  available = AST_STRING_FIELD_ALLOCATION(*ptr);
1953  if (*ptr == mgr->last_alloc) {
1954  available += space;
1955  }
1956  } else {
1957  /* pool->used is always a multiple of ast_alignof(ast_string_field_allocation)
1958  * so we don't need to re-align anything here.
1959  */
1960  target = (*pool_head)->base + (*pool_head)->used + ast_alignof(ast_string_field_allocation);
1962  available = space - ast_alignof(ast_string_field_allocation);
1963  } else {
1964  available = 0;
1965  }
1966  }
1967 
1968  res = vsnprintf(target, available, format, ap1);
1969  if (res < 0) {
1970  /* Are we out of memory? */
1971  return;
1972  }
1973  if (res == 0) {
1974  __ast_string_field_release_active(*pool_head, *ptr);
1975  *ptr = __ast_string_field_empty;
1976  return;
1977  }
1978  needed = (size_t)res + 1; /* NUL byte */
1979 
1980  if (needed > available) {
1981  /* the allocation could not be satisfied using the field's current allocation
1982  (if it has one), or the space available in the pool (if it does not). allocate
1983  space for it, adding a new string pool if necessary.
1984  */
1985  if (!(target = (char *) __ast_string_field_alloc_space(mgr, pool_head, needed))) {
1986  return;
1987  }
1988  vsprintf(target, format, ap2);
1989  __ast_string_field_release_active(*pool_head, *ptr);
1990  *ptr = target;
1991  } else if (*ptr != target) {
1992  /* the allocation was satisfied using available space in the pool, but not
1993  using the space already allocated to the field
1994  */
1995  __ast_string_field_release_active(*pool_head, *ptr);
1996  mgr->last_alloc = *ptr = target;
1999  (*pool_head)->used += ast_make_room_for(needed, ast_string_field_allocation);
2000  (*pool_head)->active += needed;
2001  } else if ((grow = (needed - AST_STRING_FIELD_ALLOCATION(*ptr))) > 0) {
2002  /* the allocation was satisfied by using available space in the pool *and*
2003  the field was the last allocated field from the pool, so it grew
2004  */
2005  AST_STRING_FIELD_ALLOCATION(*ptr) += grow;
2006  (*pool_head)->used += ast_align_for(grow, ast_string_field_allocation);
2007  (*pool_head)->active += grow;
2008  }
2009 }
uint16_t ast_string_field_allocation
Definition: stringfields.h:119
#define ast_alignof(type)
Return the number of bytes used in the alignment of type.
Definition: utils.h:760
const char * __ast_string_field_empty
Definition: utils.c:1725
#define ast_assert(a)
Definition: utils.h:738
#define AST_STRING_FIELD_ALLOCATION(x)
Macro to provide access to the allocation field that lives immediately in front of a string field...
Definition: stringfields.h:309
#define ast_make_room_for(offset, type)
Increase offset by the required alignment of type and make sure it is a multiple of said alignment...
Definition: utils.h:803
void __ast_string_field_release_active(struct ast_string_field_pool *pool_head, const ast_string_field ptr)
Definition: utils.c:1910
static int available(struct dahdi_pvt **pvt, int is_specific_channel)
Definition: chan_dahdi.c:13288
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: utils.c:1847
#define ast_align_for(offset, type)
Increase offset so it is a multiple of the required alignment of type.
Definition: utils.h:780
static snd_pcm_format_t format
Definition: chan_alsa.c:93
ast_string_field last_alloc
Definition: stringfields.h:146
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.

1891 {
1892  ssize_t grow = needed - AST_STRING_FIELD_ALLOCATION(*ptr);
1893  size_t space = (*pool_head)->size - (*pool_head)->used;
1894 
1895  if (*ptr != mgr->last_alloc) {
1896  return 1;
1897  }
1898 
1899  if (space < grow) {
1900  return 1;
1901  }
1902 
1903  (*pool_head)->used += grow;
1904  (*pool_head)->active += grow;
1905  AST_STRING_FIELD_ALLOCATION(*ptr) += grow;
1906 
1907  return 0;
1908 }
#define AST_STRING_FIELD_ALLOCATION(x)
Macro to provide access to the allocation field that lives immediately in front of a string field...
Definition: stringfields.h:309
ast_string_field last_alloc
Definition: stringfields.h:146
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().

1912 {
1913  struct ast_string_field_pool *pool, *prev;
1914 
1915  if (ptr == __ast_string_field_empty) {
1916  return;
1917  }
1918 
1919  for (pool = pool_head, prev = NULL; pool; prev = pool, pool = pool->prev) {
1920  if ((ptr >= pool->base) && (ptr <= (pool->base + pool->size))) {
1921  pool->active -= AST_STRING_FIELD_ALLOCATION(ptr);
1922  if (pool->active == 0) {
1923  if (prev) {
1924  prev->prev = pool->prev;
1925  ast_free(pool);
1926  } else {
1927  pool->used = 0;
1928  }
1929  }
1930  break;
1931  }
1932  }
1933 }
const char * __ast_string_field_empty
Definition: utils.c:1725
#define AST_STRING_FIELD_ALLOCATION(x)
Macro to provide access to the allocation field that lives immediately in front of a string field...
Definition: stringfields.h:309
#define ast_free(a)
Definition: astmm.h:97
struct ast_string_field_pool * prev
Definition: stringfields.h:134

Variable Documentation

const char* __ast_string_field_empty