return g_string_free (string, FALSE);
}
+static void
+update_e164_attribute_params (EVCard *vcard)
+{
+ GList *attr_list;
+
+ for (attr_list = e_vcard_get_attributes (vcard); attr_list; attr_list = attr_list->next) {
+ EVCardAttribute *const attr = attr_list->data;
+ EVCardAttributeParam *param = NULL;
+ gchar *e164 = NULL, *cc, *nn;
+ GList *param_list, *values;
+
+ /* We only attach E164 parameters to TEL attributes. */
+ if (strcmp (e_vcard_attribute_get_name (attr), EVC_TEL) != 0)
+ continue;
+
+ /* Compute E164 number. */
+ values = e_vcard_attribute_get_values (attr);
+ e164 = values && values->data ? convert_phone (values->data, NULL) : NULL;
+
+ if (e164 == NULL) {
+ e_vcard_attribute_remove_param (attr, EVC_X_E164);
+ continue;
+ }
+
+ /* Find already exisiting parameter, so that we can reuse it. */
+ for (param_list = e_vcard_attribute_get_params (attr); param_list; param_list = param_list->next) {
+ if (strcmp (e_vcard_attribute_param_get_name (param_list->data), EVC_X_E164) == 0) {
+ param = param_list->data;
+ break;
+ }
+ }
+
+ /* Create a new parameter instance if needed. Otherwise clean
+ * the existing parameter's values: This is much cheaper than
+ * checking for modifications. */
+ if (param == NULL) {
+ param = e_vcard_attribute_param_new (EVC_X_E164);
+ e_vcard_attribute_add_param (attr, param);
+ } else {
+ e_vcard_attribute_param_remove_values (param);
+ }
+
+ /* Split the phone number into country calling code and
+ * national number code. */
+ nn = strchr (e164, '|');
+
+ if (nn == NULL) {
+ g_warn_if_reached ();
+ continue;
+ }
+
+ *nn++ = '\0';
+ cc = e164;
+
+ /* Assign the parameter values. It seems odd that we revert
+ * the order of NN and CC, but at least EVCard's parser doesn't
+ * permit an empty first param value. Which of course could be
+ * fixed - in order to create a nice potential IOP problem with
+ ** other vCard parsers. */
+ e_vcard_attribute_param_add_values (param, nn, cc, NULL);
+
+ g_free (e164);
+ }
+}
+
static gboolean
insert_contact (EBookBackendSqliteDB *ebsdb,
EContact *contact,
priv = ebsdb->priv;
+ /* Update E.164 parameters in vcard if needed */
+ if (priv->store_vcard)
+ update_e164_attribute_params (E_VCARD (contact));
+
/* Update main summary table */
stmt = insert_stmt_from_contact (ebsdb, contact, folderid, priv->store_vcard, replace_existing);
success = book_backend_sql_exec (priv->db, stmt, NULL, NULL, error);
--- /dev/null
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2013 Intel Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU Lesser General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * 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 Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * Authors: Tristan Van Berkom <tristanvb@openismus.com>
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <libebook/libebook.h>
+
+#include "client-test-utils.h"
+#include "e-test-server-utils.h"
+
+#ifdef ENABLE_PHONENUMBER
+
+typedef struct {
+ ETestServerClosure parent;
+
+ gchar *vcard_name;
+ gchar *formatted_number;
+ gchar *country_calling_code;
+ gchar *national_number;
+} TestData;
+
+static void
+test_data_free (gpointer user_data)
+{
+ TestData *const data = user_data;
+
+ g_free (data->vcard_name);
+ g_free (data->formatted_number);
+ g_free (data->country_calling_code);
+ g_free (data->national_number);
+ g_free (data);
+}
+
+static TestData *
+test_data_new (const gchar *vcard_name,
+ const gchar *formatted_number,
+ const gchar *country_calling_code,
+ const gchar *national_number)
+{
+ TestData *const data = g_new0 (TestData, 1);
+
+ data->parent.type = E_TEST_SERVER_ADDRESS_BOOK;
+ data->parent.destroy_closure_func = test_data_free;
+ data->vcard_name = g_strdup (vcard_name);
+ data->formatted_number = g_strdup (formatted_number);
+ data->country_calling_code = g_strdup (country_calling_code);
+ data->national_number = g_strdup (national_number);
+
+ g_print ("%d %p\n", data->parent.calendar_source_type, data->parent.destroy_closure_func);
+
+ return data;
+}
+
+static void
+test_add_e164_param (ETestServerFixture *fixture,
+ gconstpointer user_data)
+{
+ const TestData *const data = user_data;
+ EBookClient *book_client;
+ EContact *contact;
+ gchar *vcard;
+ gchar *uid;
+ EVCardAttribute *tel;
+ GList *values;
+ GError *error = NULL;
+
+ book_client = E_TEST_SERVER_UTILS_SERVICE (fixture, EBookClient);
+ g_print ("%p\n", book_client);
+
+ vcard = new_vcard_from_test_case (data->vcard_name);
+ contact = e_contact_new_from_vcard (vcard);
+ g_free (vcard);
+
+ tel = e_vcard_get_attribute (E_VCARD (contact), EVC_TEL);
+ values = tel ? e_vcard_attribute_get_values (tel) : NULL;
+
+ g_assert (values != NULL);
+ g_assert_cmpstr (values->data, ==, data->formatted_number);
+
+ values = e_vcard_attribute_get_param (tel, EVC_X_E164);
+ g_assert (values == NULL);
+
+ if (!e_book_client_add_contact_sync (book_client, contact, &uid, NULL, &error))
+ g_error ("Failed to add contact: %s", error->message);
+
+ g_object_unref (contact);
+
+ if (!e_book_client_get_contact_sync (book_client, uid, &contact, NULL, &error))
+ g_error ("Failed to restore contact: %s", error->message);
+
+ g_free (uid);
+
+
+ tel = e_vcard_get_attribute (E_VCARD (contact), EVC_TEL);
+ values = tel ? e_vcard_attribute_get_values (tel) : NULL;
+
+ g_assert (values != NULL);
+ g_assert_cmpstr (values->data, ==, data->formatted_number);
+
+ values = e_vcard_attribute_get_param (tel, EVC_X_E164);
+
+ g_assert (values != NULL);
+ g_assert_cmpstr (values->data, ==, data->national_number);
+
+ if (data->country_calling_code) {
+ g_assert (values->next != NULL);
+ g_assert_cmpstr (values->next->data, ==, data->country_calling_code);
+ } else {
+ g_assert (values->next == NULL);
+ }
+}
+
+#endif /* ENABLE_PHONENUMBER */
+
+gint
+main (gint argc,
+ gchar **argv)
+{
+#if !GLIB_CHECK_VERSION (2, 35, 1)
+ g_type_init ();
+#endif
+ g_test_init (&argc, &argv, NULL);
+
+#ifdef ENABLE_PHONENUMBER
+
+ g_test_add (
+ "/EBookClient/AddContact/AddE164Param/1", ETestServerFixture,
+ test_data_new ("custom-1", "+1-221-5423789", "+1", "2215423789"),
+ e_test_server_utils_setup, test_add_e164_param,
+ e_test_server_utils_teardown);
+ g_test_add (
+ "/EBookClient/AddContact/AddE164Param/2", ETestServerFixture,
+ test_data_new ("custom-2", "7654321", NULL, "7654321"),
+ e_test_server_utils_setup, test_add_e164_param,
+ e_test_server_utils_teardown);
+
+#endif /* ENABLE_PHONENUMBER */
+
+ return e_test_server_utils_run ();
+}