#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(), realtime_multi_odbc(), realtime_odbc(), sip_alloc(), sip_registry_destroy(), temp_pvt_cleanup(), update_odbc(), 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(), realtime_multi_odbc(), realtime_odbc(), sip_alloc(), sip_register(), sla_build_station(), sla_build_trunk(), transmit_response_using_temp(), and update_odbc().
#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_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(), custom_prepare(), dahdi_new(), disa_exec(), extract_uri(), feature_request_and_dial(), features_call(), findmeexec(), 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 1235 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.
01237 { 01238 char *result = NULL; 01239 01240 if (__builtin_expect(needed > mgr->space, 0)) { 01241 size_t new_size = mgr->size * 2; 01242 01243 while (new_size < needed) 01244 new_size *= 2; 01245 01246 if (add_string_pool(mgr, new_size)) 01247 return NULL; 01248 } 01249 01250 result = mgr->pool->base + mgr->used; 01251 mgr->used += needed; 01252 mgr->space -= needed; 01253 return result; 01254 }
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 1310 of file utils.c.
References __ast_string_field_index_build_va().
01313 { 01314 va_list ap1, ap2; 01315 01316 va_start(ap1, format); 01317 va_start(ap2, format); /* va_copy does not exist on FreeBSD */ 01318 01319 __ast_string_field_index_build_va(mgr, fields, num_fields, index, format, ap1, ap2); 01320 01321 va_end(ap1); 01322 va_end(ap2); 01323 }
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 1256 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().
01259 { 01260 size_t needed; 01261 size_t available; 01262 char *target; 01263 01264 /* if the field already has space allocated, try to reuse it; 01265 otherwise, use the empty space at the end of the current 01266 pool 01267 */ 01268 if (fields[index][0] != '\0') { 01269 target = (char *) fields[index]; 01270 available = strlen(fields[index]) + 1; 01271 } else { 01272 target = mgr->pool->base + mgr->used; 01273 available = mgr->space; 01274 } 01275 01276 needed = vsnprintf(target, available, format, ap1) + 1; 01277 01278 va_end(ap1); 01279 01280 if (needed > available) { 01281 /* if the space needed can be satisfied by using the current 01282 pool (which could only occur if we tried to use the field's 01283 allocated space and failed), then use that space; otherwise 01284 allocate a new pool 01285 */ 01286 if (needed <= mgr->space) { 01287 target = mgr->pool->base + mgr->used; 01288 } else { 01289 size_t new_size = mgr->size * 2; 01290 01291 while (new_size < needed) 01292 new_size *= 2; 01293 01294 if (add_string_pool(mgr, new_size)) 01295 return; 01296 01297 target = mgr->pool->base + mgr->used; 01298 } 01299 01300 vsprintf(target, format, ap2); 01301 } 01302 01303 if (fields[index] != target) { 01304 fields[index] = target; 01305 mgr->used += needed; 01306 mgr->space -= needed; 01307 } 01308 }
int __ast_string_field_init | ( | struct ast_string_field_mgr * | mgr, | |
size_t | size, | |||
ast_string_field * | fields, | |||
int | num_fields | |||
) |
Definition at line 1221 of file utils.c.
References add_string_pool().
01223 { 01224 int index; 01225 01226 if (add_string_pool(mgr, size)) 01227 return -1; 01228 01229 for (index = 0; index < num_fields; index++) 01230 fields[index] = __ast_string_field_empty; 01231 01232 return 0; 01233 }
const char __ast_string_field_empty[] |