/* * dLeyna * * Copyright (C) 2012-2017 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 * */ #include #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; gchar *translated_type_ex; 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_TYPE_EX)) { /* Skip the quotes */ value[strlen(value) - 1] = 0; translated_type_ex = dls_props_media_spec_ex_to_upnp_class( value + 1); if (!translated_type_ex) goto on_error; g_free(value); value = g_strdup_printf("\"%s\"", translated_type_ex); g_free(translated_type_ex); } 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; }