libebook: Export the API for phone region guessing
authorMathias Hasselmann <mathias@openismus.com>
Fri, 1 Feb 2013 13:56:11 +0000 (14:56 +0100)
committerMathias Hasselmann <mathias@openismus.com>
Mon, 4 Feb 2013 17:09:07 +0000 (18:09 +0100)
This adds e_phone_number_get_country_code_for_region() and
e_phone_number_get_default_region() which give access to the
region guessing mechanisms. They are needed to efficently
build the sqlite backend's phone number indexes.

See: https://bugzilla.gnome.org/show_bug.cgi?id=689622

addressbook/libebook/e-phone-number-private.cpp
addressbook/libebook/e-phone-number-private.h
addressbook/libebook/e-phone-number.c
addressbook/libebook/e-phone-number.h
docs/reference/addressbook/libebook/libebook-sections.txt
tests/libebook/test-ebook-phone-number.c

index fd49583..99857df 100644 (file)
@@ -88,15 +88,9 @@ e_phone_number_error_code (PhoneNumberUtil::ErrorType error)
        g_return_val_if_reached (E_PHONE_NUMBER_ERROR_UNKNOWN);
 }
 
-EPhoneNumber *
-_e_phone_number_cxx_from_string (const gchar *phone_number,
-                                 const gchar *region_code,
-                                 GError **error)
+static std::string
+e_phone_number_make_region_code (const gchar *region_code)
 {
-       g_return_val_if_fail (NULL != phone_number, NULL);
-
-       std::string valid_region;
-
        /* Get country code from current locale's address facet if supported */
 #if HAVE__NL_ADDRESS_COUNTRY_AB2
        if (region_code == NULL || region_code[0] == '\0')
@@ -107,17 +101,40 @@ _e_phone_number_cxx_from_string (const gchar *phone_number,
        if (region_code == NULL || region_code[0] == '\0') {
                /* From outside this is a C library, so we better consult the
                 * C infrastructure instead of std::locale, which might divert. */
-               valid_region = setlocale (LC_ADDRESS, NULL);
+               std::string current_region = setlocale (LC_ADDRESS, NULL);
 
-               const std::string::size_type underscore = valid_region.find ('_');
+               const std::string::size_type underscore = current_region.find ('_');
 
                if (underscore != std::string::npos)
-                       valid_region.resize (underscore);
-       } else {
-               valid_region = region_code;
+                       current_region.resize (underscore);
+
+               return current_region;
        }
 
-       /* Now finally parse the phone number */
+       return region_code;
+}
+
+gint
+_e_phone_number_cxx_get_country_code_for_region (const gchar *region_code)
+{
+       return e_phone_number_util_get_instance ()->GetCountryCodeForRegion (
+               e_phone_number_make_region_code (region_code));
+}
+
+gchar *
+_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)
+{
+       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 =
index d3d11f6..0817c38 100644 (file)
@@ -57,6 +57,10 @@ E_PHONE_NUMBER_LOCAL void            _e_phone_number_set_error               (GError **error,
 
 /* defined in e-phone-number-private.cpp, and used by by e-phone-number.c */
 
+E_PHONE_NUMBER_LOCAL gint              _e_phone_number_cxx_get_country_code_for_region
+                                                                               (const gchar *region_code);
+E_PHONE_NUMBER_LOCAL gchar *           _e_phone_number_cxx_get_default_region  (void);
+
 E_PHONE_NUMBER_LOCAL EPhoneNumber *    _e_phone_number_cxx_from_string         (const gchar *phone_number,
                                                                                 const gchar *region_code,
                                                                                 GError **error);
index e929730..75595a7 100644 (file)
@@ -91,6 +91,66 @@ e_phone_number_is_supported (void)
 }
 
 /**
+ * e_phone_number_get_country_code_for_region:
+ * @region_code: (allow-none): a 2-letter country code, or %NULL
+ *
+ * Returns the preferred country code for @region_code, e.g. 358 for "fi".
+ *
+ * If %NULL is passed for @region_code the default region as returned by
+ * e_phone_number_get_default_region() is used.
+ *
+ * Returns: a valid country code, or zero if an unknown region code was passed.
+ *
+ * Since: 3.8
+ */
+gint
+e_phone_number_get_country_code_for_region (const gchar *region_code)
+{
+#ifdef ENABLE_PHONENUMBER
+
+       return _e_phone_number_cxx_get_country_code_for_region (region_code);
+
+#else /* ENABLE_PHONENUMBER */
+
+       g_warning ("%s: The library was built without phone number support.", G_STRFUNC);
+       return 0;
+
+#endif /* ENABLE_PHONENUMBER */
+}
+
+/**
+ * e_phone_number_get_default_region:
+ *
+ * Retrieves the current 2-letter region code that's used by default for
+ * parsing phone numbers in e_phone_number_from_string(). It can be useful
+ * to store this number before parsing a bigger number of phone numbers.
+ *
+ * The result of this functions depends on the current setup of the
+ * %LC_ADDRESS category: If that category provides a reasonable value
+ * for %_NL_ADDRESS_COUNTRY_AB2 this value is returned. Otherwise the
+ * locale name configured for %LC_ADDRESS is parsed.
+ *
+ * Returns: (transfer full): a newly allocated string containing the
+ * current locale's 2-letter code for phone number parsing.
+ *
+ * Since: 3.8
+ */
+gchar *
+e_phone_number_get_default_region (void)
+{
+#ifdef ENABLE_PHONENUMBER
+
+       return _e_phone_number_cxx_get_default_region ();
+
+#else /* ENABLE_PHONENUMBER */
+
+       g_warning ("%s: The library was built without phone number support.", G_STRFUNC);
+       return NULL;
+
+#endif /* ENABLE_PHONENUMBER */
+}
+
+/**
  * e_phone_number_from_string:
  * @phone_number: the phone number to parse
  * @region_code: (allow-none): a 2-letter country code, or %NULL
@@ -101,10 +161,12 @@ e_phone_number_is_supported (void)
  * region.
  *
  * The 2-letter country code passed in @region_code only is used if the
- * @phone_number is not written in international format. The applications's
- * currently locale is consulted if %NULL gets passed for @region_code.
+ * @phone_number is not written in international format. The application's
+ * default region as returned by e_phone_number_get_default_region() is used
+ * if @region_code is %NULL.
+ *
  * If the number is guaranteed to start with a '+' followed by the country
- * calling code, then "ZZ" can be passed here.
+ * calling code, then "ZZ" can be passed for @region_code.
  *
  * Returns: (transfer full): a new EPhoneNumber instance on success,
  * or %NULL on error. Call e_phone_number_free() to release this instance.
index a81fb71..e1442b2 100644 (file)
@@ -188,6 +188,10 @@ GType                      e_phone_number_get_type         (void);
 GQuark                 e_phone_number_error_quark      (void);
 
 gboolean               e_phone_number_is_supported     (void) G_GNUC_CONST;
+gint                   e_phone_number_get_country_code_for_region
+                                                       (const gchar *region_code);
+gchar *                        e_phone_number_get_default_region
+                                                       (void);
 
 EPhoneNumber *         e_phone_number_from_string      (const gchar *phone_number,
                                                         const gchar *region_code,
index 0932f14..7344f52 100644 (file)
@@ -565,6 +565,8 @@ EPhoneNumberError
 EPhoneNumberFormat
 EPhoneNumberMatch
 e_phone_number_is_supported
+e_phone_number_get_country_code_for_region
+e_phone_number_get_default_region
 e_phone_number_from_string
 e_phone_number_to_string
 e_phone_number_get_country_code
index 60513b1..b8bbd48 100644 (file)
@@ -335,6 +335,16 @@ test_supported (void)
 #endif /* ENABLE_PHONENUMBER */
 }
 
