Thu Apr 28 2011 17:16:22

Asterisk developer's documentation


stringfields.h File Reference

String fields in structures. More...

#include "asterisk/inline_api.h"
Include dependency graph for stringfields.h:
This graph shows which files directly or indirectly include this file:

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:

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_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 227 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 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:
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 308 of file stringfields.h.

Referenced by __ast_channel_alloc_ap(), build_callid_pvt(), build_callid_registry(), build_contact(), build_profile(), build_rpid(), build_user(), create_addr_from_peer(), handle_request_subscribe(), handle_response(), init_acf_query(), mgcp_new(), parse_moved_contact(), parse_register_contact(), 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:
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 332 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__)

Initialize a field pool and fields.

Parameters:
xPointer to a structure containing fields
sizeAmount 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(), acf_retrieve_docs(), append_mailbox_mapping(), ast_register_application2(), build_extension(), build_peer(), build_profile(), build_route(), build_user(), init_acf_query(), init_outgoing(), init_pvt(), jack_data_alloc(), load_module(), new_iax(), pbx_builtin_raise_exception(), realtime_multi_odbc(), realtime_odbc(), register_group(), register_group_feature(), sip_alloc(), sip_register(), sip_subscribe_mwi(), sla_build_station(), sla_build_trunk(), tds_load_module(), temp_peer(), temp_pvt_init(), transmit_response_using_temp(), and update_odbc().

#define ast_string_field_ptr_build (   x,
  ptr,
  fmt,
  args... 
)    __ast_string_field_ptr_build(&(x)->__field_mgr, &(x)->__field_mgr_pool, (ast_string_field *) ptr, fmt, args)

Set a field to a complex (built) value.

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 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:
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 320 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 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:
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 285 of file stringfields.h.

Referenced by __ast_channel_alloc_ap(), __find_callno(), __oh323_new(), __sip_subscribe_mwi_do(), acf_retrieve_docs(), agent_new(), alsa_new(), append_mailbox_mapping(), apply_outgoing(), ast_call_forward(), ast_cdr_setaccount(), ast_change_name(), ast_do_masquerade(), ast_iax2_new(), ast_register_application2(), 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(), custom_prepare(), dahdi_new(), dial_exec_full(), disa_exec(), do_forward(), extract_uri(), feature_request_and_dial(), 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(), handle_response_subscribe(), iax2_call(), iax2_request(), init_acf_query(), init_pvt(), 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(), read_config(), reg_source_db(), register_group(), register_group_feature(), register_verify(), registry_authrequest(), replace_cid(), reply_digest(), reqprep(), respprep(), ring_entry(), save_osptoken(), set_moh_exec(), set_peer_defaults(), set_pvt_defaults(), sip_alloc(), sip_call(), sip_new(), sip_park(), sip_poke_peer(), sip_register(), sip_request_call(), sip_set_redirstr(), sip_subscribe_mwi(), 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 1570 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.

{
   char *result = NULL;
   size_t space = mgr->size - mgr->used;

   if (__builtin_expect(needed > space, 0)) {
      size_t new_size = mgr->size * 2;

      while (new_size < needed)
         new_size *= 2;

#if defined(__AST_DEBUG_MALLOC)
      if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func))
         return NULL;
#else
      if (add_string_pool(mgr, pool_head, new_size, __FILE__, __LINE__, __FUNCTION__))
         return NULL;
#endif
   }

   result = (*pool_head)->base + mgr->used;
   mgr->used += needed;
   mgr->last_alloc = result;
   return result;
}
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 1516 of file utils.c.

References __ast_string_field_empty, 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.

{
   const char **p = (const char **) pool_head + 1;
   struct ast_string_field_pool *cur = NULL;
   struct ast_string_field_pool *preserve = NULL;

   /* clear fields - this is always necessary */
   while ((struct ast_string_field_mgr *) p != mgr)
      *p++ = __ast_string_field_empty;
   mgr->last_alloc = NULL;
#if defined(__AST_DEBUG_MALLOC)
   mgr->owner_file = file;
   mgr->owner_func = func;
   mgr->owner_line = lineno;
#endif
   if (needed > 0) {    /* allocate the initial pool */
      *pool_head = NULL;
      return add_string_pool(mgr, pool_head, needed, file, lineno, func);
   }
   if (needed < 0) {    /* reset all pools */
      if (*pool_head == NULL) {
         ast_log(LOG_WARNING, "trying to reset empty pool\n");
         return -1;
      }
      cur = *pool_head;
   } else {       /* preserve the last pool */
      if (*pool_head == NULL) {
         ast_log(LOG_WARNING, "trying to reset empty pool\n");
         return -1;
      }
      mgr->used = 0;
      preserve = *pool_head;
      cur = preserve->prev;
   }

   if (preserve) {
      preserve->prev = NULL;
   }

   while (cur) {
      struct ast_string_field_pool *prev = cur->prev;

      if (cur != preserve) {
         ast_free(cur);
      }
      cur = prev;
   }

   *pool_head = preserve;

   return 0;
}
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 1676 of file utils.c.

References __ast_string_field_ptr_build_va().

{
   va_list ap1, ap2;

   va_start(ap1, format);
   va_start(ap2, format);     /* va_copy does not exist on FreeBSD */

   __ast_string_field_ptr_build_va(mgr, pool_head, ptr, format, ap1, ap2);

   va_end(ap1);
   va_end(ap2);
}
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 1620 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().

{
   size_t needed;
   size_t available;
   size_t space = mgr->size - mgr->used;
   char *target;

   /* if the field already has space allocated, try to reuse it;
      otherwise, use the empty space at the end of the current
      pool
   */
   if ((*ptr)[0] != '\0') {
      target = (char *) *ptr;
      available = strlen(target) + 1;
   } else {
      target = (*pool_head)->base + mgr->used;
      available = space;
   }

   needed = vsnprintf(target, available, format, ap1) + 1;

   va_end(ap1);

   if (needed > available) {
      /* if the space needed can be satisfied by using the current
         pool (which could only occur if we tried to use the field's
         allocated space and failed), then use that space; otherwise
         allocate a new pool
      */
      if (needed > space) {
         size_t new_size = mgr->size * 2;

         while (new_size < needed)
            new_size *= 2;
         
#if defined(__AST_DEBUG_MALLOC)
         if (add_string_pool(mgr, pool_head, new_size, mgr->owner_file, mgr->owner_line, mgr->owner_func))
            return;
#else
         if (add_string_pool(mgr, pool_head, new_size, NULL, 0, NULL))
            return;
#endif
      }

      target = (*pool_head)->base + mgr->used;
      vsprintf(target, format, ap2);
   }

   if (*ptr != target) {
      mgr->last_alloc = *ptr = target;
      mgr->used += needed;
   }
}
int __ast_string_field_ptr_grow ( struct ast_string_field_mgr mgr,
size_t  needed,
const ast_string_field ptr 
)

Definition at line 1597 of file utils.c.

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

{
   int grow = needed - (strlen(*ptr) + 1);
   size_t space = mgr->size - mgr->used;

   if (grow <= 0) {
      return 0;
   }

   if (*ptr != mgr->last_alloc) {
      return 1;
   }

   if (space < grow) {
      return 1;
   }

   mgr->used += grow;

   return 0;
}

Variable Documentation

the empty string

Definition at line 1476 of file utils.c.

Referenced by __ast_string_field_init().