Merge "sorcery/res_pjsip: Refactor for realtime performance" into 13

This commit is contained in:
Joshua Colp
2016-03-29 13:16:17 -05:00
committed by Gerrit Code Review
22 changed files with 881 additions and 425 deletions

View File

@@ -723,6 +723,96 @@ const char *ast_variable_find(const struct ast_category *category, const char *v
return ast_variable_find_in_list(category->root, variable);
}
const struct ast_variable *ast_variable_find_variable_in_list(const struct ast_variable *list, const char *variable_name)
{
const struct ast_variable *v;
for (v = list; v; v = v->next) {
if (!strcasecmp(variable_name, v->name)) {
return v;
}
}
return NULL;
}
int ast_variables_match(const struct ast_variable *left, const struct ast_variable *right)
{
char *op;
if (left == right) {
return 1;
}
if (!(left && right)) {
return 0;
}
op = strrchr(right->name, ' ');
if (op) {
op++;
}
return ast_strings_match(left->value, op ? ast_strdupa(op) : NULL, right->value);
}
int ast_variable_lists_match(const struct ast_variable *left, const struct ast_variable *right, int exact_match)
{
const struct ast_variable *field;
int right_count = 0;
int left_count = 0;
if (left == right) {
return 1;
}
if (!(left && right)) {
return 0;
}
for (field = right; field; field = field->next) {
char *space = strrchr(field->name, ' ');
const struct ast_variable *old;
char * name = (char *)field->name;
if (space) {
name = ast_strdup(field->name);
if (!name) {
return 0;
}
name[space - field->name] = '\0';
}
old = ast_variable_find_variable_in_list(left, name);
if (name != field->name) {
ast_free(name);
}
if (exact_match) {
if (!old || strcmp(old->value, field->value)) {
return 0;
}
} else {
if (!ast_variables_match(old, field)) {
return 0;
}
}
right_count++;
}
if (exact_match) {
for (field = left; field; field = field->next) {
left_count++;
}
if (right_count != left_count) {
return 0;
}
}
return 1;
}
const char *ast_variable_find_in_list(const struct ast_variable *list, const char *variable)
{
const struct ast_variable *v;

View File

@@ -39,6 +39,7 @@
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include <regex.h>
#include "asterisk/strings.h"
#include "asterisk/pbx.h"
@@ -228,3 +229,129 @@ char *ast_generate_random_string(char *buf, size_t size)
return buf;
}
int ast_strings_match(const char *left, const char *op, const char *right)
{
char *internal_op = (char *)op;
char *internal_right = (char *)right;
float left_num;
float right_num;
int scan_numeric = 0;
if (!(left && right)) {
return 0;
}
if (ast_strlen_zero(op)) {
if (ast_strlen_zero(left) && ast_strlen_zero(right)) {
return 1;
}
if (strlen(right) >= 2 && right[0] == '/' && right[strlen(right) - 1] == '/') {
internal_op = "regex";
internal_right = ast_strdupa(right);
/* strip the leading and trailing '/' */
internal_right++;
internal_right[strlen(internal_right) - 1] = '\0';
goto regex;
} else {
internal_op = "=";
goto equals;
}
}
if (!strcasecmp(op, "like")) {
char *tok;
struct ast_str *buffer = ast_str_alloca(128);
if (!strchr(right, '%')) {
return !strcmp(left, right);
} else {
internal_op = "regex";
internal_right = ast_strdupa(right);
tok = strsep(&internal_right, "%");
ast_str_set(&buffer, 0, "^%s", tok);
while ((tok = strsep(&internal_right, "%"))) {
ast_str_append(&buffer, 0, ".*%s", tok);
}
ast_str_append(&buffer, 0, "%s", "$");
internal_right = ast_str_buffer(buffer);
/* fall through to regex */
}
}
regex:
if (!strcasecmp(internal_op, "regex")) {
regex_t expression;
int rc;
if (regcomp(&expression, internal_right, REG_EXTENDED | REG_NOSUB)) {
return 0;
}
rc = regexec(&expression, left, 0, NULL, 0);
regfree(&expression);
return !rc;
}
equals:
scan_numeric = (sscanf(left, "%f", &left_num) && sscanf(internal_right, "%f", &right_num));
if (internal_op[0] == '=') {
if (ast_strlen_zero(left) && ast_strlen_zero(internal_right)) {
return 1;
}
if (scan_numeric) {
return (left_num == right_num);
} else {
return (!strcmp(left, internal_right));
}
}
if (internal_op[0] == '!' && internal_op[1] == '=') {
if (scan_numeric) {
return (left_num != right_num);
} else {
return !!strcmp(left, internal_right);
}
}
if (internal_op[0] == '<') {
if (scan_numeric) {
if (internal_op[1] == '=') {
return (left_num <= right_num);
} else {
return (left_num < right_num);
}
} else {
if (internal_op[1] == '=') {
return strcmp(left, internal_right) <= 0;
} else {
return strcmp(left, internal_right) < 0;
}
}
}
if (internal_op[0] == '>') {
if (scan_numeric) {
if (internal_op[1] == '=') {
return (left_num >= right_num);
} else {
return (left_num > right_num);
}
} else {
if (internal_op[1] == '=') {
return strcmp(left, internal_right) >= 0;
} else {
return strcmp(left, internal_right) > 0;
}
}
}
return 0;
}