Browse Source

JS/C++: Added mobile token support to phone number util

pull/567/head
Cecilia Roes 12 years ago
committed by Mihaela Rosca
parent
commit
35a62b36e7
6 changed files with 120 additions and 24 deletions
  1. +35
    -9
      cpp/src/phonenumbers/phonenumberutil.cc
  2. +7
    -0
      cpp/src/phonenumbers/phonenumberutil.h
  3. +4
    -4
      cpp/test/phonenumbers/geocoding/geocoding_data_test.cc
  4. +19
    -0
      cpp/test/phonenumbers/phonenumberutil_test.cc
  5. +46
    -11
      javascript/i18n/phonenumbers/phonenumberutil.js
  6. +9
    -0
      javascript/i18n/phonenumbers/phonenumberutil_test.js

+ 35
- 9
cpp/src/phonenumbers/phonenumberutil.cc View File

@ -473,6 +473,9 @@ class PhoneNumberRegExpsAndMappings {
alpha_phone_mappings_.insert(make_pair(c, c));
all_plus_number_grouping_symbols_.insert(make_pair(c, c));
}
mobile_token_mappings_.insert(make_pair(52, '1'));
mobile_token_mappings_.insert(make_pair(54, '9'));
}
// Small string helpers since StrCat has a maximum number of arguments. These
@ -526,6 +529,12 @@ class PhoneNumberRegExpsAndMappings {
// such as "-" and " ".
map<char32, char> all_plus_number_grouping_symbols_;
// Map of country calling codes that use a mobile token before the area code.
// One example of when this is relevant is when determining the length of the
// national destination code, which should be the length of the area code plus
// the length of the mobile token.
map<int, char> mobile_token_mappings_;
// Pattern that makes it easy to distinguish whether a region has a unique
// international dialing prefix or not. If a region has a unique international
// prefix (e.g. 011 in USA), it will be represented as a string that contains
@ -610,6 +619,7 @@ class PhoneNumberRegExpsAndMappings {
alpha_mappings_(),
alpha_phone_mappings_(),
all_plus_number_grouping_symbols_(),
mobile_token_mappings_(),
unique_international_prefix_(regexp_factory_->CreateRegExp(
/* "[\\d]+(?:[~⁓∼~][\\d]+)?" */
"[\\d]+(?:[~\xE2\x81\x93\xE2\x88\xBC\xEF\xBD\x9E][\\d]+)?")),
@ -2185,19 +2195,35 @@ int PhoneNumberUtil::GetLengthOfNationalDestinationCode(
third_group = digit_group;
}
}
string region_code;
GetRegionCodeForCountryCode(number.country_code(), &region_code);
if (region_code == "AR" &&
GetNumberType(number) == MOBILE) {
// Argentinian mobile numbers, when formatted in the international format,
// are in the form of +54 9 NDC XXXX.... As a result, we take the length of
// the third group (NDC) and add 1 for the digit 9, which also forms part of
// the national significant number.
return third_group.size() + 1;
if (GetNumberType(number) == MOBILE) {
// For example Argentinian mobile numbers, when formatted in the
// international format, are in the form of +54 9 NDC XXXX.... As a result,
// we take the length of the third group (NDC) and add the length of the
// mobile token, which also forms part of the national significant number.
// This assumes that the mobile token is always formatted separately from
// the rest of the phone number.
string mobile_token;
GetCountryMobileToken(number.country_code(), &mobile_token);
if (!mobile_token.empty()) {
return third_group.size() + mobile_token.size();
}
}
return ndc.size();
}
void PhoneNumberUtil::GetCountryMobileToken(int country_calling_code,
string* mobile_token) const {
DCHECK(mobile_token);
map<int, char>::iterator it = reg_exps_->mobile_token_mappings_.find(
country_calling_code);
if (it != reg_exps_->mobile_token_mappings_.end()) {
*mobile_token = it->second;
} else {
mobile_token->assign("");
}
}
void PhoneNumberUtil::NormalizeDigitsOnly(string* number) const {
DCHECK(number);
const RegExp& non_digits_pattern = reg_exps_->regexp_cache_->GetRegExp(


+ 7
- 0
cpp/src/phonenumbers/phonenumberutil.h View File

@ -272,6 +272,13 @@ class PhoneNumberUtil : public Singleton<PhoneNumberUtil> {
// GetLengthOfGeographicalAreaCode().
int GetLengthOfNationalDestinationCode(const PhoneNumber& number) const;
// Returns the mobile token for the provided country calling code if it has
// one, otherwise returns an empty string. A mobile token is a number inserted
// before the area code when dialing a mobile number from that country from
// abroad.
void GetCountryMobileToken(int country_calling_code,
string* mobile_token) const;
// Formats a phone number in the specified format using default rules. Note
// that this does not promise to produce a phone number that the user can
// dial from where they are - although we do format in either NATIONAL or


+ 4
- 4
cpp/test/phonenumbers/geocoding/geocoding_data_test.cc View File

@ -130,9 +130,9 @@ TEST(GeocodingDataTest, TestTestPrefixDescriptions) {
}
TEST(GeocodingDataTest, TestTestGeocodingData) {
ASSERT_EQ(2, get_test_country_calling_codes_size());
ASSERT_EQ(3, get_test_country_calling_codes_size());
const int* country_calling_codes = get_test_country_calling_codes();
const int expected_calling_codes[] = {1, 82};
const int expected_calling_codes[] = {1, 54, 82};
for (int i = 0; i < get_test_country_calling_codes_size(); ++i) {
EXPECT_EQ(expected_calling_codes[i], country_calling_codes[i]);
}
@ -144,10 +144,10 @@ TEST(GeocodingDataTest, TestTestGeocodingData) {
EXPECT_STREQ(expected_languages[i], langs_1->available_languages[i]);
}
ASSERT_EQ(4, get_test_prefix_language_code_pairs_size());
ASSERT_EQ(5, get_test_prefix_language_code_pairs_size());
const char** language_code_pairs = get_test_prefix_language_code_pairs();
const char* expected_language_code_pairs[] = {
"1_de", "1_en", "82_en", "82_ko",
"1_de", "1_en", "54_en", "82_en", "82_ko",
};
for (int i = 0; i < get_test_prefix_language_code_pairs_size(); ++i) {
EXPECT_STREQ(expected_language_code_pairs[i], language_code_pairs[i]);


+ 19
- 0
cpp/test/phonenumbers/phonenumberutil_test.cc View File

@ -1281,6 +1281,11 @@ TEST_F(PhoneNumberUtilTest, GetLengthOfNationalDestinationCode) {
number.set_national_number(1155303000ULL);
EXPECT_EQ(2, phone_util_.GetLengthOfNationalDestinationCode(number));
// An Argentinian mobile which has NDC "911".
number.set_country_code(54);
number.set_national_number(91187654321ULL);
EXPECT_EQ(3, phone_util_.GetLengthOfNationalDestinationCode(number));
// Google Sydney, which has NDC "2".
number.set_country_code(61);
number.set_national_number(293744000ULL);
@ -1320,6 +1325,20 @@ TEST_F(PhoneNumberUtilTest, GetLengthOfNationalDestinationCode) {
EXPECT_EQ(4, phone_util_.GetLengthOfNationalDestinationCode(number));
}
TEST_F(PhoneNumberUtilTest, GetCountryMobileToken) {
int country_calling_code;
string mobile_token;
country_calling_code = phone_util_.GetCountryCodeForRegion(RegionCode::MX());
phone_util_.GetCountryMobileToken(country_calling_code, &mobile_token);
EXPECT_EQ("1", mobile_token);
// Country calling code for United States, which has no mobile token.
country_calling_code = phone_util_.GetCountryCodeForRegion(RegionCode::US());
phone_util_.GetCountryMobileToken(country_calling_code, &mobile_token);
EXPECT_EQ("", mobile_token);
}
TEST_F(PhoneNumberUtilTest, ExtractPossibleNumber) {
// Removes preceding funky punctuation and letters but leaves the rest
// untouched.


+ 46
- 11
javascript/i18n/phonenumbers/phonenumberutil.js View File

@ -159,6 +159,22 @@ i18n.phonenumbers.PhoneNumberUtil.UNKNOWN_REGION_ = 'ZZ';
i18n.phonenumbers.PhoneNumberUtil.COLOMBIA_MOBILE_TO_FIXED_LINE_PREFIX_ = '3';
/**
* Map of country calling codes that use a mobile token before the area code.
* One example of when this is relevant is when determining the length of the
* national destination code, which should be the length of the area code plus
* the length of the mobile token.
*
* @const
* @type {!Object.<number, string>}
* @private
*/
i18n.phonenumbers.PhoneNumberUtil.MOBILE_TOKEN_MAPPINGS_ = {
52: '1',
54: '9'
};
/**
* The PLUS_SIGN signifies the international prefix.
*
@ -1217,22 +1233,41 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.getLengthOfNationalDestinationCode =
return 0;
}
if (this.getRegionCodeForCountryCode(number.getCountryCodeOrDefault()) ==
'AR' &&
this.getNumberType(number) == i18n.phonenumbers.PhoneNumberType.MOBILE) {
// Argentinian mobile numbers, when formatted in the international format,
// are in the form of +54 9 NDC XXXX.... As a result, we take the length of
// the third group (NDC) and add 1 for the digit 9, which also forms part of
// the national significant number.
//
// TODO: Investigate the possibility of better modeling the metadata to make
// it easier to obtain the NDC.
return numberGroups[2].length + 1;
if (this.getNumberType(number) == i18n.phonenumbers.PhoneNumberType.MOBILE) {
// For example Argentinian mobile numbers, when formatted in the
// international format, are in the form of +54 9 NDC XXXX.... As a result,
// we take the length of the third group (NDC) and add the length of the
// mobile token, which also forms part of the national significant number.
// This assumes that the mobile token is always formatted separately from
// the rest of the phone number.
/** @type {string} */
var mobileToken = i18n.phonenumbers.PhoneNumberUtil.getCountryMobileToken(
number.getCountryCodeOrDefault());
if (mobileToken != '') {
return numberGroups[2].length + mobileToken.length;
}
}
return numberGroups[1].length;
};
/**
* Returns the mobile token for the provided country calling code if it has
* one, otherwise returns an empty string. A mobile token is a number inserted
* before the area code when dialing a mobile number from that country from
* abroad.
*
* @param {number} countryCallingCode the country calling code for which we
* want the mobile token.
* @return {string} the mobile token for the given country calling code.
*/
i18n.phonenumbers.PhoneNumberUtil.getCountryMobileToken =
function(countryCallingCode) {
return i18n.phonenumbers.PhoneNumberUtil.MOBILE_TOKEN_MAPPINGS_[
countryCallingCode] || '';
};
/**
* Normalizes a string of characters representing a phone number by replacing
* all characters found in the accompanying map with the values therein, and


+ 9
- 0
javascript/i18n/phonenumbers/phonenumberutil_test.js View File

@ -415,6 +415,15 @@ function testGetLengthOfNationalDestinationCode() {
phoneUtil.getLengthOfNationalDestinationCode(INTERNATIONAL_TOLL_FREE));
}
function testGetCountryMobileToken() {
assertEquals('1', i18n.phonenumbers.PhoneNumberUtil.getCountryMobileToken(
phoneUtil.getCountryCodeForRegion(RegionCode.MX)));
// Country calling code for United States, which has no mobile token.
assertEquals('', i18n.phonenumbers.PhoneNumberUtil.getCountryMobileToken(
phoneUtil.getCountryCodeForRegion(RegionCode.US)));
}
function testGetNationalSignificantNumber() {
assertEquals('6502530000',
phoneUtil.getNationalSignificantNumber(US_NUMBER));


Loading…
Cancel
Save