[folks] Fix phone normalization
- From: Xavier Claessens <xclaesse src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [folks] Fix phone normalization
- Date: Mon, 21 Oct 2013 17:36:03 +0000 (UTC)
commit d118e13f9a73e9ce4a9ff806150e36888f144f17
Author: Xavier Claessens <xavier claessens collabora co uk>
Date: Mon Oct 21 10:29:02 2013 -0400
Fix phone normalization
This make the code actually match the algorithm described on
http://blog.barisione.org/2010-06/handling-phone-numbers/
It also use a StringBuilder instead of doing tones of string copy.
NEWS | 3 +
folks/phone-details.vala | 70 ++++++++++++++++++++++++----------
tests/folks/phone-field-details.vala | 3 +
3 files changed, 56 insertions(+), 20 deletions(-)
---
diff --git a/NEWS b/NEWS
index 00fdcc9..2ad7b4f 100644
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,9 @@ Bugs fixed:
• Bug 710178 — Skip whitespace between oFono vCards
• Bug 682698 — const string[] not NULL terminated; crashes in GBoxed property
getter (workaround)
+• Avoid useless string copies when normalizing phone numbers, and make the
+ implementation respect the algorithm described in
+ http://blog.barisione.org/2010-06/handling-phone-numbers
API changes:
diff --git a/folks/phone-details.vala b/folks/phone-details.vala
index f906990..141ac07 100644
--- a/folks/phone-details.vala
+++ b/folks/phone-details.vala
@@ -35,11 +35,11 @@ using Gee;
*/
public class Folks.PhoneFieldDetails : AbstractFieldDetails<string>
{
- private const string[] _extension_chars = { "p", "P", "w", "W", "x", "X" };
- private const string[] _common_delimiters = { ",", ".", "(", ")", "-", " ",
- "\t", "/" };
- private const string[] _valid_digits = { "#", "*", "0", "1", "2", "3", "4",
- "5", "6", "7", "8", "9" };
+ private const char[] _extension_chars = { 'p', 'P', 'w', 'W', 'x', 'X' };
+ private const char[] _common_delimiters = { ',', '.', '(', ')', '-', ' ',
+ '\t', '/' };
+ private const char[] _valid_digits = { '#', '*', '0', '1', '2', '3', '4',
+ '5', '6', '7', '8', '9' };
private string _id;
/**
@@ -108,7 +108,7 @@ public class Folks.PhoneFieldDetails : AbstractFieldDetails<string>
debug ("[PhoneDetails.equal] Comparing %s with %s",
n1_reduced, n2_reduced);
- return n1_reduced == n2_reduced;
+ return n1_reduced == n2_reduced;
}
return n1 == n2;
@@ -139,30 +139,53 @@ public class Folks.PhoneFieldDetails : AbstractFieldDetails<string>
*/
public string get_normalised ()
{
- string normalised_number = "";
+ var builder = new StringBuilder ();
- for (int i = 0; i < this.value.length; i++)
+ /* Based on http://blog.barisione.org/2010-06/handling-phone-numbers/ */
+ for (uint i = 0; i < this.value.length; i++)
{
- var digit = this.value.slice (i, i + 1);
+ var digit = this.value[i];
- if (digit in PhoneFieldDetails._extension_chars ||
- digit in PhoneFieldDetails._valid_digits ||
- (i == 0 && digit == "+"))
+ if (digit in PhoneFieldDetails._extension_chars)
+ {
+ /* Keep the extension characters P, W and X, but be sure they are
+ * upper case. */
+ digit = digit.toupper ();
+ }
+ else if (digit == '+')
{
- /* lets keep valid digits */
- normalised_number += digit;
+ /* "+" is valid only at the beginning of phone numbers or after
+ * the number suppression prefix. */
+ if (builder.str != "" &&
+ builder.str != "*31#" &&
+ builder.str != "#31#")
+ {
+ /* Skip this "+". */
+ debug ("[PhoneDetails.get_normalised] Wrong '+' in %s",
+ this.value);
+ continue;
+ }
}
else if (digit in PhoneFieldDetails._common_delimiters)
{
+ /* Skip this delimiter. */
continue;
}
+ else if (digit in PhoneFieldDetails._valid_digits)
+ {
+ /* Ok, let's keep it. */
+ }
else
{
- debug ("[PhoneDetails.get_normalised] unknown digit: %s", digit);
+ /* What is this? It doesn't seem valid but we just keep it */
+ debug ("[PhoneDetails.get_normalised] Unknown character '%c' in '%s'",
+ digit, this.value);
}
+
+ builder.append_c (digit);
}
- return normalised_number.up ();
+ return builder.str;
}
/**
@@ -176,15 +199,22 @@ public class Folks.PhoneFieldDetails : AbstractFieldDetails<string>
*/
internal static string _drop_extension (string number)
{
- for (var i = 0; i < PhoneFieldDetails._extension_chars.length; i++)
+ /* Based on http://blog.barisione.org/2010-06/handling-phone-numbers/ */
+ var builder = new StringBuilder ();
+
+ for (uint i = 0; i < number.length; i++)
{
- if (number.index_of (PhoneFieldDetails._extension_chars[i]) >= 0)
+ var digit = number[i];
+ if (digit in PhoneFieldDetails._extension_chars)
{
- return number.split (PhoneFieldDetails._extension_chars[i])[0];
+ /* Extension character, drop this character and the rest of the
+ * string. */
+ break;
}
+ builder.append_c (digit);
}
- return number;
+ return builder.str;
}
}
diff --git a/tests/folks/phone-field-details.vala b/tests/folks/phone-field-details.vala
index 02f07aa..afcb2b7 100644
--- a/tests/folks/phone-field-details.vala
+++ b/tests/folks/phone-field-details.vala
@@ -43,6 +43,9 @@ public class PhoneFieldDetailsTests : Folks.TestCase
{ "1-800-123-4567", "18001234567" },
{ "+1-800-123-4567", "+18001234567" },
{ "+1-800-123-4567P123", "+18001234567P123" },
+ { "+1-800-123-4567p123", "+18001234567P123" },
+ { "#31#+123", "#31#+123" },
+ { "*31#+123", "*31#+123" },
};
foreach (var s in normalisation_pairs)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]