summaryrefslogtreecommitdiff
path: root/libdleyna/server/search.c
diff options
context:
space:
mode:
authorRegis Merlino <regis.merlino@intel.com>2013-03-11 10:52:35 -0700
committerRegis Merlino <regis.merlino@intel.com>2013-03-11 10:52:35 -0700
commitd929e2f2b70447e3589952d8c69688880b7b514d (patch)
tree935e700c96d309003009e236b58860461efc3918 /libdleyna/server/search.c
parent6b9249f2b95ee7e01546bce4ea6366c4e7aa25f7 (diff)
downloaddleyna-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.c148
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;
+}