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
// 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
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]+)?")),
third_group = digit_group;
}
}
- string region_code;
- GetRegionCodeForCountryCode(number.country_code(), ®ion_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(
// 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
}
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]);
}
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]);
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);
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.
/**
+ * 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.
*
* @const
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
* stripping all other characters if removeNonMatches is true.
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));