Wed Aug 18 22:34:34 2010

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_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_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

Functions

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, size_t needed, 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 (this feature is not used in this code, but comes from external requirements).

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 (XXX perhaps the latter is too much of a restriction since values are not shared).

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; ast_string_field_build_va() is the varargs version of the above (for portability reasons it uses two vararg); 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_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 227 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 212 of file stringfields.h.

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

Referenced by __ast_channel_alloc_ap(), build_callid_pvt(), build_callid_registry(), build_contact(), build_rpid(), build_user(), create_addr_from_peer(), handle_request_subscribe(), handle_response(), mgcp_new(), parse_moved_contact(), parse_register_contact(), pri_fixup_principle(), set_nonce_randdata(), sip_sendhtml(), sip_sipredirect(), and unistim_new().

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

free all memory - to be called before destroying the object

Definition at line 245 of file stringfields.h.

Referenced by __ast_channel_alloc_ap(), __sip_destroy(), ast_channel_free(), ast_unregister_groups(), build_user(), delete_extension(), delete_file(), destroy_jack_data(), destroy_mailbox_mapping(), destroy_queue(), destroy_station(), destroy_trunk(), exception_store_free(), load_module(), peer_destructor(), profile_destructor(), pvt_destructor(), route_destructor(), sip_registry_destroy(), tds_unload_module(), temp_pvt_cleanup(), and user_destructor().

#define ast_string_field_init ( x,
size   )     __ast_string_field_init(&(x)->__field_mgr, &(x)->__field_mgr_pool, size, __FILE__, __LINE__, __PRETTY_FUNCTION__)

Initialize a field pool and fields.

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

Definition at line 241 of file stringfields.h.

Referenced by __ast_channel_alloc_ap(), alloc_queue(), append_mailbox_mapping(), build_extension(), build_peer(), build_profile(), build_route(), build_user(), init_pvt(), jack_data_alloc(), load_module(), new_iax(), pbx_builtin_raise_exception(), register_group(), register_group_feature(), sip_alloc(), sip_register(), sla_build_station(), sla_build_trunk(), tds_load_module(), temp_pvt_init(), and transmit_response_using_temp().

#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 297 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 320 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 262 of file stringfields.h.

Referenced by reply_digest().

#define ast_string_field_set ( x,
field,
data   ) 

Value:

do {     \
   ast_string_field_ptr_set(x, &(x)->field, data);    \
   } while (0)
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 285 of file stringfields.h.

Referenced by __ast_channel_alloc_ap(), __find_callno(), __oh323_new(), agent_new(), alloc_queue(), alsa_new(), append_mailbox_mapping(), ast_call_forward(), ast_cdr_setaccount(), ast_change_name(), ast_do_masquerade(), ast_feature_request_and_dial(), ast_iax2_new(), authenticate_reply(), authenticate_request(), authenticate_verify(), begin_dial_channel(), build_extension(), build_peer(), build_profile(), build_route(), build_rpid(), build_user(), cache_get_callno_locked(), check_access(), check_peer_ok(), check_user_full(), conf_start_moh(), console_new(), create_addr(), create_addr_from_peer(), dahdi_new(), dial_exec_full(), do_forward(), extract_uri(), findmeexec(), get_also_info(), get_destination(), get_rdnis(), gtalk_new(), handle_incoming(), handle_options(), handle_request_bye(), handle_request_invite(), handle_request_options(), handle_request_refer(), handle_response(), handle_response_invite(), handle_response_notify(), iax2_call(), iax2_request(), init_pvt(), init_queue(), initreqprep(), jingle_new(), load_module(), local_call(), mgcp_new(), moh_handle_digit(), monitor_dial(), nbs_new(), new_iax(), oss_new(), parse_moved_contact(), parse_ok_contact(), parse_register_contact(), pbx_builtin_raise_exception(), phone_new(), queue_set_param(), read_config(), register_group(), register_group_feature(), register_verify(), registry_authrequest(), replace_cid(), reply_digest(), reqprep(), respprep(), ring_entry(), save_osptoken(), set_moh_exec(), set_pvt_defaults(), sip_alloc(), sip_call(), sip_new(), sip_park(), sip_poke_peer(), sip_register(), sip_request_call(), sip_set_redirstr(), skinny_new(), sla_build_station(), sla_build_trunk(), socket_process(), store_callerid(), tds_load_module(), transmit_refer(), transmit_register(), transmit_response_using_temp(), unistim_new(), usbradio_new(), vm_execmain(), and wait_for_answer().


Typedef Documentation

typedef const char* ast_string_field

Definition at line 114 of file stringfields.h.


Function Documentation

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

References add_string_pool(), ast_string_field_mgr::last_alloc, ast_string_field_mgr::size, and ast_string_field_mgr::used.

01570 {
01571    char *result = NULL;
01572    size_t space = mgr->size - mgr->used;
01573 
01574    if (__builtin_expect(needed > space, 0)) {
01575       size_t new_size = mgr->size * 2;
01576 
01577       while (new_size < needed)
01578          new_size *= 2;
01579 
01580 #if defined(__AST_DEBUG_MALLOC)
01581       if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func))
01582          return NULL;
01583 #else
01584       if (add_string_pool(mgr, pool_head, new_size, __FILE__, __LINE__, __FUNCTION__))
01585          return NULL;
01586 #endif
01587    }
01588 
01589    result = (*pool_head)->base + mgr->used;
01590    mgr->used += needed;
01591    mgr->last_alloc = result;
01592    return result;
01593 }

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

