summaryrefslogtreecommitdiff
path: root/asyoutypeformatter.h
diff options
context:
space:
mode:
Diffstat (limited to 'asyoutypeformatter.h')
-rw-r--r--asyoutypeformatter.h217
1 files changed, 217 insertions, 0 deletions
diff --git a/asyoutypeformatter.h b/asyoutypeformatter.h
new file mode 100644
index 0000000..0121f4f
--- /dev/null
+++ b/asyoutypeformatter.h
@@ -0,0 +1,217 @@
+// Copyright (C) 2011 The Libphonenumber Authors
+//
+// 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.
+
+// A formatter which formats phone numbers as they are entered.
+//
+// An AsYouTypeFormatter can be created by invoking the GetAsYouTypeFormatter
+// method of the PhoneNumberUtil. After that digits can be added by invoking the
+// InputDigit method on the formatter instance, and the partially formatted
+// phone number will be returned each time a digit is added. The Clear method
+// can be invoked before a new number needs to be formatted.
+//
+// See AYTF_US, AYTF_GBFixedLine and AYTF_DE test functions in
+// asyoutypeformatter_test.cc for more details on how the formatter is to be
+// used.
+//
+// This is a direct port from AsYouTypeFormatter.java. Changes to this class
+// should also happen to the Java version, whenever it makes sense.
+//
+// This class is NOT THREAD SAFE.
+
+#ifndef I18N_PHONENUMBERS_ASYOUTYPEFORMATTER_H_
+#define I18N_PHONENUMBERS_ASYOUTYPEFORMATTER_H_
+
+#include <list>
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "phonenumbers/regexp_adapter.h"
+#include "phonenumbers/regexp_cache.h"
+#include "phonenumbers/phonemetadata.pb.h"
+#include "phonenumbers/unicodestring.h"
+
+namespace i18n {
+namespace phonenumbers {
+
+using std::list;
+using std::string;
+
+class PhoneNumberUtil;
+
+class AsYouTypeFormatter {
+ public:
+ ~AsYouTypeFormatter() {}
+
+ // Formats a phone number on-the-fly as each digit is entered.
+ // next_char is the most recently entered digit of a phone number. Formatting
+ // characters are allowed, but as soon as they are encountered this method
+ // formats the number as entered and not "as you type" anymore. Full width
+ // digits and Arabic-indic digits are allowed, and will be shown as they are.
+ // Returns the partially formatted phone number (which is a reference to the
+ // given string parameter for convenience).
+ const string& InputDigit(char32 next_char, string* result);
+
+ // Same as InputDigit, but remembers the position where next_char is inserted,
+ // so that it could be retrieved later by using GetRememberedPosition(). The
+ // remembered position will be automatically adjusted if additional formatting
+ // characters are later inserted/removed in front of next_char.
+ // Returns the partially formatted phone number (which is a reference to the
+ // given string parameter for convenience).
+ const string& InputDigitAndRememberPosition(char32 next_char, string* result);
+
+ // Returns the current position in the partially formatted phone number of the
+ // character which was previously passed in as the parameter of
+ // InputDigitAndRememberPosition().
+ int GetRememberedPosition() const;
+
+ // Clears the internal state of the formatter, so it could be reused.
+ void Clear();
+
+ private:
+ // Constructs an as-you-type formatter. Should be obtained from
+ // PhoneNumberUtil::GetAsYouTypeFormatter().
+ explicit AsYouTypeFormatter(const string& region_code);
+
+ // Returns the metadata corresponding to the given region code or empty
+ // metadata if it is unsupported.
+ const PhoneMetadata* GetMetadataForRegion(const string& region_code) const;
+
+ // Returns true if a new template is created as opposed to reusing the
+ // existing template.
+ bool MaybeCreateNewTemplate();
+
+ void GetAvailableFormats(const string& leading_three_digits);
+
+ void NarrowDownPossibleFormats(const string& leading_digits);
+
+ bool CreateFormattingTemplate(const NumberFormat& format);
+
+ // Gets a formatting template which could be used to efficiently format a
+ // partial number where digits are added one by one.
+ void GetFormattingTemplate(const string& number_pattern,
+ const string& number_format,
+ UnicodeString* formatting_template);
+
+ void InputDigitWithOptionToRememberPosition(char32 next_char,
+ bool remember_position,
+ string* phone_number);
+
+ void AttemptToChoosePatternWithPrefixExtracted(string* formatted_number);
+
+ // Some national prefixes are a substring of others. If extracting the
+ // shorter NDD doesn't result in a number we can format, we try to see if we
+ // can extract a longer version here.
+ bool AbleToExtractLongerNdd();
+
+ void AttemptToFormatAccruedDigits(string* formatted_number);
+
+ // Attempts to set the formatting template and assigns the passed-in string
+ // parameter to the formatted version of the digits entered so far.
+ void AttemptToChooseFormattingPattern(string* formatted_number);
+
+ // Invokes InputDigitHelper on each digit of the national number accrued, and
+ // assigns the passed-in string parameter to a formatted string in the end.
+ void InputAccruedNationalNumber(string* number);
+
+ // Extracts the national prefix into national_prefix, or sets it to empty
+ // string if a national prefix is not present.
+ void RemoveNationalPrefixFromNationalNumber(string* national_prefix);
+
+ // Extracts IDD and plus sign to prefix_before_national_number_ when they are
+ // available, and places the remaining input into national_number_.
+ bool AttemptToExtractIdd();
+
+ // Extracts country code from the begining of national_number_ to
+ // prefix_before_national_number_ when they are available, and places the
+ // remaining input into national_number_.
+ // Returns true when a valid country code can be found.
+ bool AttemptToExtractCountryCode();
+
+ // Accrues digits and the plus sign to accrued_input_without_formatting for
+ // later use. If next_char contains a digit in non-ASCII format (e.g the
+ // full-width version of digits), it is first normalized to the ASCII
+ // version. The return value is next_char itself, or its normalized version,
+ // if next_char is a digit in non-ASCII format.
+ char NormalizeAndAccrueDigitsAndPlusSign(char32 next_char,
+ bool remember_position);
+
+ void InputDigitHelper(char next_char, string* number);
+
+ // Converts UnicodeString position to std::string position.
+ static int ConvertUnicodeStringPosition(const UnicodeString& s, int pos);
+
+ // Class attributes.
+ const scoped_ptr<const AbstractRegExpFactory> regexp_factory_;
+ RegExpCache regexp_cache_;
+
+ string current_output_;
+
+ UnicodeString formatting_template_;
+ string current_formatting_pattern_;
+
+ UnicodeString accrued_input_;
+ UnicodeString accrued_input_without_formatting_;
+
+ // This indicates whether AsYouTypeFormatter is currently doing the
+ // formatting.
+ bool able_to_format_;
+ // Set to true when users enter their own formatting. AsYouTypeFormatter will
+ // do no formatting at all when this is set to true.
+ bool input_has_formatting_;
+ bool is_international_formatting_;
+ bool is_expecting_country_code_;
+
+ const PhoneNumberUtil& phone_util_;
+
+ const string default_country_;
+
+ const PhoneMetadata empty_metadata_;
+ const PhoneMetadata* const default_metadata_;
+ const PhoneMetadata* current_metadata_;
+
+ int last_match_position_;
+
+ // The position of a digit upon which InputDigitAndRememberPosition is most
+ // recently invoked, as found in the original sequence of characters the user
+ // entered.
+ int original_position_;
+
+ // The position of a digit upon which InputDigitAndRememberPosition is most
+ // recently invoked, as found in AccruedInputWithoutFormatting.
+ int position_to_remember_;
+
+ // This contains anything that has been entered so far preceding the national
+ // significant number, and it is formatted (e.g. with space inserted). For
+ // example, this can contain IDD, country code, and/or NDD, etc.
+ string prefix_before_national_number_;
+ // This contains the national prefix that has been extracted. It contains only
+ // digits without formatting.
+ string national_prefix_extracted_;
+ string national_number_;
+
+ list<const NumberFormat*> possible_formats_;
+
+ friend class PhoneNumberUtil;
+ friend class AsYouTypeFormatterTest;
+
+ // Disallow copy and assign since this class uses RegExpCache which can't be
+ // copied.
+ DISALLOW_COPY_AND_ASSIGN(AsYouTypeFormatter);
+};
+
+} // namespace phonenumbers
+} // namespace i18n
+
+#endif // I18N_PHONENUMBERS_ASYOUTYPEFORMATTER_H_