autofill_regexes.cc revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
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/public/i18n/unicode/regex.h"
16
17namespace {
18
19// A singleton class that serves as a cache of compiled regex patterns.
20class 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
39AutofillRegexes* AutofillRegexes::GetInstance() {
40  return Singleton<AutofillRegexes>::get();
41}
42
43AutofillRegexes::AutofillRegexes() {
44}
45
46AutofillRegexes::~AutofillRegexes() {
47  STLDeleteContainerPairSecondPointers(matchers_.begin(),
48                                       matchers_.end());
49}
50
51icu::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
69namespace autofill {
70
71bool 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