Home | History | Annotate | Download | only in browser
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "components/autofill/core/browser/autofill_regexes.h"
      6 
      7 #include <map>
      8 #include <utility>
      9 
     10 #include "base/logging.h"
     11 #include "base/memory/scoped_ptr.h"
     12 #include "base/memory/singleton.h"
     13 #include "base/stl_util.h"
     14 #include "base/strings/string16.h"
     15 #include "third_party/icu/source/i18n/unicode/regex.h"
     16 
     17 namespace {
     18 
     19 // A singleton class that serves as a cache of compiled regex patterns.
     20 class AutofillRegexes {
     21  public:
     22   static AutofillRegexes* GetInstance();
     23 
     24   // Returns the compiled regex matcher corresponding to |pattern|.
     25   icu::RegexMatcher* GetMatcher(const base::string16& pattern);
     26 
     27  private:
     28   AutofillRegexes();
     29   ~AutofillRegexes();
     30   friend struct DefaultSingletonTraits<AutofillRegexes>;
     31 
     32   // Maps patterns to their corresponding regex matchers.
     33   std::map<base::string16, icu::RegexMatcher*> matchers_;
     34 
     35   DISALLOW_COPY_AND_ASSIGN(AutofillRegexes);
     36 };
     37 
     38 // static
     39 AutofillRegexes* AutofillRegexes::GetInstance() {
     40   return Singleton<AutofillRegexes>::get();
     41 }
     42 
     43 AutofillRegexes::AutofillRegexes() {
     44 }
     45 
     46 AutofillRegexes::~AutofillRegexes() {
     47   STLDeleteContainerPairSecondPointers(matchers_.begin(),
     48                                        matchers_.end());
     49 }
     50 
     51 icu::RegexMatcher* AutofillRegexes::GetMatcher(const base::string16& pattern) {
     52   if (!matchers_.count(pattern)) {
     53     const icu::UnicodeString icu_pattern(pattern.data(), pattern.length());
     54 
     55     UErrorCode status = U_ZERO_ERROR;
     56     icu::RegexMatcher* matcher = new icu::RegexMatcher(icu_pattern,
     57                                                        UREGEX_CASE_INSENSITIVE,
     58                                                        status);
     59     DCHECK(U_SUCCESS(status));
     60 
     61     matchers_.insert(std::make_pair(pattern, matcher));
     62   }
     63 
     64   return matchers_[pattern];
     65 }
     66 
     67 }  // namespace
     68 
     69 namespace autofill {
     70 
     71 bool MatchesPattern(const base::string16& input,
     72                     const base::string16& pattern) {
     73   icu::RegexMatcher* matcher =
     74       AutofillRegexes::GetInstance()->GetMatcher(pattern);
     75   icu::UnicodeString icu_input(input.data(), input.length());
     76   matcher->reset(icu_input);
     77 
     78   UErrorCode status = U_ZERO_ERROR;
     79   UBool match = matcher->find(0, status);
     80   DCHECK(U_SUCCESS(status));
     81   return !!match;
     82 }
     83 
     84 }  // namespace autofill
     85