diff options
author | Regis Merlino <regis.merlino@intel.com> | 2013-03-11 10:52:35 -0700 |
---|---|---|
committer | Regis Merlino <regis.merlino@intel.com> | 2013-03-11 10:52:35 -0700 |
commit | d929e2f2b70447e3589952d8c69688880b7b514d (patch) | |
tree | 935e700c96d309003009e236b58860461efc3918 /libdleyna/server/search.c | |
parent | 6b9249f2b95ee7e01546bce4ea6366c4e7aa25f7 (diff) | |
download | dleyna-server-d929e2f2b70447e3589952d8c69688880b7b514d.tar.gz |
[Architecture] Change directory structure to enable build from a master project
Signed-off-by: Regis Merlino <regis.merlino@intel.com>
Diffstat (limited to 'libdleyna/server/search.c')
-rw-r--r-- | libdleyna/server/search.c | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/libdleyna/server/search.c b/libdleyna/server/search.c new file mode 100644 index 0000000..264654e --- /dev/null +++ b/libdleyna/server/search.c @@ -0,0 +1,148 @@ +/* + * dLeyna + * + * Copyright (C) 2012-2013 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU Lesser General Public License, + * version 2.1, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + * + * Mark Ryan <mark.d.ryan@intel.com> + * + */ + +#include <string.h> + +#include "interface.h" +#include "path.h" +#include "props.h" +#include "search.h" + +gchar *dls_search_translate_search_string(GHashTable *filter_map, + const gchar *search_string) +{ + GRegex *reg; + gchar *retval = NULL; + GMatchInfo *match_info = NULL; + gchar *prop = NULL; + gchar *op = NULL; + gchar *value = NULL; + const gchar *translated_value; + dls_prop_map_t *prop_map; + GString *str; + gint start_pos; + gint end_pos; + gint old_end_pos = 0; + unsigned int skipped; + unsigned int search_string_len = strlen(search_string); + gchar *root_path; + gchar *id; + + reg = g_regex_new("(\\w+)\\s+(=|!=|<|<=|>|>|contains|doesNotContain|"\ + "derivedfrom|exists)\\s+"\ + "(\"[^\"]*\"|true|false)", + 0, 0, NULL); + str = g_string_new(""); + + g_regex_match(reg, search_string, 0, &match_info); + while (g_match_info_matches(match_info)) { + prop = g_match_info_fetch(match_info, 1); + if (!prop) + goto on_error; + + op = g_match_info_fetch(match_info, 2); + if (!op) + goto on_error; + + value = g_match_info_fetch(match_info, 3); + if (!value) + goto on_error; + + /* Handle special cases where we need to translate + value as well as property name */ + + if (!strcmp(prop, DLS_INTERFACE_PROP_TYPE)) { + /* Skip the quotes */ + + value[strlen(value) - 1] = 0; + translated_value = dls_props_media_spec_to_upnp_class( + value + 1); + if (!translated_value) + goto on_error; + g_free(value); + value = g_strdup_printf("\"%s\"", translated_value); + } else if (!strcmp(prop, DLS_INTERFACE_PROP_PARENT) || + !strcmp(prop, DLS_INTERFACE_PROP_PATH)) { + value[strlen(value) - 1] = 0; + if (!dls_path_get_path_and_id(value + 1, &root_path, + &id, NULL)) + goto on_error; + g_free(root_path); + g_free(value); + value = g_strdup_printf("\"%s\"", id); + g_free(id); + } + + prop_map = g_hash_table_lookup(filter_map, prop); + if (!prop_map) + goto on_error; + + if (!prop_map->searchable) + goto on_error; + + if (!g_match_info_fetch_pos(match_info, 0, &start_pos, + &end_pos)) + goto on_error; + + skipped = start_pos - old_end_pos; + if (skipped > 0) + g_string_append_len(str, &search_string[old_end_pos], + skipped); + g_string_append_printf(str, "%s %s %s", + prop_map->upnp_prop_name, op, value); + old_end_pos = end_pos; + + g_free(value); + g_free(prop); + g_free(op); + + value = NULL; + prop = NULL; + op = NULL; + + g_match_info_next(match_info, NULL); + } + + skipped = search_string_len - old_end_pos; + if (skipped > 0) + g_string_append_len(str, &search_string[old_end_pos], + skipped); + + retval = g_string_free(str, FALSE); + str = NULL; + +on_error: + + g_free(value); + g_free(prop); + g_free(op); + + if (match_info) + g_match_info_free(match_info); + + if (str) + g_string_free(str, TRUE); + + g_regex_unref(reg); + + return retval; +} |