/**
  * Helper method to get the national-number part of a number, formatted without any national
  * prefix, and return it as a set of digit blocks that would be formatted together.
  */
 private static String[] GetNationalNumberGroups(PhoneNumberUtil util, PhoneNumber number,
                                                 NumberFormat formattingPattern)
 {
     if (formattingPattern == null)
     {
         // This will be in the format +CC-DG;ext=EXT where DG represents groups of digits.
         String rfc3966Format = util.Format(number, PhoneNumberFormat.RFC3966);
         // We remove the extension part from the formatted string before splitting it into different
         // groups.
         int endIndex = rfc3966Format.IndexOf(';');
         if (endIndex < 0)
         {
             endIndex = rfc3966Format.Length;
         }
         // The country-code will have a '-' following it.
         int startIndex = rfc3966Format.IndexOf('-') + 1;
         return(rfc3966Format.Substring(startIndex, endIndex - startIndex).Split(new [] { '-' }));
     }
     else
     {
         // We format the NSN only, and split that according to the separator.
         String nationalSignificantNumber = util.GetNationalSignificantNumber(number);
         return(util.FormatNsnUsingPattern(nationalSignificantNumber,
                                           formattingPattern, PhoneNumberFormat.RFC3966).Split(new [] { '-' }));
     }
 }
示例#2
0
        /// <summary>
        /// Helper method to get the national-number part of a number, formatted without any national
        /// prefix, and return it as a set of digit blocks that should be formatted together according to
        /// the formatting pattern passed in.
        /// </summary>
        private static IList <string> GetNationalNumberGroups(PhoneNumberUtil util, PhoneNumber number,
                                                              NumberFormat formattingPattern)
        {
            // If a format is provided, we format the NSN only, and split that according to the separator.
            var nationalSignificantNumber = util.GetNationalSignificantNumber(number);

            return(util.FormatNsnUsingPattern(nationalSignificantNumber,
                                              formattingPattern, PhoneNumberFormat.RFC3966).Split('-'));
        }
示例#3
0
        /// <summary>
        /// Extracts the subscriber number
        /// </summary>
        /// <param name="parser">An instance of type <see cref="PhoneNumberUtil"/> to parse</param>
        /// <param name="parsedNumber">An instance of type <see cref="PhoneNumber"/> representing the parsed number</param>
        /// <returns>The subscriber number as <see cref="string"/></returns>
        private string GetSubscriberNumber(PhoneNumberUtil parser, PhoneNumber parsedNumber)
        {
            // Get the national relevant number and the length of the area code
            string nationalNumber = parser.GetNationalSignificantNumber(parsedNumber);
            int    areaCodeLength = parser.GetLengthOfGeographicalAreaCode(parsedNumber);

            // Get the substring of the national relevant number from the index of the length of the area code
            string subscriberNumber = nationalNumber.Substring(areaCodeLength);

            return(subscriberNumber);
        }
        public static bool IsNationalPrefixPresentIfRequired(PhoneNumber number, PhoneNumberUtil util)
        {
            // First, check how we deduced the country code. If it was written in international format, then
            // the national prefix is not required.
            if (number.CountryCodeSource != PhoneNumber.Types.CountryCodeSource.FROM_DEFAULT_COUNTRY)
            {
                return(true);
            }
            String phoneNumberRegion =
                util.GetRegionCodeForCountryCode(number.CountryCode);
            PhoneMetadata metadata = util.GetMetadataForRegion(phoneNumberRegion);

            if (metadata == null)
            {
                return(true);
            }
            // Check if a national prefix should be present when formatting this number.
            String       nationalNumber = util.GetNationalSignificantNumber(number);
            NumberFormat formatRule     =
                util.ChooseFormattingPatternForNumber(metadata.NumberFormatList, nationalNumber);

            // To do this, we check that a national prefix formatting rule was present and that it wasn't
            // just the first-group symbol ($1) with punctuation.
            if ((formatRule != null) && formatRule.NationalPrefixFormattingRule.Length > 0)
            {
                if (formatRule.NationalPrefixOptionalWhenFormatting)
                {
                    // The national-prefix is optional in these cases, so we don't need to check if it was
                    // present.
                    return(true);
                }
                // Remove the first-group symbol.
                String candidateNationalPrefixRule = formatRule.NationalPrefixFormattingRule;
                // We assume that the first-group symbol will never be _before_ the national prefix.
                candidateNationalPrefixRule =
                    candidateNationalPrefixRule.Substring(0, candidateNationalPrefixRule.IndexOf("${1}"));
                candidateNationalPrefixRule =
                    PhoneNumberUtil.NormalizeDigitsOnly(candidateNationalPrefixRule);
                if (candidateNationalPrefixRule.Length == 0)
                {
                    // National Prefix not needed for this number.
                    return(true);
                }
                // Normalize the remainder.
                String        rawInputCopy = PhoneNumberUtil.NormalizeDigitsOnly(number.RawInput);
                StringBuilder rawInput     = new StringBuilder(rawInputCopy);
                // Check if we found a national prefix and/or carrier code at the start of the raw input, and
                // return the result.
                return(util.MaybeStripNationalPrefixAndCarrierCode(rawInput, metadata, null));
            }
            return(true);
        }
