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 47 // This type is neither copyable nor movable. 48 ShortNumberInfo(const ShortNumberInfo&) = delete; 49 ShortNumberInfo& operator=(const ShortNumberInfo&) = delete; 50 51 ~ShortNumberInfo(); 52 53 // Cost categories of short numbers. 54 enum ShortNumberCost { 55 TOLL_FREE, 56 STANDARD_RATE, 57 PREMIUM_RATE, 58 UNKNOWN_COST 59 }; 60 61 // Check whether a short number is a possible number when dialled from a 62 // region, given the number in the form of a string, and the region where the 63 // number is dialed from. This provides a more lenient check than 64 // IsValidShortNumberForRegion. 65 bool IsPossibleShortNumberForRegion( 66 const PhoneNumber& short_number, 67 const string& region_dialing_from) const; 68 69 // Check whether a short number is a possible number. If a country calling 70 // code is shared by multiple regions, this returns true if it's possible in 71 // any of them. This provides a more lenient check than IsValidShortNumber. 72 // See IsPossibleShortNumberForRegion for details. 73 bool IsPossibleShortNumber(const PhoneNumber& number) const; 74 75 // Tests whether a short number matches a valid pattern in a region. Note 76 // that this doesn't verify the number is actually in use, which is 77 // impossible to tell by just looking at the number itself. 78 bool IsValidShortNumberForRegion( 79 const PhoneNumber& short_number, 80 const string& region_dialing_from) const; 81 82 // Tests whether a short number matches a valid pattern. If a country calling 83 // code is shared by multiple regions, this returns true if it's valid in any 84 // of them. Note that this doesn't verify the number is actually in use, 85 // which is impossible to tell by just looking at the number itself. See 86 // IsValidShortNumberForRegion for details. 87 bool IsValidShortNumber(const PhoneNumber& number) const; 88 89 // Gets the expected cost category of a short number when dialled from a 90 // region (however, nothing is implied about its validity). If it is 91 // important that the number is valid, then its validity must first be 92 // checked using IsValidShortNumberForRegion. Note that emergency numbers are 93 // always considered toll-free. Example usage: 94 // 95 // PhoneNumber number; 96 // phone_util.Parse("110", "US", &number); 97 // ... 98 // string region_code("CA"); 99 // ShortNumberInfo short_info; 100 // if (short_info.IsValidShortNumberForRegion(number, region_code)) { 101 // ShortNumberInfo::ShortNumberCost cost = 102 // short_info.GetExpectedCostForRegion(number, region_code); 103 // // Do something with the cost information here. 104 // } 105 ShortNumberCost GetExpectedCostForRegion( 106 const PhoneNumber& short_number, 107 const string& region_dialing_from) const; 108 109 // Gets the expected cost category of a short number (however, nothing is 110 // implied about its validity). If the country calling code is unique to a 111 // region, this method behaves exactly the same as GetExpectedCostForRegion. 112 // However, if the country calling code is shared by multiple regions, then 113 // it returns the highest cost in the sequence PREMIUM_RATE, UNKNOWN_COST, 114 // STANDARD_RATE, TOLL_FREE. The reason for the position of UNKNOWN_COST in 115 // this order is that if a number is UNKNOWN_COST in one region but 116 // STANDARD_RATE or TOLL_FREE in another, its expected cost cannot be 117 // estimated as one of the latter since it might be a PREMIUM_RATE number. 118 // 119 // For example, if a number is STANDARD_RATE in the US, but TOLL_FREE in 120 // Canada, the expected cost returned by this method will be STANDARD_RATE, 121 // since the NANPA countries share the same country calling code. 122 // 123 // Note: If the region from which the number is dialed is known, it is highly 124 // preferable to call GetExpectedCostForRegion instead. 125 ShortNumberCost GetExpectedCost(const PhoneNumber& number) const; 126 127 // Gets a valid short number for the specified region. 128 string GetExampleShortNumber(const string& region_code) const; 129 130 // Gets a valid short number for the specified cost category. 131 string GetExampleShortNumberForCost(const string& region_code, 132 ShortNumberCost cost) const; 133 134 // Returns true if the number might be used to connect to an emergency service 135 // in the given region. 136 // 137 // This method takes into account cases where the number might contain 138 // formatting, or might have additional digits appended (when it is okay to do 139 // that in the region specified). 140 bool ConnectsToEmergencyNumber(const string& number, 141 const string& region_code) const; 142 143 // Returns true if the number exactly matches an emergency service number in 144 // the given region. 145 // 146 // This method takes into account cases where the number might contain 147 // formatting, but doesn't allow additional digits to be appended. 148 bool IsEmergencyNumber(const string& number, 149 const string& region_code) const; 150 151 // Given a valid short number, determines whether it is carrier-specific 152 // (however, nothing is implied about its validity). Carrier-specific numbers 153 // may connect to a different end-point, or not connect at all, depending on 154 // the user's carrier. If it is important that the number is valid, then its 155 // validity must first be checked using IsValidShortNumber or 156 // IsValidShortNumberForRegion. 157 bool IsCarrierSpecific(const PhoneNumber& number) const; 158 159 // Given a valid short number, determines whether it is carrier-specific when 160 // dialed from the given region (however, nothing is implied about its 161 // validity). Carrier-specific numbers may connect to a different end-point, 162 // or not connect at all, depending on the user's carrier. If it is important 163 // that the number is valid, then its validity must first be checked using 164 // IsValidShortNumber or IsValidShortNumberForRegion. Returns false if the 165 // number doesn't match the region provided. 166 bool IsCarrierSpecificForRegion( 167 const PhoneNumber& number, 168 const string& region_dialing_from) const; 169 170 // Given a valid short number, determines whether it is an SMS service 171 // (however, nothing is implied about its validity). An SMS service is where 172 // the primary or only intended usage is to receive and/or send text messages 173 // (SMSs). This includes MMS as MMS numbers downgrade to SMS if the other 174 // party isn't MMS-capable. If it is important that the number is valid, then 175 // its validity must first be checked using IsValidShortNumber or 176 // IsValidShortNumberForRegion. Returns false if the number doesn't match the 177 // region provided. 178 bool IsSmsServiceForRegion( 179 const PhoneNumber& number, 180 const string& region_dialing_from) const; 181 182 private: 183 const PhoneNumberUtil& phone_util_; 184 const scoped_ptr<const MatcherApi> matcher_api_; 185 186 // A mapping from a RegionCode to the PhoneMetadata for that region. 187 scoped_ptr<std::map<string, PhoneMetadata> > 188 region_to_short_metadata_map_; 189 190 // In these countries, if extra digits are added to an emergency number, it no 191 // longer connects to the emergency service. 192 scoped_ptr<std::set<string> > 193 regions_where_emergency_numbers_must_be_exact_; 194 195 const i18n::phonenumbers::PhoneMetadata* GetMetadataForRegion( 196 const string& region_code) const; 197 198 bool RegionDialingFromMatchesNumber(const PhoneNumber& number, 199 const string& region_dialing_from) const; 200 201 // Helper method to get the region code for a given phone number, from a list 202 // of possible region codes. If the list contains more than one region, the 203 // first region for which the number is valid is returned. 204 void GetRegionCodeForShortNumberFromRegionList( 205 const PhoneNumber& number, 206 const list<string>& region_codes, 207 string* region_code) const; 208 209 bool MatchesEmergencyNumberHelper(const string& number, 210 const string& region_code, 211 bool allow_prefix_match) const; 212 }; 213 214 } // namespace phonenumbers 215 } // namespace i18n 216 217 #endif // I18N_PHONENUMBERS_SHORTNUMBERINFO_H_ 218