+static void
+test_country_code_for_region (void)
+{
+       g_assert_cmpstr (setlocale (LC_ADDRESS, NULL), ==, "en_US.UTF-8");
+       g_assert_cmpint (e_phone_number_get_country_code_for_region ("CH"), ==, 41);
+       g_assert_cmpint (e_phone_number_get_country_code_for_region (NULL), ==, 1);
+       g_assert_cmpint (e_phone_number_get_country_code_for_region ("C"), ==, 0);
+       g_assert_cmpint (e_phone_number_get_country_code_for_region (""), ==, 1);
+}
+
 gint
 main (gint argc,
       gchar **argv)
@@ -382,13 +392,13 @@ main (gint argc,
                         "+3587144556677", "+358 71 44556677", "071 44556677", "tel:+358-71-44556677"),
                test_parse_and_format, parse_and_format_data_free);
 
-       g_test_add_func
-               ("/ebook-phone-number/parse-and-format/bad-number",
-                test_parse_bad_number);
+       g_test_add_func (
+               "/ebook-phone-number/parse-and-format/bad-number",
+               test_parse_bad_number);
 
-       g_test_add_func
-               ("/ebook-phone-number/parse-and-format/auto-region",
-                test_parse_auto_region);
+       g_test_add_func (
+               "/ebook-phone-number/parse-and-format/auto-region",
+               test_parse_auto_region);
 
        g_assert_cmpint (G_N_ELEMENTS (match_candidates) * G_N_ELEMENTS (match_candidates),
                         ==, G_N_ELEMENTS (expected_matches));
@@ -404,5 +414,9 @@ main (gint argc,
                }
        }
 
+       g_test_add_func (
+               "/ebook-phone-number/country-code/for-region",
+               test_country_code_for_region);
+
        return g_test_run ();
 }