Asterisk - The Open Source Telephony Project GIT-master-3dee037
String Fields

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;
};
#define AST_DECLARE_STRING_FIELDS(field_list)
Declare the fields needed in a structure.
Definition: stringfields.h:341
#define AST_STRING_FIELD(name)
Declare a string field.
Definition: stringfields.h:303
static struct stasis_rest_handlers bar
Definition: test_ari.c:125

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
}
#define ast_free(a)
Definition: astmm.h:180
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define NULL
Definition: resample.c:96
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
Definition: stringfields.h:359
int error(const char *format,...)
Definition: utils/frame.c:999

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; 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);
#define ast_string_field_ptr_build_va(x, ptr, fmt, args)
Set a field to a complex (built) value with prebuilt va_lists.
Definition: stringfields.h:573
#define ast_string_field_build_va(x, field, fmt, args)
Set a field to a complex (built) value.
Definition: stringfields.h:591
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
Definition: stringfields.h:521
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:555
#define ast_string_field_ptr_build(x, ptr, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:537
#define ast_string_field_ptr_set(x, ptr, data)
Set a field to a simple string value.
Definition: stringfields.h:475
const char * args

When the structure instance is no longer needed, the fields and their storage pool must be freed:

#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
Definition: stringfields.h:374

A new feature "Extended String Fields" has been added in 13.9.0.

An extended field is one that is declared outside the AST_DECLARE_STRING_FIELDS block but still inside the parent structure. It's most useful for extending structures where adding a new string field to an existing AST_DECLARE_STRING_FIELDS block would break ABI compatibility.

Example:

struct original_structure_version {
);
int x1;
int x2;
};

Adding "blah" to the existing string fields breaks ABI compatibility because it changes the offsets of x1 and x2.

struct new_structure_version {
);
int x1;
int x2;
};

However, adding "blah" as an extended string field to the end of the structure doesn't break ABI compatibility but still allows the use of the existing pool.

struct new_structure_version {
);
int x1;
int x2;
};
#define AST_STRING_FIELD_EXTENDED(name)
Declare an extended string field.
Definition: stringfields.h:311

The only additional step required is to call ast_string_field_init_extended so the pool knows about the new field. It must be called AFTER ast_string_field_init or ast_calloc_with_stringfields. Although ast_calloc_with_stringfields is used in the sample below, it's not necessary for extended string fields.

struct new_structure_version *x = ast_calloc_with_stringfields(1, struct new_structure_version, 252);
if (!x) {
return;
}
#define ast_calloc_with_stringfields(n, type, size)
Allocate a structure with embedded stringfields in a single allocation.
Definition: stringfields.h:432
#define ast_string_field_init_extended(x, field)
Initialize an extended string field.
Definition: stringfields.h:401

The new field can now be treated just like any other string field and it's storage will be released with the rest of the string fields.

ast_string_field_set(x, foo, "infinite loop");
ast_stringfield_free_memory(x);

This completes the API description.