diff options
author | Sean Bright <sean.bright@gmail.com> | 2017-11-09 09:21:38 -0500 |
---|---|---|
committer | Sean Bright <sean.bright@gmail.com> | 2017-11-13 16:52:22 -0500 |
commit | 2e01b779cc18c1f0f66c28db775e1e6b1d5065e4 (patch) | |
tree | a95ad356e5f4f1efdae07f65225ae5ca47857c4c /main/sorcery.c | |
parent | bcd3782051fa069252ba8a9cd9c6cc13d827e0bf (diff) |
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
Diffstat (limited to 'main/sorcery.c')
-rw-r--r-- | main/sorcery.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/main/sorcery.c b/main/sorcery.c index 5ff1d106c..4e8384409 100644 --- a/main/sorcery.c +++ b/main/sorcery.c @@ -552,6 +552,28 @@ 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, + .is_stale = interface->is_stale, + .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; @@ -2036,6 +2058,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) { |