[evolution-data-server] libedata-book: Improve national phone number matching
- From: Mathias Hasselmann <hasselmm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] libedata-book: Improve national phone number matching
- Date: Wed, 6 Mar 2013 11:10:54 +0000 (UTC)
commit c2c059e4e81410edfea4384d653fbf18838a0978
Author: Mathias Hasselmann <mathias openismus com>
Date: Fri Mar 1 12:49:44 2013 +0100
libedata-book: Improve national phone number matching
e_phone_number_compare() and e_phone_number_compare_strings()
had different opinion how well "1234" and "234" match within
NANP regions. First considered them a national significant
number match as it interpreted the leading "1" as country
calling code, the later didn't. The former interpretion fits
better our E.164 normalization we do in the SQLite backend,
therefore we adopted that approach.
This also introduces e_phone_number_compare_strings_for_region().
https://bugs.freedesktop.org/show_bug.cgi?id=59571
.../libebook-contacts/e-phone-number-private.cpp | 102 +++++++++++++-------
.../libebook-contacts/e-phone-number-private.h | 1 +
addressbook/libebook-contacts/e-phone-number.c | 26 +++++-
addressbook/libebook-contacts/e-phone-number.h | 5 +
4 files changed, 100 insertions(+), 34 deletions(-)
---
diff --git a/addressbook/libebook-contacts/e-phone-number-private.cpp
b/addressbook/libebook-contacts/e-phone-number-private.cpp
index 86c4e52..9c7abbb 100644
--- a/addressbook/libebook-contacts/e-phone-number-private.cpp
+++ b/addressbook/libebook-contacts/e-phone-number-private.cpp
@@ -133,30 +133,43 @@ _e_phone_number_cxx_get_default_region ()
return g_strdup (e_phone_number_make_region_code (NULL).c_str ());
}
-EPhoneNumber *
-_e_phone_number_cxx_from_string (const gchar *phone_number,
- const gchar *region_code,
- GError **error)
+static bool
+_e_phone_number_cxx_parse (const std::string &phone_number,
+ const std::string ®ion,
+ PhoneNumber *parsed_number,
+ GError **error)
{
- g_return_val_if_fail (NULL != phone_number, NULL);
-
- const std::string valid_region = e_phone_number_make_region_code (region_code);
- std::auto_ptr<EPhoneNumber> parsed_number(new EPhoneNumber);
-
const PhoneNumberUtil::ErrorType err =
#ifdef PHONENUMBER_RAW_INPUT_NEEDED
e_phone_number_util_get_instance ()->ParseAndKeepRawInput (
- phone_number, valid_region, &parsed_number->priv);
+ phone_number, region, parsed_number);
#else /* PHONENUMBER_RAW_INPUT_NEEDED */
e_phone_number_util_get_instance ()->Parse (
- phone_number, valid_region, &parsed_number->priv);
+ phone_number, region, parsed_number);
#endif /* PHONENUMBER_RAW_INPUT_NEEDED */
if (err != PhoneNumberUtil::NO_PARSING_ERROR) {
_e_phone_number_set_error (error, e_phone_number_error_code (err));
- return NULL;
+ return false;
}
+ return true;
+}
+
+EPhoneNumber *
+_e_phone_number_cxx_from_string (const gchar *phone_number,
+ const gchar *region_code,
+ GError **error)
+{
+ g_return_val_if_fail (NULL != phone_number, NULL);
+
+ const std::string valid_region = e_phone_number_make_region_code (region_code);
+ std::auto_ptr<EPhoneNumber> parsed_number(new EPhoneNumber);
+
+ if (!_e_phone_number_cxx_parse (
+ phone_number, valid_region, &parsed_number->priv, error))
+ return NULL;
+
return parsed_number.release ();
}
@@ -180,13 +193,13 @@ _e_phone_number_cxx_to_string (const EPhoneNumber *phone_number,
}
static EPhoneNumberCountrySource
-e_phone_number_get_country_source (const EPhoneNumber *phone_number)
+_e_phone_number_cxx_get_country_source (const PhoneNumber &phone_number)
{
g_return_val_if_fail (
- phone_number->priv.has_country_code_source (),
+ phone_number.has_country_code_source (),
E_PHONE_NUMBER_COUNTRY_FROM_DEFAULT);
- switch (phone_number->priv.country_code_source ()) {
+ switch (phone_number.country_code_source ()) {
case PhoneNumber::FROM_NUMBER_WITH_PLUS_SIGN:
return E_PHONE_NUMBER_COUNTRY_FROM_FQTN;
@@ -207,6 +220,12 @@ e_phone_number_get_country_source (const EPhoneNumber *phone_number)
return E_PHONE_NUMBER_COUNTRY_FROM_DEFAULT;
}
+static EPhoneNumberCountrySource
+_e_phone_number_cxx_get_country_source (const EPhoneNumber *phone_number)
+{
+ return _e_phone_number_cxx_get_country_source (phone_number->priv);
+}
+
gint
_e_phone_number_cxx_get_country_code (const EPhoneNumber *phone_number,
EPhoneNumberCountrySource *source)
@@ -215,7 +234,7 @@ _e_phone_number_cxx_get_country_code (const EPhoneNumber *phone_number,
if (phone_number->priv.has_country_code ()) {
if (source)
- *source = e_phone_number_get_country_source (phone_number);
+ *source = _e_phone_number_cxx_get_country_source (phone_number);
return phone_number->priv.country_code ();
}
@@ -257,6 +276,31 @@ e_phone_number_match (PhoneNumberUtil::MatchType match_type)
g_return_val_if_reached (E_PHONE_NUMBER_MATCH_NONE);
}
+static EPhoneNumberMatch
+_e_phone_number_cxx_compare (const PhoneNumber &first_number,
+ const PhoneNumber &second_number)
+{
+ PhoneNumberUtil::MatchType match_type =
+ e_phone_number_util_get_instance ()->IsNumberMatch (
+ first_number, second_number);
+
+ /* Downgrade exact matches to national number matches
+ * if one of the numbers had a guessed country code. */
+ if (match_type == PhoneNumberUtil::EXACT_MATCH) {
+ const EPhoneNumberCountrySource cs1 =
+ _e_phone_number_cxx_get_country_source (first_number);
+ const EPhoneNumberCountrySource cs2 =
+ _e_phone_number_cxx_get_country_source (second_number);
+
+ if (cs1 == E_PHONE_NUMBER_COUNTRY_FROM_DEFAULT
+ || cs2 == E_PHONE_NUMBER_COUNTRY_FROM_DEFAULT)
+ match_type = PhoneNumberUtil::NSN_MATCH;
+ }
+
+ g_warn_if_fail (match_type != PhoneNumberUtil::INVALID_NUMBER);
+ return e_phone_number_match (match_type);
+}
+
EPhoneNumberMatch
_e_phone_number_cxx_compare (const EPhoneNumber *first_number,
const EPhoneNumber *second_number)
@@ -264,35 +308,27 @@ _e_phone_number_cxx_compare (const EPhoneNumber *first_number,
g_return_val_if_fail (NULL != first_number, E_PHONE_NUMBER_MATCH_NONE);
g_return_val_if_fail (NULL != second_number, E_PHONE_NUMBER_MATCH_NONE);
- const PhoneNumberUtil::MatchType match_type =
- e_phone_number_util_get_instance ()->
- IsNumberMatch (first_number->priv, second_number->priv);
-
- g_warn_if_fail (match_type != PhoneNumberUtil::INVALID_NUMBER);
- return e_phone_number_match (match_type);
+ return _e_phone_number_cxx_compare (first_number->priv, second_number->priv);
}
EPhoneNumberMatch
_e_phone_number_cxx_compare_strings (const gchar *first_number,
const gchar *second_number,
+ const gchar *region_code,
GError **error)
{
- EPhoneNumberMatch result = E_PHONE_NUMBER_MATCH_NONE;
-
g_return_val_if_fail (NULL != first_number, E_PHONE_NUMBER_MATCH_NONE);
g_return_val_if_fail (NULL != second_number, E_PHONE_NUMBER_MATCH_NONE);
- const PhoneNumberUtil::MatchType match_type =
- e_phone_number_util_get_instance ()->
- IsNumberMatchWithTwoStrings (first_number, second_number);
+ const std::string region = e_phone_number_make_region_code (region_code);
+ PhoneNumber pn1, pn2;
- if (match_type == PhoneNumberUtil::INVALID_NUMBER) {
- _e_phone_number_set_error (error, E_PHONE_NUMBER_ERROR_NOT_A_NUMBER);
- } else {
- result = e_phone_number_match (match_type);
- }
+ if (!_e_phone_number_cxx_parse (first_number, region, &pn1, error))
+ return E_PHONE_NUMBER_MATCH_NONE;
+ if (!_e_phone_number_cxx_parse (second_number, region, &pn2, error))
+ return E_PHONE_NUMBER_MATCH_NONE;
- return result;
+ return _e_phone_number_cxx_compare (pn1, pn2);
}
EPhoneNumber *
diff --git a/addressbook/libebook-contacts/e-phone-number-private.h
b/addressbook/libebook-contacts/e-phone-number-private.h
index ec9c6fe..0f80491 100644
--- a/addressbook/libebook-contacts/e-phone-number-private.h
+++ b/addressbook/libebook-contacts/e-phone-number-private.h
@@ -74,6 +74,7 @@ E_PHONE_NUMBER_LOCAL EPhoneNumberMatch _e_phone_number_cxx_compare
(const EPhon
const EPhoneNumber
*second_number);
E_PHONE_NUMBER_LOCAL EPhoneNumberMatch _e_phone_number_cxx_compare_strings (const gchar *first_number,
const gchar *second_number,
+ const gchar *region_code,
GError **error);
E_PHONE_NUMBER_LOCAL EPhoneNumber * _e_phone_number_cxx_copy (const EPhoneNumber
*phone_number);
E_PHONE_NUMBER_LOCAL void _e_phone_number_cxx_free (EPhoneNumber *phone_number);
diff --git a/addressbook/libebook-contacts/e-phone-number.c b/addressbook/libebook-contacts/e-phone-number.c
index face50a..6194f69 100644
--- a/addressbook/libebook-contacts/e-phone-number.c
+++ b/addressbook/libebook-contacts/e-phone-number.c
@@ -324,9 +324,33 @@ e_phone_number_compare_strings (const gchar *first_number,
const gchar *second_number,
GError **error)
{
+ return e_phone_number_compare_strings_with_region (
+ first_number, second_number, NULL, error);
+}
+
+/**
+ * e_phone_number_compare_strings_with_region:
+ * @first_number: the first EPhoneNumber to compare
+ * @second_number: the second EPhoneNumber to compare
+ * @region_code: (allow-none): a two-letter country code, or %NULL
+ * @error: (out): a #GError to set an error, if any
+ *
+ * Compares two phone numbers within the context of @region_code.
+ *
+ * Returns: The quality of matching for the two phone numbers.
+ *
+ * Since: 3.8
+ **/
+EPhoneNumberMatch
+e_phone_number_compare_strings_with_region (const gchar *first_number,
+ const gchar *second_number,
+ const gchar *region_code,
+ GError **error)
+{
#ifdef ENABLE_PHONENUMBER
- return _e_phone_number_cxx_compare_strings (first_number, second_number, error);
+ return _e_phone_number_cxx_compare_strings (
+ first_number, second_number, region_code, error);
#else /* ENABLE_PHONENUMBER */
diff --git a/addressbook/libebook-contacts/e-phone-number.h b/addressbook/libebook-contacts/e-phone-number.h
index 023ca20..17d2d1b 100644
--- a/addressbook/libebook-contacts/e-phone-number.h
+++ b/addressbook/libebook-contacts/e-phone-number.h
@@ -228,6 +228,11 @@ EPhoneNumberMatch e_phone_number_compare (const EPhoneNumber *first_number,
EPhoneNumberMatch e_phone_number_compare_strings (const gchar *first_number,
const gchar *second_number,
GError **error);
+EPhoneNumberMatch e_phone_number_compare_strings_with_region
+ (const gchar *first_number,
+ const gchar *second_number,
+ const gchar *region_code,
+ GError **error);
EPhoneNumber * e_phone_number_copy (const EPhoneNumber *phone_number);
void e_phone_number_free (EPhoneNumber *phone_number);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]