private bool MatchesEmergencyNumberHelper(string number, string regionCode, bool allowPrefixMatch) { var possibleNumber = PhoneNumberUtil.ExtractPossibleNumber(number); if (PhoneNumberUtil.PlusCharsPattern.MatchBeginning(possibleNumber).Success) { // Returns false if the number starts with a plus sign. We don't believe dialing the country // code before emergency numbers (e.g. +1911) works, but later, if that proves to work, we can // add additional logic here to handle it. return(false); } var metadata = MetadataManager.GetShortNumberMetadataForRegion(regionCode); if (metadata == null || !metadata.HasEmergency) { return(false); } var normalizedNumber = PhoneNumberUtil.NormalizeDigitsOnly(possibleNumber); var allowPrefixMatchForRegion = allowPrefixMatch && !RegionsWhereEmergencyNumbersMustBeExact.Contains(regionCode); return(matcherApi.MatchNationalNumber(normalizedNumber, metadata.Emergency, allowPrefixMatchForRegion)); }
/// <summary> Helper method to get the region code for a given phone number, from a list of possible region /// codes. If the list Contains more than one region, the first region for which the number is /// valid is returned. /// </summary> private string GetRegionCodeForShortNumberFromRegionList(PhoneNumber number, List <string> regionCodes) { if (!regionCodes.Any()) { return(null); } else if (regionCodes.Count == 1) { return(regionCodes[0]); } var nationalNumber = GetNationalSignificantNumber(number); foreach (var regionCode in regionCodes) { var phoneMetadata = MetadataManager.GetShortNumberMetadataForRegion(regionCode); if (phoneMetadata != null && MatchesPossibleNumberAndNationalNumber(nationalNumber, phoneMetadata.ShortCode)) { // The number is valid for this region. return(regionCode); } } return(null); }
/// <summary> /// Gets a valid short number for the specified cost category. /// </summary> /// /// <param name="regionCode">the region for which an example short number is needed</param> /// <param name="cost">the cost category of number that is needed</param> /// <returns> a valid short number for the specified region and cost category. Returns an empty /// string when the metadata does not contain such information, or the cost is UNKNOWN_COST.</returns> internal string GetExampleShortNumberForCost(string regionCode, ShortNumberCost cost) { var phoneMetadata = MetadataManager.GetShortNumberMetadataForRegion(regionCode); if (phoneMetadata == null) { return(""); } PhoneNumberDesc desc = null; switch (cost) { case ShortNumberCost.TOLL_FREE: desc = phoneMetadata.TollFree; break; case ShortNumberCost.STANDARD_RATE: desc = phoneMetadata.StandardRate; break; case ShortNumberCost.PREMIUM_RATE: desc = phoneMetadata.PremiumRate; break; // UNKNOWN_COST numbers are computed by the process of elimination from the other cost // categories. } return(desc?.ExampleNumber ?? string.Empty); }
/// <summary> /// Tests whether a short number matches a valid pattern in a region. Note that this doesn't verify /// the number is actually in use, which is impossible to tell by just looking at the number itself. /// </summary> /// /// <param name="number">the short number for which we want to test the validity</param> /// <param name="regionDialingFrom">the region from which the number is dialed</param> /// <returns> whether the short number matches a valid pattern</returns> public bool IsValidShortNumberForRegion(PhoneNumber number, string regionDialingFrom) { if (!RegionDialingFromMatchesNumber(number, regionDialingFrom)) { return(false); } var phoneMetadata = MetadataManager.GetShortNumberMetadataForRegion(regionDialingFrom); if (phoneMetadata == null) { return(false); } var shortNumber = GetNationalSignificantNumber(number); var generalDesc = phoneMetadata.GeneralDesc; if (!MatchesPossibleNumberAndNationalNumber(shortNumber, generalDesc)) { return(false); } var shortNumberDesc = phoneMetadata.ShortCode; return(MatchesPossibleNumberAndNationalNumber(shortNumber, shortNumberDesc)); }
/// <summary> /// Given a valid short number, determines whether it is carrier-specific (however, nothing is /// implied about its validity). Carrier-specific numbers may connect to a different end-point, or /// not connect at all, depending on the user's carrier. If it is important that the number is /// valid, then its validity must first be checked using <see cref="IsValidShortNumber" /> or /// <see cerf="IsValidShortNumberForRegion" />. /// </summary> /// /// <param name="number"> the valid short number to check</param> /// <returns> whether the short number is carrier-specific, assuming the input was a valid short /// number</returns> public bool IsCarrierSpecific(PhoneNumber number) { var regionCodes = GetRegionCodesForCountryCode(number.CountryCode); var regionCode = GetRegionCodeForShortNumberFromRegionList(number, regionCodes); var nationalNumber = GetNationalSignificantNumber(number); var phoneMetadata = MetadataManager.GetShortNumberMetadataForRegion(regionCode); return(phoneMetadata != null && MatchesPossibleNumberAndNationalNumber(nationalNumber, phoneMetadata.CarrierSpecific)); }
/// <summary> /// Gets a valid short number for the specified region. /// </summary> /// <param name="regionCode">the region for which an example short number is needed</param> /// <returns> a valid short number for the specified region. Returns an empty string when the /// metadata does not contain such information.</returns> internal string GetExampleShortNumber(string regionCode) { var phoneMetadata = MetadataManager.GetShortNumberMetadataForRegion(regionCode); if (phoneMetadata == null) { return(""); } var desc = phoneMetadata.ShortCode; return(desc.ExampleNumber ?? string.Empty); }
/// <summary> /// Gets the expected cost category of a short number when dialed from a region (however, nothing /// is implied about its validity). If it is important that the number is valid, then its validity /// must first be checked using <see cref="IsValidShortNumberForRegion" />. Note that emergency numbers /// are always considered toll-free. Example usage: /// <code> /// // The region for which the number was parsed and the region we subsequently check against /// // need not be the same. Here we parse the number in the US and check it for Canada. /// PhoneNumber number = phoneUtil.parse("110", "US"); /// ... /// string regionCode = "CA"; /// ShortNumberInfo shortInfo = ShortNumberInfo.getInstance(); /// if (shortInfo.isValidShortNumberForRegion(shortNumber, regionCode)) { /// ShortNumberCost cost = shortInfo.getExpectedCostForRegion(number, regionCode); /// // Do something with the cost information here. /// }}</code> /// </summary> /// /// <param name="number">the short number for which we want to know the expected cost category </param> /// <param name="regionDialingFrom">the region from which the number is dialed</param> /// <returns> the expected cost category for that region of the short number. Returns UNKNOWN_COST if /// the number does not match a cost category. Note that an invalid number may match any cost /// category.</returns> public ShortNumberCost GetExpectedCostForRegion(PhoneNumber number, string regionDialingFrom) { if (!RegionDialingFromMatchesNumber(number, regionDialingFrom)) { return(ShortNumberCost.UNKNOWN_COST); } // Note that regionDialingFrom may be null, in which case phoneMetadata will also be null. var phoneMetadata = MetadataManager.GetShortNumberMetadataForRegion( regionDialingFrom); if (phoneMetadata == null) { return(ShortNumberCost.UNKNOWN_COST); } var shortNumber = GetNationalSignificantNumber(number); // The possible lengths are not present for a particular sub-type if they match the general // description; for this reason, we check the possible lengths against the general description // first to allow an early exit if possible. if (!phoneMetadata.GeneralDesc.PossibleLengthList.Contains(shortNumber.Length)) { return(ShortNumberCost.UNKNOWN_COST); } // The cost categories are tested in order of decreasing expense, since if for some reason the // patterns overlap the most expensive matching cost category should be returned. if (MatchesPossibleNumberAndNationalNumber(shortNumber, phoneMetadata.PremiumRate)) { return(ShortNumberCost.PREMIUM_RATE); } if (MatchesPossibleNumberAndNationalNumber(shortNumber, phoneMetadata.StandardRate)) { return(ShortNumberCost.STANDARD_RATE); } if (MatchesPossibleNumberAndNationalNumber(shortNumber, phoneMetadata.TollFree)) { return(ShortNumberCost.TOLL_FREE); } if (IsEmergencyNumber(shortNumber, regionDialingFrom)) { // Emergency numbers are implicitly toll-free. return(ShortNumberCost.TOLL_FREE); } return(ShortNumberCost.UNKNOWN_COST); }
/// <summary> /// Given a valid short number, determines whether it is an SMS service (however, nothing is /// implied about its validity). An SMS service is where the primary or only intended usage is to /// receive and/or send text messages (SMSs). This includes MMS as MMS numbers downgrade to SMS if /// the other party isn't MMS-capable. If it is important that the number is valid, then its /// validity must first be checked using <see cref="IsValidShortNumber" /> or /// <see cref="IsValidShortNumberForRegion" />. Returns false if the number doesn't match the region provided. /// </summary> /// /// <param name="number"> the valid short number to check</param> /// <param name="regionDialingFrom"> the region from which the number is dialed</param> /// <returns> whether the short number is an SMS service in the provided region, assuming the input /// was a valid short number</returns> public bool IsSmsServiceForRegion(PhoneNumber number, string regionDialingFrom) { if (!RegionDialingFromMatchesNumber(number, regionDialingFrom)) { return(false); } var phoneMetadata = MetadataManager.GetShortNumberMetadataForRegion(regionDialingFrom); return(phoneMetadata != null && MatchesPossibleNumberAndNationalNumber(GetNationalSignificantNumber(number), phoneMetadata.SmsServices)); }
/// <summary> /// Given a valid short number, determines whether it is carrier-specific when dialed from the /// given region (however, nothing is implied about its validity). Carrier-specific numbers may /// connect to a different end-point, or not connect at all, depending on the user's carrier. If /// it is important that the number is valid, then its validity must first be checked using /// <see cref="IsValidShortNumber" /> or <see cref="IsValidShortNumberForRegion" />. /// Returns false if the number doesn't match the region provided. /// </summary> /// /// <param name="number"> the valid short number to check</param> /// <param name="regionDialingFrom"> the region from which the number is dialed</param> /// <returns>whether the short number is carrier-specific in the provided region, assuming the /// input was a valid short number</returns> public bool IsCarrierSpecificForRegion(PhoneNumber number, string regionDialingFrom) { if (!RegionDialingFromMatchesNumber(number, regionDialingFrom)) { return(false); } var nationalNumber = GetNationalSignificantNumber(number); var phoneMetadata = MetadataManager.GetShortNumberMetadataForRegion(regionDialingFrom); return(phoneMetadata != null && MatchesPossibleNumberAndNationalNumber(nationalNumber, phoneMetadata.CarrierSpecific)); }
/** * Check whether a short number is a possible number when dialed from the given region. This * provides a more lenient check than {@link #isValidShortNumberForRegion}. * * @param number the short number to check * @param regionDialingFrom the region from which the number is dialed * @return whether the number is a possible short number */ public bool IsPossibleShortNumberForRegion(PhoneNumber number, String regionDialingFrom) { if (!RegionDialingFromMatchesNumber(number, regionDialingFrom)) { return(false); } PhoneMetadata phoneMetadata = MetadataManager.GetShortNumberMetadataForRegion(regionDialingFrom); if (phoneMetadata == null) { return(false); } int numberLength = GetNationalSignificantNumber(number).Length; return(phoneMetadata.GeneralDesc.PossibleLengthList.Contains(numberLength)); }
/** * Check whether a short number is a possible number. If a country calling code is shared by * multiple regions, this returns true if it's possible in any of them. This provides a more * lenient check than {@link #isValidShortNumber}. See {@link * #isPossibleShortNumberForRegion(PhoneNumber, String)} for details. * * @param number the short number to check * @return whether the number is a possible short number */ public bool IsPossibleShortNumber(PhoneNumber number) { List <string> regionCodes = GetRegionCodesForCountryCode(number.CountryCode); int shortNumberLength = GetNationalSignificantNumber(number).Length; foreach (string region in regionCodes) { PhoneMetadata phoneMetadata = MetadataManager.GetShortNumberMetadataForRegion(region); if (phoneMetadata == null) { continue; } if (phoneMetadata.GeneralDesc.PossibleLengthList.Contains(shortNumberLength)) { return(true); } } return(false); }