示例#5
0
        public bool CheckNumberGroupingIsValid(
            PhoneNumber number, string candidate, PhoneNumberUtil util, CheckGroups checker)
        {
            // TODO: Evaluate how this works for other locales (testing has been limited to NANPA regions)
            // and optimise if necessary.
            var normalizedCandidate =
                PhoneNumberUtil.NormalizeDigits(new StringBuilder(candidate), true /* keep non-digits */);
            var formattedNumberGroups = GetNationalNumberGroups(util, number);

            if (checker(util, number, normalizedCandidate, formattedNumberGroups))
            {
                return(true);
            }
            // If this didn't pass, see if there are any alternate formats that match, and try them instead.
            var alternateFormats =
                MetadataManager.GetAlternateFormatsForCountry(number.CountryCode);
            var nationalSignificantNumber = util.GetNationalSignificantNumber(number);

            if (alternateFormats != null)
            {
                foreach (var alternateFormat in alternateFormats.NumberFormatList)
                {
                    if (alternateFormat.LeadingDigitsPatternCount > 0)
                    {
                        // There is only one leading digits pattern for alternate formats.
                        var pattern =
                            regexCache.GetPatternForRegex(alternateFormat.GetLeadingDigitsPattern(0));
                        if (!pattern.IsMatchBeginning(nationalSignificantNumber))
                        {
                            // Leading digits don't match; try another one.
                            continue;
                        }
                    }
                    formattedNumberGroups = GetNationalNumberGroups(util, number, alternateFormat);
                    if (checker(util, number, normalizedCandidate, formattedNumberGroups))
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
        public static bool AllNumberGroupsRemainGrouped(PhoneNumberUtil util,
                                                        PhoneNumber number,
                                                        StringBuilder normalizedCandidate,
                                                        String[] formattedNumberGroups)
        {
            int fromIndex = 0;

            // Check each group of consecutive digits are not broken into separate groupings in the
            // {@code normalizedCandidate} string.
            for (int i = 0; i < formattedNumberGroups.Length; i++)
            {
                // Fails if the substring of {@code normalizedCandidate} starting from {@code fromIndex}
                // doesn't contain the consecutive digits in formattedNumberGroups[i].
                fromIndex = normalizedCandidate.ToString().IndexOf(formattedNumberGroups[i], fromIndex);
                if (fromIndex < 0)
                {
                    return(false);
                }
                // Moves {@code fromIndex} forward.
                fromIndex += formattedNumberGroups[i].Length;
                if (i == 0 && fromIndex < normalizedCandidate.Length)
                {
                    // We are at the position right after the NDC.
                    if (char.IsDigit(normalizedCandidate[fromIndex]))
                    {
                        // This means there is no formatting symbol after the NDC. In this case, we only
                        // accept the number if there is no formatting symbol at all in the number, except
                        // for extensions.
                        String nationalSignificantNumber = util.GetNationalSignificantNumber(number);
                        return(normalizedCandidate.ToString().Substring(fromIndex - formattedNumberGroups[i].Length)
                               .StartsWith(nationalSignificantNumber));
                    }
                }
            }
            // The check here makes sure that we haven't mistakenly already used the extension to
            // match the last group of the subscriber number. Note the extension cannot have
            // formatting in-between digits.
            return(normalizedCandidate.ToString().Substring(fromIndex).Contains(number.Extension));
        }
示例#7
0
        /**
         * Returns the description of the geographical area the {@code number} corresponds to. This method
         * distinguishes the case of an invalid prefix and a prefix for which the name is not available in
         * the current language. If the description is not available in the current language an empty
         * string is returned. If no description was found for the provided number, null is returned.
         *
         * @param number  the phone number to look up
         * @return  the description of the geographical area
         */
        public String Lookup(PhoneNumber number)
        {
            int numOfEntries = areaCodeMapStorage.getNumOfEntries();

            if (numOfEntries == 0)
            {
                return(null);
            }
            long phonePrefix =
                long.Parse(number.CountryCode + phoneUtil.GetNationalSignificantNumber(number));
            int        currentIndex        = numOfEntries - 1;
            List <int> currentSetOfLengths = areaCodeMapStorage.getPossibleLengths();
            var        length = currentSetOfLengths.Count;

            while (length > 0)
            {
                int    possibleLength = currentSetOfLengths[length - 1];
                String phonePrefixStr = phonePrefix.ToString();
                if (phonePrefixStr.Length > possibleLength)
                {
                    phonePrefix = long.Parse(phonePrefixStr.Substring(0, possibleLength));
                }
                currentIndex = binarySearch(0, currentIndex, phonePrefix);
                if (currentIndex < 0)
                {
                    return(null);
                }
                int currentPrefix = areaCodeMapStorage.getPrefix(currentIndex);
                if (phonePrefix == currentPrefix)
                {
                    return(areaCodeMapStorage.getDescription(currentIndex));
                }
                while (length > 0 && currentSetOfLengths[length - 1] >= possibleLength)
                {
                    length--;
                }
            }
            return(null);
        }
示例#8
0
        /// <summary>
        /// Retrieves the area code of parsed number
        /// </summary>
        /// <param name="parser">An instance of type <see cref="PhoneNumberUtil"/> representing the parser</param>
        /// <param name="parsedNumber">An instance of type <see cref="PhoneNumber"/> representing the parsed number</param>
        /// <param name="number">The raw number as <see cref="string"/></param>
        /// <returns></returns>
        private string GetAreaCode(PhoneNumberUtil parser, PhoneNumber parsedNumber, string number)
        {
            string areaCode;

            // Get length of area code and the national relevant part of the number
            int    areaCodeLength = parser.GetLengthOfGeographicalAreaCode(parsedNumber);
            string nationalNumber = parser.GetNationalSignificantNumber(parsedNumber);

            // Check if the number starts with "0"
            if (number.StartsWith("0"))
            {
                // Get the area code which starts with a "0"
                areaCode = $"0{nationalNumber.Substring(0, areaCodeLength)}";
            }
            else
            {
                // Get the area code which does not start with a "0"
                areaCode = nationalNumber.Substring(0, areaCodeLength);
            }

            return(areaCode);
        }
        public static bool AllNumberGroupsAreExactlyPresent(PhoneNumberUtil util,
                                                            PhoneNumber number,
                                                            StringBuilder normalizedCandidate,
                                                            String[] formattedNumberGroups)
        {
            String[] candidateGroups =
                PhoneNumberUtil.NON_DIGITS_PATTERN.Split(normalizedCandidate.ToString());
            // Set this to the last group, skipping it if the number has an extension.
            int candidateNumberGroupIndex =
                number.HasExtension ? candidateGroups.Length - 2 : candidateGroups.Length - 1;

            // First we check if the national significant number is formatted as a block.
            // We use contains and not equals, since the national significant number may be present with
            // a prefix such as a national number prefix, or the country code itself.
            if (candidateGroups.Length == 1 ||
                candidateGroups[candidateNumberGroupIndex].Contains(
                    util.GetNationalSignificantNumber(number)))
            {
                return(true);
            }
            // Starting from the end, go through in reverse, excluding the first group, and check the
            // candidate and number groups are the same.
            for (int formattedNumberGroupIndex = (formattedNumberGroups.Length - 1);
                 formattedNumberGroupIndex > 0 && candidateNumberGroupIndex >= 0;
                 formattedNumberGroupIndex--, candidateNumberGroupIndex--)
            {
                if (!candidateGroups[candidateNumberGroupIndex].Equals(
                        formattedNumberGroups[formattedNumberGroupIndex]))
                {
                    return(false);
                }
            }
            // Now check the first group. There may be a national prefix at the start, so we only check
            // that the candidate group ends with the formatted number group.
            return(candidateNumberGroupIndex >= 0 &&
                   candidateGroups[candidateNumberGroupIndex].EndsWith(formattedNumberGroups[0]));
        }