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.

Patches against 13 and 15 have a compatibility layer needed to
maintain ABI that is not needed in master.

Change-Id: I56f4e20ba1154bd52281f995c27a429a854f6a79
This commit is contained in:
Sean Bright
2017-11-09 09:21:38 -05:00
parent b1743cb3c7
commit cf062303e3
7 changed files with 247 additions and 1 deletions

View File

@@ -543,6 +543,27 @@ static void sorcery_internal_wizard_destructor(void *obj)
}
int __ast_sorcery_wizard_register(const struct ast_sorcery_wizard *interface, struct ast_module *module)
{
struct ast_sorcery_wizard compat = {
.name = interface->name,
.open = interface->open,
.load = interface->load,
.reload = interface->reload,
.create = interface->create,
.retrieve_id = interface->retrieve_id,
.retrieve_regex = interface->retrieve_regex,
.retrieve_fields = interface->retrieve_fields,
.retrieve_multiple = interface->retrieve_multiple,
.update = interface->update,
.delete = interface->delete,
.close = interface->close,
.retrieve_prefix = NULL,
};
return __ast_sorcery_wizard_register_with_prefix(&compat, module);
}
int __ast_sorcery_wizard_register_with_prefix(const struct ast_sorcery_wizard *interface, struct ast_module *module)
{
struct ast_sorcery_internal_wizard *wizard;
int res = -1;
@@ -1982,6 +2003,36 @@ struct ao2_container *ast_sorcery_retrieve_by_regex(const struct ast_sorcery *so
return objects;
}
struct ao2_container *ast_sorcery_retrieve_by_prefix(const struct ast_sorcery *sorcery, const char *type, const char *prefix, const size_t prefix_len)
{
RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
struct ao2_container *objects;
int i;
if (!object_type || !(objects = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_NOLOCK, 1, NULL, NULL))) {
return NULL;
}
AST_VECTOR_RW_RDLOCK(&object_type->wizards);
for (i = 0; i < AST_VECTOR_SIZE(&object_type->wizards); i++) {
struct ast_sorcery_object_wizard *wizard =
AST_VECTOR_GET(&object_type->wizards, i);
if (!wizard->wizard->callbacks.retrieve_prefix) {
continue;
}
wizard->wizard->callbacks.retrieve_prefix(sorcery, wizard->data, object_type->name, objects, prefix, prefix_len);
if (wizard->caching && ao2_container_count(objects)) {
break;
}
}
AST_VECTOR_RW_UNLOCK(&object_type->wizards);
return objects;
}
/*! \brief Internal function which returns if the wizard has created the object */
static int sorcery_wizard_create(const struct ast_sorcery_object_wizard *object_wizard, const struct sorcery_details *details)
{