Upload upstream chromium 85.0.4183.84
[platform/framework/web/chromium-efl.git] / base / i18n / string_search.cc
1 // Copyright (c) 2011 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 <stdint.h>
6
7 #include "base/i18n/string_search.h"
8
9 #include "third_party/icu/source/i18n/unicode/usearch.h"
10
11 namespace base {
12 namespace i18n {
13
14 FixedPatternStringSearch::FixedPatternStringSearch(const string16& find_this,
15                                                    bool case_sensitive)
16     : find_this_(find_this) {
17   // usearch_open requires a valid string argument to be searched, even if we
18   // want to set it by usearch_setText afterwards. So, supplying a dummy text.
19   const string16& dummy = find_this_;
20
21   UErrorCode status = U_ZERO_ERROR;
22   search_ = usearch_open(find_this_.data(), find_this_.size(), dummy.data(),
23                          dummy.size(), uloc_getDefault(),
24                          nullptr,  // breakiter
25                          &status);
26   if (U_SUCCESS(status)) {
27     // http://icu-project.org/apiref/icu4c40/ucol_8h.html#6a967f36248b0a1bc7654f538ee8ba96
28     // Set comparison level to UCOL_PRIMARY to ignore secondary and tertiary
29     // differences. Set comparison level to UCOL_TERTIARY to include all
30     // comparison differences.
31     // Diacritical differences on the same base letter represent a
32     // secondary difference.
33     // Uppercase and lowercase versions of the same character represents a
34     // tertiary difference.
35     UCollator* collator = usearch_getCollator(search_);
36     ucol_setStrength(collator, case_sensitive ? UCOL_TERTIARY : UCOL_PRIMARY);
37     usearch_reset(search_);
38   }
39 }
40
41 FixedPatternStringSearch::~FixedPatternStringSearch() {
42   if (search_)
43     usearch_close(search_);
44 }
45
46 bool FixedPatternStringSearch::Search(const string16& in_this,
47                                       size_t* match_index,
48                                       size_t* match_length,
49                                       bool forward_search) {
50   UErrorCode status = U_ZERO_ERROR;
51   usearch_setText(search_, in_this.data(), in_this.size(), &status);
52
53   // Default to basic substring search if usearch fails. According to
54   // http://icu-project.org/apiref/icu4c/usearch_8h.html, usearch_open will fail
55   // if either |find_this| or |in_this| are empty. In either case basic
56   // substring search will give the correct return value.
57   if (!U_SUCCESS(status)) {
58     size_t index = in_this.find(find_this_);
59     if (index == string16::npos)
60       return false;
61     if (match_index)
62       *match_index = index;
63     if (match_length)
64       *match_length = find_this_.size();
65     return true;
66   }
67
68   int32_t index = forward_search ? usearch_first(search_, &status)
69                                  : usearch_last(search_, &status);
70   if (!U_SUCCESS(status) || index == USEARCH_DONE)
71     return false;
72   if (match_index)
73     *match_index = static_cast<size_t>(index);
74   if (match_length)
75     *match_length = static_cast<size_t>(usearch_getMatchedLength(search_));
76   return true;
77 }
78
79 FixedPatternStringSearchIgnoringCaseAndAccents::
80     FixedPatternStringSearchIgnoringCaseAndAccents(const string16& find_this)
81     : base_search_(find_this, /*case_sensitive=*/false) {}
82
83 bool FixedPatternStringSearchIgnoringCaseAndAccents::Search(
84     const string16& in_this,
85     size_t* match_index,
86     size_t* match_length) {
87   return base_search_.Search(in_this, match_index, match_length,
88                              /*forward_search=*/true);
89 }
90
91 bool StringSearchIgnoringCaseAndAccents(const string16& find_this,
92                                         const string16& in_this,
93                                         size_t* match_index,
94                                         size_t* match_length) {
95   return FixedPatternStringSearchIgnoringCaseAndAccents(find_this).Search(
96       in_this, match_index, match_length);
97 }
98
99 bool StringSearch(const string16& find_this,
100                   const string16& in_this,
101                   size_t* match_index,
102                   size_t* match_length,
103                   bool case_sensitive,
104                   bool forward_search) {
105   return FixedPatternStringSearch(find_this, case_sensitive)
106       .Search(in_this, match_index, match_length, forward_search);
107 }
108
109 }  // namespace i18n
110 }  // namespace base