Browse Source

Adding implementations of PhoneNumberUtil.

pull/567/head
Philip Liard 15 years ago
committed by Mihaela Rosca
parent
commit
e0b6260361
7 changed files with 5593 additions and 3 deletions
  1. +63
    -0
      cpp/src/default_logger.cc
  2. +56
    -0
      cpp/src/default_logger.h
  3. +25
    -0
      cpp/src/logger_adapter.cc
  4. +48
    -0
      cpp/src/logger_adapter.h
  5. +2152
    -1
      cpp/src/phonenumberutil.cc
  6. +651
    -1
      cpp/src/phonenumberutil.h
  7. +2598
    -1
      cpp/src/phonenumberutil_test.cc

+ 63
- 0
cpp/src/default_logger.cc View File

@ -0,0 +1,63 @@
// Copyright (C) 2011 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Author: Philippe Liard
#include <iostream>
#include "default_logger.h"
using std::cerr;
using std::cout;
using std::endl;
namespace i18n {
namespace phonenumbers {
DefaultLogger::DefaultLogger(LogLevel level) : level_(level) {}
DefaultLogger::~DefaultLogger() {}
void DefaultLogger::Fatal(const string& msg) const {
if (level_ >= FATAL) {
cerr << "FATAL libphonenumber " << msg << endl;
}
}
void DefaultLogger::Error(const string& msg) const {
if (level_ >= ERROR) {
cerr << "ERROR libphonenumber " << msg << endl;
}
}
void DefaultLogger::Warning(const string& msg) const {
if (level_ >= WARNING) {
cerr << "WARNING libphonenumber " << msg << endl;
}
}
void DefaultLogger::Info(const string& msg) const {
if (level_ >= INFO) {
cout << "INFO libphonenumber " << msg << endl;
}
}
void DefaultLogger::Debug(const string& msg) const {
if (level_ >= DEBUG) {
cout << "DEBUG libphonenumber " << msg << endl;
}
}
} // namespace phonenumbers
} // namespace i18n

+ 56
- 0
cpp/src/default_logger.h View File

@ -0,0 +1,56 @@
// Copyright (C) 2011 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Author: Philippe Liard
#ifndef I18N_PHONENUMBERS_DEFAULT_LOGGER_H_
#define I18N_PHONENUMBERS_DEFAULT_LOGGER_H_
#include "logger_adapter.h"
namespace i18n {
namespace phonenumbers {
enum LogLevel {
FATAL,
ERROR,
WARNING,
INFO,
DEBUG,
};
class DefaultLogger : public LoggerAdapter {
public:
virtual ~DefaultLogger();
DefaultLogger(LogLevel level = WARNING);
virtual void Fatal(const string& msg) const;
virtual void Error(const string& msg) const;
virtual void Warning(const string& msg) const;
virtual void Info(const string& msg) const;
virtual void Debug(const string& msg) const;
private:
LogLevel level_;
};
} // namespace phonenumbers
} // namespace i18n
# endif // I18N_PHONENUMBERS_DEFAULT_LOGGER_H_

+ 25
- 0
cpp/src/logger_adapter.cc View File

@ -0,0 +1,25 @@
// Copyright (C) 2011 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Author: Philippe Liard
# include "logger_adapter.h"
namespace i18n {
namespace phonenumbers {
LoggerAdapter::~LoggerAdapter() {}
} // namespace phonenumbers
} // namespace i18n

+ 48
- 0
cpp/src/logger_adapter.h View File

@ -0,0 +1,48 @@
// Copyright (C) 2011 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Author: Philippe Liard
#ifndef I18N_PHONENUMBERS_LOGGER_ADAPTER_H_
#define I18N_PHONENUMBERS_LOGGER_ADAPTER_H_
#include <string>
using std::string;
namespace i18n {
namespace phonenumbers {
// Implement this 'interface' to override the way logging is handled
// in the library.
class LoggerAdapter {
public:
virtual ~LoggerAdapter();
// Logging methods
virtual void Fatal(const string& msg) const = 0;
virtual void Error(const string& msg) const = 0;
virtual void Warning(const string& msg) const = 0;
virtual void Info(const string& msg) const = 0;
virtual void Debug(const string& msg) const = 0;
};
} // namespace phonenumbers
} // namespace i18n
#endif // I18N_PHONENUMBERS_LOGGER_ADAPTER_H_

