summaryrefslogtreecommitdiff
path: root/main/sorcery.c
diff options
context:
space:
mode:
authorMark Michelson <mmichelson@digium.com>2014-03-07 21:23:39 +0000
committerMark Michelson <mmichelson@digium.com>2014-03-07 21:23:39 +0000
commitc162101d6937babbccc6ec49f8d6ff85d51af9f9 (patch)
tree741dc5dda8a8c39af456c905d8c2679fab316310 /main/sorcery.c
parentfeae552139d2617117d1c5c5a80d36b60e6e86fc (diff)
Make res_sorcery_realtime filter unknown retrieved results.
When retrieving data from a database or other realtime backend, it's quite possible to retrieve variables that Asterisk does not care about but that are legitimate to exist. Asterisk does not need to throw a hissy fit when these variables are encountered but rather just filter them out. Review: https://reviewboard.asterisk.org/r/3305 ........ Merged revisions 410187 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@410207 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/sorcery.c')
-rw-r--r--main/sorcery.c167
1 files changed, 121 insertions, 46 deletions
diff --git a/main/sorcery.c b/main/sorcery.c
index 1d0aec757..2bb925e2f 100644
--- a/main/sorcery.c
+++ b/main/sorcery.c
@@ -58,6 +58,9 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
/*! \brief Number of buckets for instances (should be prime for performance reasons) */
#define INSTANCE_BUCKETS 17
+/*! \brief Number of buckets for object fields (should be prime for performance reasons) */
+#define OBJECT_FIELD_BUCKETS 29
+
/*! \brief Thread pool for observers */
static struct ast_threadpool *threadpool;
@@ -258,22 +261,22 @@ static sorcery_field_handler sorcery_field_default_handler(enum aco_option_type
/*! \brief Hashing function for sorcery wizards */
static int sorcery_wizard_hash(const void *obj, const int flags)
{
- const struct ast_sorcery_wizard *object;
- const char *key;
+ const struct ast_sorcery_wizard *object;
+ const char *key;
- switch (flags & OBJ_SEARCH_MASK) {
- case OBJ_SEARCH_KEY:
- key = obj;
- break;
- case OBJ_SEARCH_OBJECT:
- object = obj;
- key = object->name;
- break;
- default:
- ast_assert(0);
- return 0;
- }
- return ast_str_hash(key);
+ switch (flags & OBJ_SEARCH_MASK) {
+ case OBJ_SEARCH_KEY:
+ key = obj;
+ break;
+ case OBJ_SEARCH_OBJECT:
+ object = obj;
+ key = object->name;
+ break;
+ default:
+ ast_assert(0);
+ return 0;
+ }
+ return ast_str_hash(key);
}
/*! \brief Comparator function for sorcery wizards */
@@ -304,6 +307,54 @@ static int sorcery_wizard_cmp(void *obj, void *arg, int flags)
return CMP_MATCH;
}
+/*! \brief Hashing function for sorcery wizards */
+static int object_type_field_hash(const void *obj, const int flags)
+{
+ const struct ast_sorcery_object_field *object_field;
+ const char *key;
+
+ switch (flags & OBJ_SEARCH_MASK) {
+ case OBJ_SEARCH_KEY:
+ key = obj;
+ break;
+ case OBJ_SEARCH_OBJECT:
+ object_field = obj;
+ key = object_field->name;
+ break;
+ default:
+ ast_assert(0);
+ return 0;
+ }
+ return ast_str_hash(key);
+}
+
+static int object_type_field_cmp(void *obj, void *arg, int flags)
+{
+ const struct ast_sorcery_object_field *field_left = obj;
+ const struct ast_sorcery_object_field *field_right = arg;
+ const char *right_key = arg;
+ int cmp;
+
+ switch (flags & OBJ_SEARCH_MASK) {
+ case OBJ_SEARCH_OBJECT:
+ right_key = field_right->name;
+ /* Fall through */
+ case OBJ_SEARCH_KEY:
+ cmp = strcmp(field_left->name, right_key);
+ break;
+ case OBJ_SEARCH_PARTIAL_KEY:
+ cmp = strncmp(field_left->name, right_key, strlen(right_key));
+ break;
+ default:
+ cmp = 0;
+ break;
+ }
+ if (cmp) {
+ return 0;
+ }
+ return CMP_MATCH;
+}
+
/*! \brief Cleanup function */
static void sorcery_exit(void)
{
@@ -351,22 +402,22 @@ static int sorcery_instance_cmp(void *obj, void *arg, int flags)
/*! \brief Hashing function for sorcery instances */
static int sorcery_instance_hash(const void *obj, const int flags)
{
- const struct ast_sorcery *object;
- const char *key;
+ const struct ast_sorcery *object;
+ const char *key;
- switch (flags & OBJ_SEARCH_MASK) {
- case OBJ_SEARCH_KEY:
- key = obj;
- break;
- case OBJ_SEARCH_OBJECT:
- object = obj;
- key = object->module_name;
- break;
- default:
- ast_assert(0);
- return 0;
- }
- return ast_str_hash(key);
+ switch (flags & OBJ_SEARCH_MASK) {
+ case OBJ_SEARCH_KEY:
+ key = obj;
+ break;
+ case OBJ_SEARCH_OBJECT:
+ object = obj;
+ key = object->module_name;
+ break;
+ default:
+ ast_assert(0);
+ return 0;
+ }
+ return ast_str_hash(key);
}
int ast_sorcery_init(void)
@@ -461,22 +512,22 @@ static void sorcery_destructor(void *obj)
/*! \brief Hashing function for sorcery types */
static int sorcery_type_hash(const void *obj, const int flags)
{
- const struct ast_sorcery_object_type *object;
- const char *key;
+ const struct ast_sorcery_object_type *object;
+ const char *key;
- switch (flags & OBJ_SEARCH_MASK) {
- case OBJ_SEARCH_KEY:
- key = obj;
- break;
- case OBJ_SEARCH_OBJECT:
- object = obj;
- key = object->name;
- break;
- default:
- ast_assert(0);
- return 0;
- }
- return ast_str_hash(key);
+ switch (flags & OBJ_SEARCH_MASK) {
+ case OBJ_SEARCH_KEY:
+ key = obj;
+ break;
+ case OBJ_SEARCH_OBJECT:
+ object = obj;
+ key = object->name;
+ break;
+ default:
+ ast_assert(0);
+ return 0;
+ }
+ return ast_str_hash(key);
}
/*! \brief Comparator function for sorcery types */
@@ -577,7 +628,8 @@ static struct ast_sorcery_object_type *sorcery_object_type_alloc(const char *typ
return NULL;
}
- if (!(object_type->fields = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_NOLOCK, 1, NULL, NULL))) {
+ if (!(object_type->fields = ao2_container_alloc_options(AO2_ALLOC_OPT_LOCK_NOLOCK, OBJECT_FIELD_BUCKETS,
+ object_type_field_hash, object_type_field_cmp))) {
ao2_ref(object_type, -1);
return NULL;
}
@@ -1787,3 +1839,26 @@ int ast_sorcery_object_id_compare(const void *obj_left, const void *obj_right, i
}
return strcmp(ast_sorcery_object_get_id(obj_left), ast_sorcery_object_get_id(obj_right));
}
+
+struct ast_sorcery_object_type *ast_sorcery_get_object_type(const struct ast_sorcery *sorcery,
+ const char *type)
+{
+ return ao2_find(sorcery->types, type, OBJ_SEARCH_KEY);
+}
+
+int ast_sorcery_is_object_field_registered(const struct ast_sorcery_object_type *object_type,
+ const char *field_name)
+{
+ struct ast_sorcery_object_field *object_field;
+ int res = 1;
+
+ ast_assert(object_type != NULL);
+
+ object_field = ao2_find(object_type->fields, field_name, OBJ_SEARCH_KEY);
+ if (!object_field) {
+ res = 0;
+ }
+
+ ao2_cleanup(object_field);
+ return res;
+}