diff options
author | Mark Michelson <mmichelson@digium.com> | 2014-03-07 21:23:39 +0000 |
---|---|---|
committer | Mark Michelson <mmichelson@digium.com> | 2014-03-07 21:23:39 +0000 |
commit | c162101d6937babbccc6ec49f8d6ff85d51af9f9 (patch) | |
tree | 741dc5dda8a8c39af456c905d8c2679fab316310 /main/sorcery.c | |
parent | feae552139d2617117d1c5c5a80d36b60e6e86fc (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.c | 167 |
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; +} |