#include <string.h>
#include <stdarg.h>
#include <stddef.h>
#include "asterisk/inline_api.h"
#include "asterisk/compiler.h"
#include "asterisk/compat.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_index_build(x, ast_string_field_index(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_index_build_va(x, ast_string_field_index(x, field), fmt, args1, args2) |
Set a field to a complex (built) value. | |
#define | ast_string_field_count(x) (offsetof(typeof(*(x)), __end_field) - offsetof(typeof(*(x)), __begin_field)) / sizeof(ast_string_field) |
Get the number of string fields in a structure. | |
#define | ast_string_field_free(x, field) ast_string_field_index_free(x, ast_string_field_index(x, field)) |
Free a field's value. | |
#define | ast_string_field_free_memory(x) |
Free the stringfield storage pools attached to a structure. | |
#define | ast_string_field_index(x, field) (offsetof(typeof(*x), field) - offsetof(typeof(*x), __begin_field)) / sizeof(ast_string_field) |
Get the index of a field in a structure. | |
#define | ast_string_field_index_build(x, index, fmt, args...) __ast_string_field_index_build(&(x)->__field_mgr, &(x)->__begin_field[0], ast_string_field_count(x), index, fmt, args) |
Set a field to a complex (built) value. | |
#define | ast_string_field_index_build_va(x, index, fmt, args1, args2) __ast_string_field_index_build_va(&(x)->__field_mgr, &(x)->__begin_field[0], ast_string_field_count(x), index, fmt, args1, args2) |
Set a field to a complex (built) value with prebuilt va_lists. | |
#define | ast_string_field_index_free(x, index) |
Free a field's value. | |
#define | ast_string_field_index_logset(x, index, data, logstr) |
#define | ast_string_field_index_set(x, index, data) |
Set a field to a simple string value. | |
#define | ast_string_field_init(x, size) __ast_string_field_init(&(x)->__field_mgr, size, &(x)->__begin_field[0], ast_string_field_count(x)) |
Initialize a field pool and fields. | |
#define | ast_string_field_logset(x, field, data, logstr) ast_string_field_index_logset(x, ast_string_field_index(x, field), data, logstr) |
#define | ast_string_field_reset_all(x) |
Free the stringfields in a structure. | |
#define | ast_string_field_set(x, field, data) ast_string_field_index_set(x, ast_string_field_index(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, size_t needed, ast_string_field *fields, int num_fields) |
void | __ast_string_field_index_build (struct ast_string_field_mgr *mgr, ast_string_field *fields, int num_fields, int index, const char *format,...) |
void | __ast_string_field_index_build_va (struct ast_string_field_mgr *mgr, ast_string_field *fields, int num_fields, int index, const char *format, va_list a1, va_list a2) |
int | __ast_string_field_init (struct ast_string_field_mgr *mgr, size_t size, ast_string_field *fields, int num_fields) |
Variables | |
const char | __ast_string_field_empty [] |
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(name); AST_STRING_FIELD(address); AST_STRING_FIELD(password); ); long x2; };
When an instance of this structure is allocated, the fields (and the pool of storage for them) must be initialized:
struct sample_fields *sample; sample = calloc(1, sizeof(*sample)); if (sample) { if (ast_string_field_init(sample, 256)) { free(sample); sample = NULL; } } if (!sample) { ... }
Fields will default to pointing to an empty string, and will revert to that when ast_string_field_free() is called. This means that a string field will never contain NULL.
Using the fields is much like using regular 'char *' fields in the structure, except that writing into them must be done using wrapper macros defined in this file.
Storing simple values into fields can be done using ast_string_field_set(); more complex values (using printf-style format strings) can be stored using ast_string_field_build().
When the structure instance is no longer needed, the fields and their storage pool must be freed:
ast_string_field_free_memory(sample); free(sample);
Definition in file stringfields.h.
#define AST_DECLARE_STRING_FIELDS | ( | field_list | ) |
Value:
ast_string_field __begin_field[0]; \ field_list \ ast_string_field __end_field[0]; \ struct ast_string_field_mgr __field_mgr
field_list | The list of fields to declare, using AST_STRING_FIELD() for each one |
Definition at line 196 of file stringfields.h.
#define AST_STRING_FIELD | ( | name | ) | const ast_string_field name |
Declare a string field.
name | The field name |
Definition at line 190 of file stringfields.h.
#define ast_string_field_build | ( | x, | |||
field, | |||||
fmt, | |||||
args... | ) | ast_string_field_index_build(x, ast_string_field_index(x, field), fmt, args) |
Set a field to a complex (built) value.
x | Pointer to a structure containing fields | |
field | Name of the field to set | |
fmt | printf-style format string | |
args | Arguments for format string |
Definition at line 316 of file stringfields.h.
Referenced by 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_sipredirect(), and update_name().
#define ast_string_field_build_va | ( | x, | |||
field, | |||||
fmt, | |||||
args1, | |||||
args2 | ) | ast_string_field_index_build_va(x, ast_string_field_index(x, field), fmt, args1, args2) |
Set a field to a complex (built) value.
x | Pointer to a structure containing fields | |
field | Name of the field to set | |
fmt | printf-style format string | |
argslist | a va_list of the args |
Definition at line 327 of file stringfields.h.
#define ast_string_field_count | ( | x | ) | (offsetof(typeof(*(x)), __end_field) - offsetof(typeof(*(x)), __begin_field)) / sizeof(ast_string_field) |
Get the number of string fields in a structure.
x | Pointer to a structure containing fields |
Definition at line 207 of file stringfields.h.
#define ast_string_field_free | ( | x, | |||
field | ) | ast_string_field_index_free(x, ast_string_field_index(x, field)) |
Free a field's value.
x | Pointer to a structure containing fields | |
field | Name of the field to free |
Definition at line 354 of file stringfields.h.
Referenced by check_user_full(), handle_request_invite(), handle_response_invite(), sip_request_call(), and transmit_register().
#define ast_string_field_free_memory | ( | x | ) |
Free the stringfield storage pools attached to a structure.
x | Pointer to a structure containing fields |
Definition at line 366 of file stringfields.h.
Referenced by ast_channel_free(), build_user(), destroy_mailbox_mapping(), destroy_station(), destroy_trunk(), peer_destructor(), pvt_destructor(), sip_alloc(), sip_registry_destroy(), temp_pvt_cleanup(), and user_destructor().
#define ast_string_field_index | ( | x, | |||
field | ) | (offsetof(typeof(*x), field) - offsetof(typeof(*x), __begin_field)) / sizeof(ast_string_field) |
Get the index of a field in a structure.
x | Pointer to a structure containing fields | |
field | Name of the field to locate |
Definition at line 217 of file stringfields.h.
Referenced by reply_digest().
#define ast_string_field_index_build | ( | x, | |||
index, | |||||
fmt, | |||||
args... | ) | __ast_string_field_index_build(&(x)->__field_mgr, &(x)->__begin_field[0], ast_string_field_count(x), index, fmt, args) |
Set a field to a complex (built) value.
x | Pointer to a structure containing fields | |
index | Index position of the field within the structure | |
fmt | printf-style format string | |
args | Arguments for format string |
Definition at line 293 of file stringfields.h.
#define ast_string_field_index_build_va | ( | x, | |||
index, | |||||
fmt, | |||||
args1, | |||||
args2 | ) | __ast_string_field_index_build_va(&(x)->__field_mgr, &(x)->__begin_field[0], ast_string_field_count(x), index, fmt, args1, args2) |
Set a field to a complex (built) value with prebuilt va_lists.
x | Pointer to a structure containing fields | |
index | Index position of the 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 |
Definition at line 305 of file stringfields.h.
#define ast_string_field_index_free | ( | x, | |||
index | ) |
Value:
do { \ (x)->__begin_field[index] = __ast_string_field_empty; \ } while(0)
x | Pointer to a structure containing fields | |
index | Index position of the field within the structure |
Definition at line 340 of file stringfields.h.
#define ast_string_field_index_logset | ( | x, | |||
index, | |||||
data, | |||||
logstr | ) |
Definition at line 254 of file stringfields.h.
#define ast_string_field_index_set | ( | x, | |||
index, | |||||
data | ) |
Set a field to a simple string value.
x | Pointer to a structure containing fields | |
index | Index position of the field within the structure | |
data | String value to be copied into the field |
Definition at line 236 of file stringfields.h.
Referenced by reply_digest().
#define ast_string_field_init | ( | x, | |||
size | ) | __ast_string_field_init(&(x)->__field_mgr, size, &(x)->__begin_field[0], ast_string_field_count(x)) |
Initialize a field pool and fields.
x | Pointer to a structure containing fields | |
size | Amount of storage to allocate |
Definition at line 226 of file stringfields.h.
Referenced by append_mailbox_mapping(), ast_channel_alloc(), build_peer(), build_user(), load_module(), new_iax(), sip_alloc(), sip_register(), sla_build_station(), sla_build_trunk(), and transmit_response_using_temp().
#define ast_string_field_logset | ( | x, | |||
field, | |||||
data, | |||||
logstr | ) | ast_string_field_index_logset(x, ast_string_field_index(x, field), data, logstr) |
Definition at line 282 of file stringfields.h.
#define ast_string_field_reset_all | ( | x | ) |
Free the stringfields in a structure.
x | Pointer to a structure containing fields |
Definition at line 383 of file stringfields.h.
Referenced by transmit_response_using_temp().
#define ast_string_field_set | ( | x, | |||
field, | |||||
data | ) | ast_string_field_index_set(x, ast_string_field_index(x, field), data) |
Set a field to a simple string value.
x | Pointer to a structure containing fields | |
field | Name of the field to set | |
data | String value to be copied into the field |
Definition at line 279 of file stringfields.h.
Referenced by __find_callno(), __oh323_new(), agent_new(), 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(), build_peer(), build_rpid(), build_user(), cache_get_callno_locked(), check_access(), check_user_full(), create_addr(), create_addr_from_peer(), dahdi_new(), disa_exec(), extract_uri(), features_call(), get_also_info(), get_destination(), get_rdnis(), gtalk_new(), handle_request(), handle_request_bye(), handle_request_invite(), handle_request_options(), handle_request_refer(), handle_response(), iax2_call(), iax2_request(), initreqprep(), language_write(), load_module(), local_call(), mgcp_new(), moh2_exec(), moh_write(), nbs_new(), new_iax(), oss_new(), parse_moved_contact(), parse_ok_contact(), parse_register_contact(), phone_new(), read_config(), register_verify(), registry_authrequest(), reply_digest(), sip_alloc(), sip_call(), sip_new(), sip_poke_peer(), sip_register(), sip_request_call(), skinny_new(), sla_build_station(), sla_build_trunk(), socket_process(), transmit_refer(), transmit_register(), transmit_response_using_temp(), vm_execmain(), and wait_for_answer().
typedef const char* ast_string_field |
Definition at line 100 of file stringfields.h.
ast_string_field __ast_string_field_alloc_space | ( | struct ast_string_field_mgr * | mgr, | |
size_t | needed, | |||
ast_string_field * | fields, | |||
int | num_fields | |||
) |
Definition at line 1233 of file utils.c.
References add_string_pool(), ast_string_field_pool::base, ast_string_field_mgr::pool, ast_string_field_mgr::size, ast_string_field_mgr::space, and ast_string_field_mgr::used.
01235 { 01236 char *result = NULL; 01237 01238 if (__builtin_expect(needed > mgr->space, 0)) { 01239 size_t new_size = mgr->size * 2; 01240 01241 while (new_size < needed) 01242 new_size *= 2; 01243 01244 if (add_string_pool(mgr, new_size)) 01245 return NULL; 01246 } 01247 01248 result = mgr->pool->base + mgr->used; 01249 mgr->used += needed; 01250 mgr->space -= needed; 01251 return result; 01252 }
void __ast_string_field_index_build | ( | struct ast_string_field_mgr * | mgr, | |
ast_string_field * | fields, | |||
int | num_fields, | |||
int | index, | |||
const char * | format, | |||
... | ||||
) |
Definition at line 1308 of file utils.c.
References __ast_string_field_index_build_va().
01311 { 01312 va_list ap1, ap2; 01313 01314 va_start(ap1, format); 01315 va_start(ap2, format); /* va_copy does not exist on FreeBSD */ 01316 01317 __ast_string_field_index_build_va(mgr, fields, num_fields, index, format, ap1, ap2); 01318 01319 va_end(ap1); 01320 va_end(ap2); 01321 }
void __ast_string_field_index_build_va | ( | struct ast_string_field_mgr * | mgr, | |
ast_string_field * | fields, | |||
int | num_fields, | |||
int | index, | |||
const char * | format, | |||
va_list | a1, | |||
va_list | a2 | |||
) |
Definition at line 1254 of file utils.c.
References add_string_pool(), available(), ast_string_field_pool::base, ast_string_field_mgr::pool, ast_string_field_mgr::size, ast_string_field_mgr::space, and ast_string_field_mgr::used.
Referenced by __ast_string_field_index_build().
01257 { 01258 size_t needed; 01259 size_t available; 01260 char *target; 01261 01262 /* if the field already has space allocated, try to reuse it; 01263 otherwise, use the empty space at the end of the current 01264 pool 01265 */ 01266 if (fields[index][0] != '\0') { 01267 target = (char *) fields[index]; 01268 available = strlen(fields[index]) + 1; 01269 } else { 01270 target = mgr->pool->base + mgr->used; 01271 available = mgr->space; 01272 } 01273 01274 needed = vsnprintf(target, available, format, ap1) + 1; 01275 01276 va_end(ap1); 01277 01278 if (needed > available) { 01279 /* if the space needed can be satisfied by using the current 01280 pool (which could only occur if we tried to use the field's 01281 allocated space and failed), then use that space; otherwise 01282 allocate a new pool 01283 */ 01284 if (needed <= mgr->space) { 01285 target = mgr->pool->base + mgr->used; 01286 } else { 01287 size_t new_size = mgr->size * 2; 01288 01289 while (new_size < needed) 01290 new_size *= 2; 01291 01292 if (add_string_pool(mgr, new_size)) 01293 return; 01294 01295 target = mgr->pool->base + mgr->used; 01296 } 01297 01298 vsprintf(target, format, ap2); 01299 } 01300 01301 if (fields[index] != target) { 01302 fields[index] = target; 01303 mgr->used += needed; 01304 mgr->space -= needed; 01305 } 01306 }
int __ast_string_field_init | ( | struct ast_string_field_mgr * | mgr, | |
size_t | size, | |||
ast_string_field * | fields, | |||
int | num_fields | |||
) |
Definition at line 1219 of file utils.c.
References add_string_pool().
01221 { 01222 int index; 01223 01224 if (add_string_pool(mgr, size)) 01225 return -1; 01226 01227 for (index = 0; index < num_fields; index++) 01228 fields[index] = __ast_string_field_empty; 01229 01230 return 0; 01231 }
const char __ast_string_field_empty[] |