+ 2152
- 1
cpp/src/phonenumberutil.cc
File diff suppressed because it is too large
View File


+ 651
- 1
cpp/src/phonenumberutil.h View File

@ -1 +1,651 @@
// TODO
// Copyright (C) 2009 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Utility for international phone numbers.
//
// Author: Shaopeng Jia
// Open-sourced by: Philippe Liard
#ifndef I18N_PHONENUMBERS_PHONENUMBERUTIL_H_
#define I18N_PHONENUMBERS_PHONENUMBERUTIL_H_
#include <list>
#include <map>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "base/scoped_ptr.h"
#include "base/singleton.h"
#include "phonenumber.pb.h"
class TelephoneNumber;
namespace i18n {
namespace phonenumbers {
using std::list;
using std::map;
using std::pair;
using std::set;
using std::string;
using std::vector;
using google::protobuf::RepeatedPtrField;
class LoggerAdapter;
class NumberFormat;
class PhoneMetadata;
class PhoneMetadataCollection;
class PhoneNumber;
class PhoneNumberUtil {
friend struct DefaultSingletonTraits<PhoneNumberUtil>;
friend class PhoneNumberUtilTest;
public:
// INTERNATIONAL and NATIONAL formats are consistent with the definition
// in ITU-T Recommendation E. 123. For example, the number of the Google
// Zürich office will be written as "+41 44 668 1800" in INTERNATIONAL
// format, and as "044 668 1800" in NATIONAL format. E164 format is as per
// INTERNATIONAL format but with no formatting applied e.g. +41446681800.
enum PhoneNumberFormat {
E164,
INTERNATIONAL,
NATIONAL
};
// Type of phone numbers.
enum PhoneNumberType {
FIXED_LINE,
MOBILE,
// In some countries (e.g. the USA), it is impossible to distinguish between
// fixed-line and mobile numbers by looking at the phone number itself.
FIXED_LINE_OR_MOBILE,
// Freephone lines
TOLL_FREE,
PREMIUM_RATE,
// The cost of this call is shared between the caller and the recipient, and
// is hence typically less than PREMIUM_RATE calls. See
// http://en.wikipedia.org/wiki/Shared_Cost_Service for more information.
SHARED_COST,
// Voice over IP numbers. This includes TSoIP (Telephony Service over IP).
VOIP,
// A personal number is associated with a particular person, and may be
// routed to either a MOBILE or FIXED_LINE number. Some more information can
// be found here: http://en.wikipedia.org/wiki/Personal_Numbers
PERSONAL_NUMBER,
PAGER,
// Used for "Universal Access Numbers" or "Company Numbers". They may be
// further routed to specific offices, but allow one number to be used for a
// company.
UAN,
// A phone number is of type UNKNOWN when it does not fit any of the known
// patterns for a specific country.
UNKNOWN
};
// Types of phone number matches. See detailed description beside the
// IsNumberMatch() method.
enum MatchType {
INVALID_NUMBER, // NOT_A_NUMBER in the java version.
NO_MATCH,
SHORT_NSN_MATCH,
NSN_MATCH,
EXACT_MATCH,
};
enum ErrorType {
NO_ERROR,
INVALID_COUNTRY_CODE_ERROR, // INVALID_COUNTRY_CODE in the java version.
NOT_A_NUMBER,
TOO_SHORT_AFTER_IDD,
TOO_SHORT_NSN,
TOO_LONG_NSN, // TOO_LONG in the java version.
};
// Possible outcomes when testing if a PhoneNumber is possible.
enum ValidationResult {
IS_POSSIBLE,
INVALID_COUNTRY_CODE,
TOO_SHORT,
TOO_LONG,
};
// Gets a PhoneNumberUtil instance to carry out international phone number
// formatting, parsing, or validation. The instance is loaded with phone
// number metadata for a number of most commonly used countries/regions,
// as specified by DEFAULT_REGIONS_.
//
// The PhoneNumberUtil is implemented as a singleton. Therefore, calling
// getInstance multiple times will only result in one instance being created.
static PhoneNumberUtil* GetInstance();
// Check whether country_code represents the country calling code from a
// country whose national significant number could contain a leading zero. An
// example of such a country is Italy.
static bool IsLeadingZeroCountry(int country_code);
// Returns true if the number is a valid vanity (alpha) number such as 800
// MICROSOFT. A valid vanity number will start with at least 3 digits and will
// have three or more alpha characters. This does not do region-specific
// checks - to work out if this number is actually valid for a region, it
// should be parsed and methods such as IsPossibleNumberWithRegion or
// IsValidNumber should be used.
bool IsAlphaNumber(const string& number) const;
// Converts all alpha characters in a number to their respective digits on
// a keypad, but retains existing formatting.
void ConvertAlphaCharactersInNumber(string* number) const;
// Normalizes a string of characters representing a phone number. This
// converts wide-ascii and arabic-indic numerals to European numerals, and
// strips punctuation and alpha characters.
static void NormalizeDigitsOnly(string* number);
// Gets the national significant number of a phone number. Note a national
// significant number doesn't contain a national prefix or any formatting.
static void GetNationalSignificantNumber(const PhoneNumber& number,
string* national_significant_num);
// Gets the length of the geographical area code from the PhoneNumber object
// passed in, so that clients could use it to split a national significant
// number into geographical area code and subscriber number. It works in such
// a way that the resultant subscriber number should be diallable, at least on
// some devices. An example of how this could be used:
//
// const PhoneNumberUtil& phone_util(PhoneNumberUtil::GetInstance());
// PhoneNumber number;
// phone_util.Parse("16502530000", "US", &number);
// string national_significant_number;
// phone_util.GetNationalSignificantNumber(number,
// &national_significant_number);
// string area_code;
// string subscriber_number;
//
// int area_code_length = phone_util.GetLengthOfGeographicalAreaCode(number);
// if (area_code_length > 0) {
// area_code = national_significant_number.substring(0, area_code_length);
// subscriber_number = national_significant_number.substring(
// area_code_length, string::npos);
// else {
// area_code = "";
// subscriber_number = national_significant_number;
// }
//
// N.B.: area code is a very ambiguous concept, so the I18N team generally
// recommends against using it for most purposes, but recommends using the
// more general national_number instead. Read the following carefully before
// deciding to use this method:
//
// - geographical area codes change over time, and this method honors those
// changes; therefore, it doesn't guarantee the stability of the result it
// produces.
// - subscriber numbers may not be diallable from all devices (notably mobile
// devices, which typically requires the full national_number to be dialled
// in most countries).
// - most non-geographical numbers have no area codes.
// - some geographical numbers have no area codes.
int GetLengthOfGeographicalAreaCode(const PhoneNumber& number) const;
// Gets the length of the national destination code (NDC) from the PhoneNumber
// object passed in, so that clients could use it to split a national
// significant number into NDC and subscriber number. The NDC of a phone
// number is normally the first group of digit(s) right after the country code
// when the number is formatted in the international format, if there is a
// subscriber number part that follows. An example of how this could be used:
//
// const PhoneNumberUtil& phone_util(PhoneNumberUtil::GetInstance());
// PhoneNumber number;
// phone_util.Parse("16502530000", "US", &number);
// string national_significant_number;
// phone_util.GetNationalSignificantNumber(number,
// &national_significant_number);
// string national_destination_code;
// string subscriber_number;
//
// int national_destination_code_length =
// phone_util.GetLengthOfGeographicalAreaCode(number);
// if (national_destination_code_length > 0) {
// national_destination_code = national_significant_number.substring(
// 0, national_destination_code_length);
// subscriber_number = national_significant_number.substring(
// national_destination_code_length, string::npos);
// else {
// national_destination_code = "";
// subscriber_number = national_significant_number;
// }
//
// Refer to the unittests to see the difference between this function and
// GetLengthOfGeographicalAreaCode().
int GetLengthOfNationalDestinationCode(const PhoneNumber& number) const;
// Formats a phone number in the specified format using default rules. Note
// that this does not promise to produce a phone number that the user can
// dial from where they are - although we do format in either NATIONAL or
// INTERNATIONAL format depending on what the client asks for, we do not
// currently support a more abbreviated format, such as for users in the
// same area who could potentially dial the number without area code.
void Format(const PhoneNumber& number,
PhoneNumberFormat number_format,
string* formatted_number) const;
// Formats a phone number in the specified format using client-defined
// formatting rules.
void FormatByPattern(
const PhoneNumber& number,
PhoneNumberFormat number_format,
const RepeatedPtrField<NumberFormat>& user_defined_formats,
string* formatted_number) const;
// Formats a phone number in national format for dialing using the carrier as
// specified in the carrier_code. The carrier_code will always be used
// regardless of whether the phone number already has a preferred domestic
// carrier code stored. If carrier_code contains an empty string, return the
// number in national format without any carrier code.
void FormatNationalNumberWithCarrierCode(const PhoneNumber& number,
const string& carrier_code,
string* formatted_number) const;
// Formats a phone number in national format for dialing using the carrier as
// specified in the preferred_domestic_carrier_code field of the PhoneNumber
// object passed in. If that is missing, use the fallback_carrier_code passed
// in instead. If there is no preferred_domestic_carrier_code, and the
// fallback_carrier_code contains an empty string, return the number in
// national format without any carrier code.
//
// Use FormatNationalNumberWithCarrierCode instead if the carrier code passed
// in should take precedence over the number's preferred_domestic_carrier_code
// when formatting.
void FormatNationalNumberWithPreferredCarrierCode(
const PhoneNumber& number,
const string& fallback_carrier_code,
string* formatted_number) const;
// Formats a phone number for out-of-country dialing purpose.
// The calling_from parameter is an ISO 3166-1 two-letter country code string.
//
// Note this function takes care of the case for calling inside of NANPA
// and between Russia and Kazakhstan (who share the same country code).
// In those cases, no international prefix is used. For countries which
// have multiple international prefixes, the number in its INTERNATIONAL
// format will be returned instead.
void FormatOutOfCountryCallingNumber(
const PhoneNumber& number,
const string& calling_from,
string* formatted_number) const;
// Formats a phone number for out-of-country dialing purpose.
// The calling_from parameter is an ISO 3166-1 two-letter country code string.
//
// Note that in this version, if the number was entered originally using alpha
// characters and this version of the number is stored in raw_input, this
// representation of the number will be used rather than the digit
// representation. Grouping information as specified characters such as "-"
// and " " will be retained.
//
// Caveats:
// 1) This will not produce good results if the country code is both
// present in the raw input _and_ is the start of the national number. This
// is not a problem in the countries which typically use alpha numbers.
// 2) This will also not produce good results if the raw input has any
// grouping information within the first three digits of the national number,
// and if the function needs to strip preceding digits/words in the raw input
// before these digits. Normally people group the first three digits together
// so this is not a huge problem - and will be fixed if it proves to be so.
void FormatOutOfCountryKeepingAlphaChars(
const PhoneNumber& number,
const string& calling_from,
string* formatted_number) const;
// Attempts to extract a valid number from a phone number that is too long to
// be valid, and resets the PhoneNumber object passed in to that valid
// version. If no valid number could be extracted, the PhoneNumber object
// passed in will not be modified. It returns true if a valid phone number can
// be successfully extracted.
bool TruncateTooLongNumber(PhoneNumber* number) const;
// Gets the type of a phone number.
PhoneNumberType GetNumberType(const PhoneNumber& number) const;
// Tests whether a phone number matches a valid pattern. Note this doesn't
// verify the number is actually in use, which is impossible to tell by just
// looking at a number itself.
bool IsValidNumber(const PhoneNumber& number) const;
// Tests whether a phone number is valid for a certain region. Note this
// doesn't verify the number is actually in use, which is impossible to tell
// by just looking at a number itself. If the country calling code is not the
// same as the country code for the region, this immediately exits with false.
// After this, the specific number pattern rules for the region are examined.
// This is useful for determining for example whether a particular number is
// valid for Canada, rather than just a valid NANPA number.
//
// The region_code parameter is an ISO 3166-1 two-letter country code string.
bool IsValidNumberForRegion(
const PhoneNumber& number,
const string& region_code) const;
// Returns the country/region where a phone number is from. This could be
// used for geo-coding in the country/region level.
//
// The country/region is returned as an ISO 3166-1 two-letter country code
// string.
void GetRegionCodeForNumber(const PhoneNumber& number,
string* region_code) const;
// Returns the country calling code for a specific region. For example,
// this would be 1 for the United States, and 64 for New Zealand.
//
// The region_code parameter is an ISO 3166-1 two-letter country code string.
int GetCountryCodeForRegion(const string& region_code) const;
// Returns the region code that matches the specific country code. Note that
// it is possible that several regions share the same country code (e.g. US
// and Canada), and in that case, only one of the regions (normally the one
// with the largest population) is returned.
//
// The region code is returned as an ISO 3166-1 two-letter country code
// string.
void GetRegionCodeForCountryCode(int country_code, string* region_code) const;
// Check if a country is one of the countries under the North American
// Numbering Plan Administration (NANPA).
//
// The region_code parameter is an ISO 3166-1 two-letter country code string.
bool IsNANPACountry(const string& region_code) const;
// Check whether a phone number is a possible number. It provides a more
// lenient check than IsValidNumber() in the following sense:
// 1. It only checks the length of phone numbers. In particular, it doesn't
// check starting digits of the number.
// 2. It doesn't attempt to figure out the type of the number, but uses
// general rules which applies to all types of phone numbers in a
// country. Therefore, it is much faster than IsValidNumber().
// 3. For fixed line numbers, many countries have the concept of area code,
// which together with subscriber number constitute the national
// significant number. It is sometimes okay to dial the subscriber
// number only when dialing in the same area. This function will return
// true if the subscriber-number-only version is passed in. On the other
// hand, because IsValidNumber() validates using information on both
// starting digits (for fixed line numbers, that would most likely be
// area codes) and length (obviously includes the length of area codes
// for fixed line numbers), it will return false for the
// subscriber-number-only version.
ValidationResult IsPossibleNumberWithReason(const PhoneNumber& number) const;
// Convenience wrapper around IsPossibleNumberWithReason. Instead of returning
// the reason for failure, this method returns a boolean value.
bool IsPossibleNumber(const PhoneNumber& number) const;
// Check whether a phone number is a possible number given a number in the
// form of a string, and the country where the number could be dialed from.
// It provides a more lenient check than IsValidNumber(). See
// IsPossibleNumber(const PhoneNumber& number) for details.
//
// This method first parses the number, then invokes
// IsPossibleNumber(const PhoneNumber& number) with the resultant PhoneNumber
// object.
//
// countryDialingFrom represents the country that we are expecting the number
// to be dialed from. Note this is different from the country where the number
// belongs. For example, the number +1 650 253 0000 is a number that belongs
// to US. When written in this form, it could be dialed from any country. When
// it is written as 00 1 650 253 0000, it could be dialed from any country
// which uses an international dialling prefix of 00. When it is written as
// 650 253 0000, it could only be dialed from within the US, and when written
// as 253 0000, it could only be dialed from within a smaller area in the US
// (Mountain View, CA, to be more specific).
//
// The country_dialing_from parameter is an ISO 3166-1 two-letter country code
// string.
bool IsPossibleNumberForString(
const string& number,
const string& country_dialing_from) const;
// Gets a valid fixed-line number for the specified country. Returns false if
// the country was unknown.
//
// The region_code parameter is an ISO 3166-1 two-letter country code string.
bool GetExampleNumber(const string& region_code,
PhoneNumber* number) const;
// Gets a valid number of the specified type for the specified country.
// Returns false if the country was unknown or if no example number of that
// type could be found.
//
// The region_code parameter is an ISO 3166-1 two-letter country code string.
bool GetExampleNumberForType(const string& region_code,
PhoneNumberType type,
PhoneNumber* number) const;
// Parses a string and returns it in proto buffer format. This method will
// return an error like INVALID_COUNTRY_CODE if the number is not considered
// to be a possible number, and NO_ERROR if it parsed correctly. Note that
// validation of whether the number is actually a valid number for a
// particular country/region is not performed. This can be done separately
// with IsValidNumber().
//
// default_country represents the country that we are expecting the number to
// be from. This is only used if the number being parsed is not written in
// international format. The country code for the number in this case would
// be stored as that of the default country supplied. If the number is
// guaranteed to start with a '+' followed by the country code, then
// "ZZ" can be supplied.
//
// The default_country parameter is an ISO 3166-1 two-letter country code
// string.
ErrorType Parse(const string& number_to_parse,
const string& default_country,
PhoneNumber* number) const;
// Parses a string and returns it in proto buffer format. This method differs
// from Parse() in that it always populates the raw_input field of the
// protocol buffer with number_to_parse as well as the country_code_source
// field.
//
// The default_country parameter is an ISO 3166-1 two-letter country code
// string.
ErrorType ParseAndKeepRawInput(const string& number_to_parse,
const string& default_country,
PhoneNumber* number) const;
// Takes two phone numbers and compares them for equality.
//
// Returns EXACT_MATCH if the country code, NSN, presence of a leading zero
// for Italian numbers and any extension present are the same.
// Returns NSN_MATCH if either or both has no country specified, and the NSNs
// and extensions are the same.
// Returns SHORT_NSN_MATCH if either or both has no country specified, or the
// country specified is the same, and one NSN could be a shorter version of
// the other number. This includes the case where one has an extension
// specified, and the other does not. Returns NO_MATCH otherwise.
// For example, the numbers +1 345 657 1234 and 657 1234 are a
// SHORT_NSN_MATCH. The numbers +1 345 657 1234 and 345 657 are a NO_MATCH.
MatchType IsNumberMatch(const PhoneNumber& first_number,
const PhoneNumber& second_number) const;
// Takes two phone numbers as strings and compares them for equality. This
// is a convenience wrapper for IsNumberMatch(PhoneNumber firstNumber,
// PhoneNumber secondNumber). No default region is known.
// Returns INVALID_NUMBER if either number cannot be parsed into a phone
// number.
MatchType IsNumberMatchWithTwoStrings(const string& first_number,
const string& second_number) const;
// Takes two phone numbers and compares them for equality. This is a
// convenience wrapper for IsNumberMatch(PhoneNumber firstNumber,
// PhoneNumber secondNumber). No default region is known.
// Returns INVALID_NUMBER if second_number cannot be parsed into a phone
// number.
MatchType IsNumberMatchWithOneString(const PhoneNumber& first_number,
const string& second_number) const;
// Implement this 'interface' to override the way metadatas are fetched.
// Useful for testing injecting stable metadatas.
class MetadataProvider {
public:
virtual ~MetadataProvider() {}
// Returns a pair containing a pointer to the data and its size
virtual pair<const void*, unsigned> operator()() = 0;
};
// Override the default logging system. The provided adapter destruction is
// handled by this class (don't delete it).
static void SetLoggerAdapter(LoggerAdapter* logger_adapter);
friend bool ConvertFromTelephoneNumberProto(
const TelephoneNumber& proto_to_convert,
PhoneNumber* new_proto);
friend bool ConvertToTelephoneNumberProto(const PhoneNumber& proto_to_convert,
TelephoneNumber* resulting_proto);
private:
typedef pair<int, list<string>*> IntRegionsPair;
// The minimum and maximum length of the national significant number.
static const unsigned int kMinLengthForNsn = 3;
static const unsigned int kMaxLengthForNsn = 15;
// A mapping from a country code to a region code which denotes the
// country/region represented by that country code. Note countries under
// NANPA share the country code 1 and Russia and Kazakhstan share the country
// code 7. Under this map, 1 is mapped to region code "US" and 7 is mapped to
// region code "RU". This is implemented as a sorted vector to achieve better
// performance.
//
// Region codes are ISO 3166-1 two-letter country code strings.
scoped_ptr<vector<IntRegionsPair> > country_code_to_region_code_map_;
struct CompareFirst {
bool operator()(const IntRegionsPair& p1,
const IntRegionsPair& p2) const {
return p1.first < p2.first;
}
};
// The set of countries that share country code 1.
scoped_ptr<set<string> > nanpa_countries_;
static const int kNanpaCountryCode = 1;
// A mapping from a region code to a PhoneMetadata for that region. The map
// contains PhoneMetadata for the DEFAULT_REGIONS and countries/regions that
// have been recently used. This is like a cache for performance reasons.
//
// Region codes are ISO 3166-1 two-letter country code strings.
scoped_ptr<map<string, PhoneMetadata> > country_to_metadata_map_;
bool LoadMetadata(PhoneMetadataCollection* metadata,
MetadataProvider& provider);
explicit PhoneNumberUtil(MetadataProvider* provider = 0);
~PhoneNumberUtil();
// Helper function to check region code is not unknown or null.
//
// The region_code parameter is an ISO 3166-1 two-letter country code string.
bool IsValidRegionCode(const string& region_code) const;
// Helper function to check region code is not unknown. The country_code and
// number supplied is used only for the resultant log message.
//
// The region_code parameter is an ISO 3166-1 two-letter country code string.
bool HasValidRegionCode(const string& region_code,
int country_code,
const string& number) const;
// The region_code parameter is an ISO 3166-1 two-letter country code string.
const i18n::phonenumbers::PhoneMetadata* GetMetadataForRegion(
const string& region_code) const;
void GetRegionCodesForCountryCode(
int country_code,
list<string>* region_codes) const;
// Simple wrapper of FormatNationalNumberWithCarrier for the common case of
// no carrier code.
//
// The region_code parameter is an ISO 3166-1 two-letter country code string.
void FormatNationalNumber(const string& number,
const string& region_code,
PhoneNumberFormat number_format,
string* formatted_number) const;
// The region_code parameter is an ISO 3166-1 two-letter country code string.
void FormatNationalNumberWithCarrier(const string& number,
const string& region_code,
PhoneNumberFormat number_format,
const string& carrier_code,
string* formatted_number) const;
// The region_code parameter is an ISO 3166-1 two-letter country code string.
void MaybeGetFormattedExtension(
const PhoneNumber& number,
const string& region_code,
string* extension) const;
// The region_code parameter is an ISO 3166-1 two-letter country code string.
void FormatExtension(const string& extension_digits,
const string& region_code,
string* extension) const;
void GetRegionCodeForNumberFromRegionList(
const PhoneNumber& number,
const list<string>& region_codes,
string* region_code) const;
void Normalize(string* number) const;
PhoneNumber::CountryCodeSource MaybeStripInternationalPrefixAndNormalize(
const string& possible_idd_prefix,
string* number) const;
static void MaybeStripNationalPrefixAndCarrierCode(
const PhoneMetadata& metadata,
string* number,
string* carrier_code);
static void ExtractPossibleNumber(const string& number,
string* extracted_number);
static bool IsViablePhoneNumber(const string& number);
static bool MaybeStripExtension(string* number, string* extension);
int ExtractCountryCode(string* national_number) const;
ErrorType MaybeExtractCountryCode(
const PhoneMetadata* default_region_metadata,
bool keepRawInput,
string* national_number,
PhoneNumber* phone_number) const;
// The default_country parameter is an ISO 3166-1 two-letter country code
// string.
bool CheckRegionForParsing(
const string& number_to_parse,
const string& default_country) const;
// The default_country parameter is an ISO 3166-1 two-letter country code
// string.
ErrorType ParseHelper(const string& number_to_parse,
const string& default_country,
bool keep_raw_input,
bool check_region,
PhoneNumber* phone_number) const;
DISALLOW_COPY_AND_ASSIGN(PhoneNumberUtil);
};
} // namespace phonenumbers
} // namespace i18n
#endif // I18N_PHONENUMBERS_PHONENUMBERUTIL_H_

+ 2598
- 1
cpp/src/phonenumberutil_test.cc
File diff suppressed because it is too large
View File


Loading…
Cancel
Save