From: philip.liard@gmail.com Date: Wed, 12 Oct 2011 11:47:24 +0000 (+0000) Subject: CPP: Add number formatting for mobile dialling X-Git-Tag: upstream/5.3.2~174 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cb2b419c90a7587644af11b57002a33dd908257c;p=platform%2Fupstream%2Flibphonenumber.git CPP: Add number formatting for mobile dialling git-svn-id: http://libphonenumber.googlecode.com/svn/trunk@367 ee073f10-1060-11df-b6a4-87a95322a99c --- diff --git a/cpp/src/phonenumbers/phonenumberutil.cc b/cpp/src/phonenumbers/phonenumberutil.cc index d1faafb..4d5fe73 100644 --- a/cpp/src/phonenumbers/phonenumberutil.cc +++ b/cpp/src/phonenumbers/phonenumberutil.cc @@ -99,6 +99,10 @@ scoped_ptr > alpha_phone_mappings; // as "-" and " ". scoped_ptr > all_plus_number_grouping_symbols; +// The prefix that needs to be inserted in front of a Colombian landline +// number when dialed from a mobile phone in Colombia. +const char kColombiaMobileToFixedLinePrefix[] = "3"; + // The kPlusSign signifies the international prefix. const char kPlusSign[] = "+"; @@ -987,6 +991,56 @@ void PhoneNumberUtil::FormatNationalNumberWithPreferredCarrierCode( formatted_number); } +void PhoneNumberUtil::FormatNumberForMobileDialing( + const PhoneNumber& number, + const string& calling_from, + bool with_formatting, + string* formatted_number) const { + string region_code; + GetRegionCodeForNumber(number, ®ion_code); + if (!IsValidRegionCode(region_code)) { + formatted_number->assign(number.has_raw_input() ? number.raw_input() : ""); + return; + } + + // Clear the extension, as that part cannot normally be dialed together with + // the main number. + PhoneNumber number_no_extension(number); + number_no_extension.clear_extension(); + PhoneNumberType number_type = GetNumberType(number_no_extension); + if ((region_code == "CO") && (calling_from == "CO") && + (number_type == FIXED_LINE)) { + FormatNationalNumberWithCarrierCode( + number_no_extension, kColombiaMobileToFixedLinePrefix, + formatted_number); + } else if ((region_code == "BR") && (calling_from == "BR") && + ((number_type == FIXED_LINE) || (number_type == MOBILE) || + (number_type == FIXED_LINE_OR_MOBILE))) { + if (number_no_extension.has_preferred_domestic_carrier_code()) { + FormatNationalNumberWithPreferredCarrierCode(number_no_extension, "", + formatted_number); + } else { + // Brazilian fixed line and mobile numbers need to be dialed with a + // carrier code when called within Brazil. Without that, most of the + // carriers won't connect the call. Because of that, we return an empty + // string here. + formatted_number->assign(""); + } + } else if (CanBeInternationallyDialled(number_no_extension)) { + with_formatting + ? Format(number_no_extension, INTERNATIONAL, formatted_number) + : Format(number_no_extension, E164, formatted_number); + return; + } else if (calling_from == region_code) { + Format(number_no_extension, NATIONAL, formatted_number); + } else { + formatted_number->assign(""); + } + if (!with_formatting) { + NormalizeDigitsOnly(formatted_number); + } +} + void PhoneNumberUtil::FormatOutOfCountryCallingNumber( const PhoneNumber& number, const string& calling_from, @@ -2257,5 +2311,20 @@ AsYouTypeFormatter* PhoneNumberUtil::GetAsYouTypeFormatter( return new AsYouTypeFormatter(region_code); } +bool PhoneNumberUtil::CanBeInternationallyDialled( + const PhoneNumber& number) const { + string region_code; + GetRegionCodeForNumber(number, ®ion_code); + string national_significant_number; + GetNationalSignificantNumber(number, &national_significant_number); + if (!HasValidRegionCode(region_code, number.country_code(), + national_significant_number)) { + return true; + } + const PhoneMetadata* metadata = GetMetadataForRegion(region_code); + return !IsNumberMatchingDesc( + national_significant_number, metadata->no_international_dialling()); +} + } // namespace phonenumbers } // namespace i18n diff --git a/cpp/src/phonenumbers/phonenumberutil.h b/cpp/src/phonenumbers/phonenumberutil.h index 6bc8022..f2979c4 100644 --- a/cpp/src/phonenumbers/phonenumberutil.h +++ b/cpp/src/phonenumbers/phonenumberutil.h @@ -298,6 +298,16 @@ class PhoneNumberUtil : public Singleton { const string& fallback_carrier_code, string* formatted_number) const; + // Returns a number formatted in such a way that it can be dialed from a + // mobile phone in a specific region. If the number cannot be reached from + // the region (e.g. some countries block toll-free numbers from being called + // outside of the country), the method returns an empty string. + void FormatNumberForMobileDialing( + const PhoneNumber& number, + const string& region_calling_from, + bool with_formatting, + string* formatted_number) const; + // Formats a phone number for out-of-country dialing purposes. // // Note this function takes care of the case for calling inside of NANPA @@ -675,6 +685,11 @@ class PhoneNumberUtil : public Singleton { bool check_region, PhoneNumber* phone_number) const; + // Returns true if the number can only be dialled from within the region. If + // unknown, or the number can be dialled from outside the region as well, + // returns false. Does not check the number is a valid number. + bool CanBeInternationallyDialled(const PhoneNumber& number) const; + DISALLOW_COPY_AND_ASSIGN(PhoneNumberUtil); }; diff --git a/cpp/test/phonenumbers/phonenumberutil_test.cc b/cpp/test/phonenumbers/phonenumberutil_test.cc index f350350..9a0cca5 100644 --- a/cpp/test/phonenumbers/phonenumberutil_test.cc +++ b/cpp/test/phonenumbers/phonenumberutil_test.cc @@ -56,6 +56,10 @@ class PhoneNumberUtilTest : public testing::Test { phone_util_.ExtractPossibleNumber(number, extracted_number); } + bool CanBeInternationallyDialled(const PhoneNumber& number) const { + return phone_util_.CanBeInternationallyDialled(number); + } + bool IsViablePhoneNumber(const string& number) const { return phone_util_.IsViablePhoneNumber(number); } @@ -787,6 +791,44 @@ TEST_F(PhoneNumberUtilTest, FormatWithPreferredCarrierCode) { EXPECT_EQ("424 123 1234", formatted_number); } +TEST_F(PhoneNumberUtilTest, FormatNumberForMobileDialing) { + PhoneNumber test_number; + string formatted_number; + test_number.set_country_code(1); + + // US toll free numbers are marked as noInternationalDialling in the test + // metadata for testing purposes. + test_number.set_national_number(8002530000ULL); + phone_util_.FormatNumberForMobileDialing( + test_number, RegionCode::US(), true, &formatted_number); + EXPECT_EQ("800 253 0000", formatted_number); + phone_util_.FormatNumberForMobileDialing( + test_number, RegionCode::CN(), true, &formatted_number); + EXPECT_EQ("", formatted_number); + phone_util_.FormatNumberForMobileDialing( + test_number, RegionCode::US(), false, &formatted_number); + EXPECT_EQ("8002530000", formatted_number); + phone_util_.FormatNumberForMobileDialing( + test_number, RegionCode::CN(), false, &formatted_number); + EXPECT_EQ("", formatted_number); + + test_number.set_national_number(6502530000ULL); + phone_util_.FormatNumberForMobileDialing( + test_number, RegionCode::US(), true, &formatted_number); + EXPECT_EQ("+1 650 253 0000", formatted_number); + phone_util_.FormatNumberForMobileDialing( + test_number, RegionCode::US(), false, &formatted_number); + EXPECT_EQ("+16502530000", formatted_number); + + test_number.set_extension("1234"); + phone_util_.FormatNumberForMobileDialing( + test_number, RegionCode::US(), true, &formatted_number); + EXPECT_EQ("+1 650 253 0000", formatted_number); + phone_util_.FormatNumberForMobileDialing( + test_number, RegionCode::US(), false, &formatted_number); + EXPECT_EQ("+16502530000", formatted_number); +} + TEST_F(PhoneNumberUtilTest, FormatByPattern) { PhoneNumber test_number; string formatted_number; @@ -2827,6 +2869,29 @@ TEST_F(PhoneNumberUtilTest, ParseAndKeepRaw) { EXPECT_EQ(korean_number, test_number); } +TEST_F(PhoneNumberUtilTest, CanBeInternationallyDialled) { + PhoneNumber test_number; + test_number.set_country_code(1); + + // We have no-international-dialling rules for the US in our test metadata + // that say that toll-free numbers cannot be dialled internationally. + test_number.set_national_number(8002530000ULL); + EXPECT_FALSE(CanBeInternationallyDialled(test_number)); + + // Normal US numbers can be internationally dialled. + test_number.set_national_number(6502530000ULL); + EXPECT_TRUE(CanBeInternationallyDialled(test_number)); + + // Invalid number. + test_number.set_national_number(2530000ULL); + EXPECT_TRUE(CanBeInternationallyDialled(test_number)); + + // We have no data for NZ - should return true. + test_number.set_country_code(64); + test_number.set_national_number(33316005ULL); + EXPECT_TRUE(CanBeInternationallyDialled(test_number)); +} + TEST_F(PhoneNumberUtilTest, IsAlphaNumber) { static const string kAlphaNumber("1800 six-flags"); EXPECT_TRUE(phone_util_.IsAlphaNumber(kAlphaNumber));