From e4446f4aefd9e9ef3cd9cc76b205c93b9fd62a03 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 5 Apr 2010 17:23:43 -0300 Subject: [PATCH] obexd: Implement SearchValue and SearchAttribute handling for PullvCardListing Only vCards matching the SearchValue for the attribute as indicated in the SearchAttribute shall be contained in the listing object. Matching routine is implementation specific. This implementation checks if the field CONTAINS the search value ignoring case sensitive. --- obexd/plugins/pbap.c | 90 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 77 insertions(+), 13 deletions(-) diff --git a/obexd/plugins/pbap.c b/obexd/plugins/pbap.c index cbf579974..9794d2758 100644 --- a/obexd/plugins/pbap.c +++ b/obexd/plugins/pbap.c @@ -154,6 +154,8 @@ static const guint8 PBAP_TARGET[TARGET_SIZE] = { typedef int (*cache_sort_f) (struct cache_entry *entry, gpointer user_data); typedef void (*cache_element_f) (struct cache_entry *entry, gpointer user_data); +typedef int (*cache_entry_find_f) (const struct cache_entry *entry, + const gchar *value); static void cache_entry_free(struct cache_entry *entry) { @@ -180,6 +182,40 @@ static void cache_foreach(struct cache *cache, cache_sort_f sort, } #endif +static gboolean entry_name_find(const struct cache_entry *entry, + const gchar *value) +{ + gchar *name; + gboolean ret; + + if (!entry->name) + return FALSE; + + name = g_utf8_strdown(entry->name, -1); + ret = (g_strstr_len(name, -1, value) ? TRUE : FALSE); + g_free(name); + + return ret; +} + +static gboolean entry_sound_find(const struct cache_entry *entry, + const gchar *value) +{ + if (!entry->sound) + return FALSE; + + return (g_strstr_len(entry->sound, -1, value) ? TRUE : FALSE); +} + +static gboolean entry_tel_find(const struct cache_entry *entry, + const gchar *value) +{ + if (!entry->tel) + return FALSE; + + return (g_strstr_len(entry->tel, -1, value) ? TRUE : FALSE); +} + static const gchar *cache_find(struct cache *cache, guint32 handle) { GSList *l; @@ -261,6 +297,9 @@ static void cache_entry_notify(const gchar *id, const gchar *name, static void cache_ready_notify(gpointer user_data) { struct pbap_session *pbap = user_data; + cache_entry_find_f find; + gchar *searchval; + GSList *l; if (pbap->params->maxlistcount == 0) { /* Ignore all other parameter and return PhoneBookSize */ @@ -273,26 +312,51 @@ static void cache_ready_notify(gpointer user_data) memcpy(hdr->val, &size, sizeof(size)); pbap->buffer = g_string_new_len(aparam, sizeof(aparam)); - } else { - GSList *l; + goto done; + } - pbap->buffer = g_string_new(VCARD_LISTING_BEGIN); - l = g_slist_nth(pbap->cache.entries, - pbap->params->liststartoffset); + pbap->buffer = g_string_new(VCARD_LISTING_BEGIN); + l = g_slist_nth(pbap->cache.entries, + pbap->params->liststartoffset); - for (; l; l = l->next) { - struct cache_entry *entry = l->data; + /* + * FIXME: See PBAP spec section 5.3.4.1 + * Order{Alphabetical | Indexed | Phonetical} not yet implemented + * + * This implementation checks if the given field CONTAINS the + * search value(case insensitive). Name is the default field + * when the attribute is not provided. + */ + switch (pbap->params->searchattrib) { + case 1: + /* Number */ + find = entry_tel_find; + break; + /* Sound */ + case 2: + find = entry_sound_find; + break; + default: + find = entry_name_find; + break; + } - /* FIXME: check if the entry matches */ + searchval = g_utf8_strdown((gchar *) pbap->params->searchval, -1); + for (; l; l = l->next) { + const struct cache_entry *entry = l->data; - g_string_append_printf(pbap->buffer, - VCARD_LISTING_ELEMENT, - entry->handle, entry->name); - } + if (searchval && !find(entry, (const gchar *) searchval)) + continue; - pbap->buffer = g_string_append(pbap->buffer, VCARD_LISTING_END); + g_string_append_printf(pbap->buffer, + VCARD_LISTING_ELEMENT, + entry->handle, entry->name); } + g_free(searchval); + pbap->buffer = g_string_append(pbap->buffer, VCARD_LISTING_END); + +done: if (!pbap->cache.valid) { pbap->cache.valid = TRUE; obex_object_set_io_flags(pbap, G_IO_IN, 0); -- 2.47.3