1 // Copyright (C) 2012 The Libphonenumber Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Library for obtaining information about international short phone numbers, 16 // such as short codes and emergency numbers. Note most commercial short 17 // numbers are not handled here, but by the phonenumberutil. 18 19 #ifndef I18N_PHONENUMBERS_SHORTNUMBERINFO_H_ 20 #define I18N_PHONENUMBERS_SHORTNUMBERINFO_H_ 21 22 #include <list> 23 #include <map> 24 #include <set> 25 #include <string> 26 27 #include "phonenumbers/base/basictypes.h" 28 #include "phonenumbers/base/memory/scoped_ptr.h" 29 30 namespace i18n { 31 namespace phonenumbers { 32 33 using std::list; 34 using std::map; 35 using std::set; 36 using std::string; 37 38 class MatcherApi; 39 class PhoneMetadata; 40 class PhoneNumber; 41 class PhoneNumberUtil; 42 43 class ShortNumberInfo { 44 public: 45 ShortNumberInfo(); 46 ~ShortNumberInfo(); 47 48 // Cost categories of short numbers. 49 enum ShortNumberCost { 50 TOLL_FREE, 51 STANDARD_RATE, 52 PREMIUM_RATE, 53 UNKNOWN_COST 54 }; 55 56 // Check whether a short number is a possible number when dialled from a 57 // region, given the number in the form of a string, and the region where the 58 // number is dialed from. This provides a more lenient check than 59 // IsValidShortNumberForRegion. 60 bool IsPossibleShortNumberForRegion( 61 const PhoneNumber& short_number, 62 const string& region_dialing_from) const; 63 64 // Check whether a short number is a possible number. If a country calling 65 // code is shared by multiple regions, this returns true if it's possible in 66 // any of them. This provides a more lenient check than IsValidShortNumber. 67 // See IsPossibleShortNumberForRegion for details. 68 bool IsPossibleShortNumber(const PhoneNumber& number) const; 69 70 // Tests whether a short number matches a valid pattern in a region. Note 71 // that this doesn't verify the number is actually in use, which is 72 // impossible to tell by just looking at the number itself. 73 bool IsValidShortNumberForRegion( 74 const PhoneNumber& short_number, 75 const string& region_dialing_from) const; 76 77 // Tests whether a short number matches a valid pattern. If a country calling 78 // code is shared by multiple regions, this returns true if it's valid in any 79 // of them. Note that this doesn't verify the number is actually in use, 80 // which is impossible to tell by just looking at the number itself. See 81 // IsValidShortNumberForRegion for details. 82 bool IsValidShortNumber(const PhoneNumber& number) const; 83 84 // Gets the expected cost category of a short number when dialled from a 85 // region (however, nothing is implied about its validity). If it is 86 // important that the number is valid, then its validity must first be 87 // checked using IsValidShortNumberForRegion. Note that emergency numbers are 88 // always considered toll-free. Example usage: 89 // 90 // PhoneNumber number; 91 // phone_util.Parse("110", "US", &number); 92 // ... 93 // string region_code("CA"); 94 // ShortNumberInfo short_info; 95 // if (short_info.IsValidShortNumberForRegion(number, region_code)) { 96 // ShortNumberInfo::ShortNumberCost cost = 97 // short_info.GetExpectedCostForRegion(number, region_code); 98 // // Do something with the cost information here. 99 // } 100 ShortNumberCost GetExpectedCostForRegion( 101 const PhoneNumber& short_number, 102 const string& region_dialing_from) const; 103 104 // Gets the expected cost category of a short number (however, nothing is 105 // implied about its validity). If the country calling code is unique to a 106 // region, this method behaves exactly the same as GetExpectedCostForRegion. 107 // However, if the country calling code is shared by multiple regions, then 108 // it returns the highest cost in the sequence PREMIUM_RATE, UNKNOWN_COST, 109 // STANDARD_RATE, TOLL_FREE. The reason for the position of UNKNOWN_COST in 110 // this order is that if a number is UNKNOWN_COST in one region but 111 // STANDARD_RATE or TOLL_FREE in another, its expected cost cannot be 112 // estimated as one of the latter since it might be a PREMIUM_RATE number. 113 // 114 // For example, if a number is STANDARD_RATE in the US, but TOLL_FREE in 115 // Canada, the expected cost returned by this method will be STANDARD_RATE, 116 // since the NANPA countries share the same country calling code. 117 // 118 // Note: If the region from which the number is dialed is known, it is highly 119 // preferable to call GetExpectedCostForRegion instead. 120 ShortNumberCost GetExpectedCost(const PhoneNumber& number) const; 121 122 // Gets a valid short number for the specified region. 123 string GetExampleShortNumber(const string& region_code) const; 124 125 // Gets a valid short number for the specified cost category. 126 string GetExampleShortNumberForCost(const string& region_code, 127 ShortNumberCost cost) const; 128 129 // Returns true if the number might be used to connect to an emergency service 130 // in the given region. 131 // 132 // This method takes into account cases where the number might contain 133 // formatting, or might have additional digits appended (when it is okay to do 134 // that in the region specified). 135 bool ConnectsToEmergencyNumber(const string& number, 136 const string& region_code) const; 137 138 // Returns true if the number exactly matches an emergency service number in 139 // the given region. 140 // 141 // This method takes into account cases where the number might contain 142 // formatting, but doesn't allow additional digits to be appended. 143 bool IsEmergencyNumber(const string& number, 144 const string& region_code) const; 145 146 // Given a valid short number, determines whether it is carrier-specific 147 // (however, nothing is implied about its validity). Carrier-specific numbers 148 // may connect to a different end-point, or not connect at all, depending on 149 // the user's carrier. If it is important that the number is valid, then its 150 // validity must first be checked using IsValidShortNumber or 151 // IsValidShortNumberForRegion. 152 bool IsCarrierSpecific(const PhoneNumber& number) const; 153 154 // Given a valid short number, determines whether it is carrier-specific when 155 // dialed from the given region (however, nothing is implied about its 156 // validity). Carrier-specific numbers may connect to a different end-point, 157 // or not connect at all, depending on the user's carrier. If it is important 158 // that the number is valid, then its validity must first be checked using 159 // IsValidShortNumber or IsValidShortNumberForRegion. Returns false if the 160 // number doesn't match the region provided. 161 bool IsCarrierSpecificForRegion( 162 const PhoneNumber& number, 163 const string& region_dialing_from) const; 164 165 // Given a valid short number, determines whether it is an SMS service 166 // (however, nothing is implied about its validity). An SMS service is where 167 // the primary or only intended usage is to receive and/or send text messages 168 // (SMSs). This includes MMS as MMS numbers downgrade to SMS if the other 169 // party isn't MMS-capable. If it is important that the number is valid, then 170 // its validity must first be checked using IsValidShortNumber or 171 // IsValidShortNumberForRegion. Returns false if the number doesn't match the 172 // region provided. 173 bool IsSmsServiceForRegion( 174 const PhoneNumber& number, 175 const string& region_dialing_from) const; 176 177 private: 178 const PhoneNumberUtil& phone_util_; 179 const scoped_ptr<const MatcherApi> matcher_api_; 180 181 // A mapping from a RegionCode to the PhoneMetadata for that region. 182 scoped_ptr<std::map<string, PhoneMetadata> > 183 region_to_short_metadata_map_; 184 185 // In these countries, if extra digits are added to an emergency number, it no 186 // longer connects to the emergency service. 187 scoped_ptr<std::set<string> > 188 regions_where_emergency_numbers_must_be_exact_; 189 190 const i18n::phonenumbers::PhoneMetadata* GetMetadataForRegion( 191 const string& region_code) const; 192 193 bool RegionDialingFromMatchesNumber(const PhoneNumber& number, 194 const string& region_dialing_from) const; 195 196 // Helper method to get the region code for a given phone number, from a list 197 // of possible region codes. If the list contains more than one region, the 198 // first region for which the number is valid is returned. 199 void GetRegionCodeForShortNumberFromRegionList( 200 const PhoneNumber& number, 201 const list<string>& region_codes, 202 string* region_code) const; 203 204 bool MatchesEmergencyNumberHelper(const string& number, 205 const string& region_code, 206 bool allow_prefix_match) const; 207 208 DISALLOW_COPY_AND_ASSIGN(ShortNumberInfo); 209 }; 210 211 } // namespace phonenumbers 212 } // namespace i18n 213 214 #endif // I18N_PHONENUMBERS_SHORTNUMBERINFO_H_ 215