sorcery: Add ast_sorcery_retrieve_by_prefix()

Some consumers of the sorcery API use ast_sorcery_retrieve_by_regex
only so that they can anchor the potential match as a prefix and not
because they truly need regular expressions.

Rather than using regular expressions for simple prefix lookups, add
a new operation - ast_sorcery_retrieve_by_prefix - that does them.

Change-Id: I56f4e20ba1154bd52281f995c27a429a854f6a79
This commit is contained in:
Sean Bright
2017-11-09 09:21:38 -05:00
parent 9eacd55c71
commit ffccce76d9
7 changed files with 214 additions and 0 deletions

View File

@@ -46,6 +46,7 @@ static void *sorcery_memory_retrieve_fields(const struct ast_sorcery *sorcery, v
static void sorcery_memory_retrieve_multiple(const struct ast_sorcery *sorcery, void *data, const char *type, struct ao2_container *objects,
const struct ast_variable *fields);
static void sorcery_memory_retrieve_regex(const struct ast_sorcery *sorcery, void *data, const char *type, struct ao2_container *objects, const char *regex);
static void sorcery_memory_retrieve_prefix(const struct ast_sorcery *sorcery, void *data, const char *type, struct ao2_container *objects, const char *prefix, const size_t prefix_len);
static int sorcery_memory_update(const struct ast_sorcery *sorcery, void *data, void *object);
static int sorcery_memory_delete(const struct ast_sorcery *sorcery, void *data, void *object);
static void sorcery_memory_close(void *data);
@@ -58,6 +59,7 @@ static struct ast_sorcery_wizard memory_object_wizard = {
.retrieve_fields = sorcery_memory_retrieve_fields,
.retrieve_multiple = sorcery_memory_retrieve_multiple,
.retrieve_regex = sorcery_memory_retrieve_regex,
.retrieve_prefix = sorcery_memory_retrieve_prefix,
.update = sorcery_memory_update,
.delete = sorcery_memory_delete,
.close = sorcery_memory_close,
@@ -74,6 +76,12 @@ struct sorcery_memory_fields_cmp_params {
/*! \brief Regular expression for checking object id */
regex_t *regex;
/*! \brief Prefix for matching object id */
const char *prefix;
/*! \brief Prefix length in bytes for matching object id */
const size_t prefix_len;
/*! \brief Optional container to put object into */
struct ao2_container *container;
};
@@ -125,6 +133,11 @@ static int sorcery_memory_fields_cmp(void *obj, void *arg, int flags)
ao2_link(params->container, obj);
}
return 0;
} else if (params->prefix) {
if (!strncmp(params->prefix, ast_sorcery_object_get_id(obj), params->prefix_len)) {
ao2_link(params->container, obj);
}
return 0;
} else if (params->fields &&
(!(objset = ast_sorcery_objectset_create(params->sorcery, obj)) ||
(!ast_variable_lists_match(objset, params->fields, 0)))) {
@@ -198,6 +211,18 @@ static void sorcery_memory_retrieve_regex(const struct ast_sorcery *sorcery, voi
regfree(&expression);
}
static void sorcery_memory_retrieve_prefix(const struct ast_sorcery *sorcery, void *data, const char *type, struct ao2_container *objects, const char *prefix, const size_t prefix_len)
{
struct sorcery_memory_fields_cmp_params params = {
.sorcery = sorcery,
.container = objects,
.prefix = prefix,
.prefix_len = prefix_len,
};
ao2_callback(data, 0, sorcery_memory_fields_cmp, &params);
}
static int sorcery_memory_update(const struct ast_sorcery *sorcery, void *data, void *object)
{
RAII_VAR(void *, existing, NULL, ao2_cleanup);