References add_string_pool(), ast_free, ast_log(), ast_string_field_mgr::last_alloc, LOG_WARNING, ast_string_field_pool::prev, and ast_string_field_mgr::used.

01516 {
01517    const char **p = (const char **) pool_head + 1;
01518    struct ast_string_field_pool *cur = NULL;
01519    struct ast_string_field_pool *preserve = NULL;
01520 
01521    /* clear fields - this is always necessary */
01522    while ((struct ast_string_field_mgr *) p != mgr)
01523       *p++ = __ast_string_field_empty;
01524    mgr->last_alloc = NULL;
01525 #if defined(__AST_DEBUG_MALLOC)
01526    mgr->owner_file = file;
01527    mgr->owner_func = func;
01528    mgr->owner_line = lineno;
01529 #endif
01530    if (needed > 0) {    /* allocate the initial pool */
01531       *pool_head = NULL;
01532       return add_string_pool(mgr, pool_head, needed, file, lineno, func);
01533    }
01534    if (needed < 0) {    /* reset all pools */
01535       if (*pool_head == NULL) {
01536          ast_log(LOG_WARNING, "trying to reset empty pool\n");
01537          return -1;
01538       }
01539       cur = *pool_head;
01540    } else {       /* preserve the last pool */
01541       if (*pool_head == NULL) {
01542          ast_log(LOG_WARNING, "trying to reset empty pool\n");
01543          return -1;
01544       }
01545       mgr->used = 0;
01546       preserve = *pool_head;
01547       cur = preserve->prev;
01548    }
01549 
01550    if (preserve) {
01551       preserve->prev = NULL;
01552    }
01553 
01554    while (cur) {
01555       struct ast_string_field_pool *prev = cur->prev;
01556 
01557       if (cur != preserve) {
01558          ast_free(cur);
01559       }
01560       cur = prev;
01561    }
01562 
01563    *pool_head = preserve;
01564 
01565    return 0;
01566 }

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

References __ast_string_field_ptr_build_va().

01677 {
01678    va_list ap1, ap2;
01679 
01680    va_start(ap1, format);
01681    va_start(ap2, format);     /* va_copy does not exist on FreeBSD */
01682 
01683    __ast_string_field_ptr_build_va(mgr, pool_head, ptr, format, ap1, ap2);
01684 
01685    va_end(ap1);
01686    va_end(ap2);
01687 }

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

References add_string_pool(), available(), ast_string_field_mgr::last_alloc, ast_string_field_mgr::size, and ast_string_field_mgr::used.

Referenced by __ast_string_field_ptr_build().

01621 {
01622    size_t needed;
01623    size_t available;
01624    size_t space = mgr->size - mgr->used;
01625    char *target;
01626 
01627    /* if the field already has space allocated, try to reuse it;
01628       otherwise, use the empty space at the end of the current
01629       pool
01630    */
01631    if ((*ptr)[0] != '\0') {
01632       target = (char *) *ptr;
01633       available = strlen(target) + 1;
01634    } else {
01635       target = (*pool_head)->base + mgr->used;
01636       available = space;
01637    }
01638 
01639    needed = vsnprintf(target, available, format, ap1) + 1;
01640 
01641    va_end(ap1);
01642 
01643    if (needed > available) {
01644       /* if the space needed can be satisfied by using the current
01645          pool (which could only occur if we tried to use the field's
01646          allocated space and failed), then use that space; otherwise
01647          allocate a new pool
01648       */
01649       if (needed > space) {
01650          size_t new_size = mgr->size * 2;
01651 
01652          while (new_size < needed)
01653             new_size *= 2;
01654          
01655 #if defined(__AST_DEBUG_MALLOC)
01656          if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func))
01657             return;
01658 #else
01659          if (add_string_pool(mgr, pool_head, new_size, NULL, 0, NULL))
01660             return;
01661 #endif
01662       }
01663 
01664       target = (*pool_head)->base + mgr->used;
01665       vsprintf(target, format, ap2);
01666    }
01667 
01668    if (*ptr != target) {
01669       mgr->last_alloc = *ptr = target;
01670       mgr->used += needed;
01671    }
01672 }

int __ast_string_field_ptr_grow ( struct ast_string_field_mgr mgr,
size_t  needed,
const ast_string_field ptr 
)

Definition at line 1595 of file utils.c.

References ast_string_field_mgr::last_alloc, ast_string_field_mgr::size, and ast_string_field_mgr::used.

01597 {
01598    int grow = needed - (strlen(*ptr) + 1);
01599    size_t space = mgr->size - mgr->used;
01600 
01601    if (grow <= 0) {
01602       return 0;
01603    }
01604 
01605    if (*ptr != mgr->last_alloc) {
01606       return 1;
01607    }
01608 
01609    if (space < grow) {
01610       return 1;
01611    }
01612 
01613    mgr->used += grow;
01614 
01615    return 0;
01616 }


Variable Documentation

const char __ast_string_field_empty[]

the empty string

Definition at line 1474 of file utils.c.


Generated on Wed Aug 18 22:34:34 2010 for Asterisk - the Open Source PBX by  doxygen 1.4.7