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