OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <algorithm> | 5 #include <algorithm> |
6 | 6 |
7 #include "chrome/browser/history/query_parser.h" | 7 #include "chrome/browser/history/query_parser.h" |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 virtual int AppendToSQLiteQuery(std::wstring* query) const; | 90 virtual int AppendToSQLiteQuery(std::wstring* query) const; |
91 virtual bool IsWord() const { return true; } | 91 virtual bool IsWord() const { return true; } |
92 | 92 |
93 const std::wstring& word() const { return word_; } | 93 const std::wstring& word() const { return word_; } |
94 void set_literal(bool literal) { literal_ = literal; } | 94 void set_literal(bool literal) { literal_ = literal; } |
95 | 95 |
96 virtual bool HasMatchIn(const std::vector<QueryWord>& words, | 96 virtual bool HasMatchIn(const std::vector<QueryWord>& words, |
97 Snippet::MatchPositions* match_positions) const; | 97 Snippet::MatchPositions* match_positions) const; |
98 | 98 |
99 virtual bool Matches(const std::wstring& word, bool exact) const; | 99 virtual bool Matches(const std::wstring& word, bool exact) const; |
| 100 virtual void AppendWords(std::vector<std::wstring>* words) const; |
100 | 101 |
101 private: | 102 private: |
102 std::wstring word_; | 103 std::wstring word_; |
103 bool literal_; | 104 bool literal_; |
104 }; | 105 }; |
105 | 106 |
106 bool QueryNodeWord::HasMatchIn(const std::vector<QueryWord>& words, | 107 bool QueryNodeWord::HasMatchIn(const std::vector<QueryWord>& words, |
107 Snippet::MatchPositions* match_positions) const { | 108 Snippet::MatchPositions* match_positions) const { |
108 for (size_t i = 0; i < words.size(); ++i) { | 109 for (size_t i = 0; i < words.size(); ++i) { |
109 if (Matches(words[i].word, false)) { | 110 if (Matches(words[i].word, false)) { |
110 size_t match_start = words[i].position; | 111 size_t match_start = words[i].position; |
111 match_positions->push_back( | 112 match_positions->push_back( |
112 Snippet::MatchPosition(match_start, | 113 Snippet::MatchPosition(match_start, |
113 match_start + static_cast<int>(word_.size()))); | 114 match_start + static_cast<int>(word_.size()))); |
114 return true; | 115 return true; |
115 } | 116 } |
116 } | 117 } |
117 return false; | 118 return false; |
118 } | 119 } |
119 | 120 |
120 bool QueryNodeWord::Matches(const std::wstring& word, bool exact) const { | 121 bool QueryNodeWord::Matches(const std::wstring& word, bool exact) const { |
121 if (exact || !IsWordLongEnoughForPrefixSearch(word_)) | 122 if (exact || !IsWordLongEnoughForPrefixSearch(word_)) |
122 return word == word_; | 123 return word == word_; |
123 return word.size() >= word_.size() && | 124 return word.size() >= word_.size() && |
124 (word_.compare(0, word_.size(), word, 0, word_.size()) == 0); | 125 (word_.compare(0, word_.size(), word, 0, word_.size()) == 0); |
125 } | 126 } |
126 | 127 |
| 128 void QueryNodeWord::AppendWords(std::vector<std::wstring>* words) const { |
| 129 words->push_back(word_); |
| 130 } |
| 131 |
127 int QueryNodeWord::AppendToSQLiteQuery(std::wstring* query) const { | 132 int QueryNodeWord::AppendToSQLiteQuery(std::wstring* query) const { |
128 query->append(word_); | 133 query->append(word_); |
129 | 134 |
130 // Use prefix search if we're not literal and long enough. | 135 // Use prefix search if we're not literal and long enough. |
131 if (!literal_ && IsWordLongEnoughForPrefixSearch(word_)) | 136 if (!literal_ && IsWordLongEnoughForPrefixSearch(word_)) |
132 *query += L'*'; | 137 *query += L'*'; |
133 return 1; | 138 return 1; |
134 } | 139 } |
135 | 140 |
136 // A QueryNodeList has a collection of child QueryNodes | 141 // A QueryNodeList has a collection of child QueryNodes |
(...skipping 18 matching lines...) Expand all Loading... |
155 // QueryNodeList is never used with Matches or HasMatchIn. | 160 // QueryNodeList is never used with Matches or HasMatchIn. |
156 virtual bool Matches(const std::wstring& word, bool exact) const { | 161 virtual bool Matches(const std::wstring& word, bool exact) const { |
157 NOTREACHED(); | 162 NOTREACHED(); |
158 return false; | 163 return false; |
159 } | 164 } |
160 virtual bool HasMatchIn(const std::vector<QueryWord>& words, | 165 virtual bool HasMatchIn(const std::vector<QueryWord>& words, |
161 Snippet::MatchPositions* match_positions) const { | 166 Snippet::MatchPositions* match_positions) const { |
162 NOTREACHED(); | 167 NOTREACHED(); |
163 return false; | 168 return false; |
164 } | 169 } |
| 170 virtual void AppendWords(std::vector<std::wstring>* words) const; |
165 | 171 |
166 protected: | 172 protected: |
167 int AppendChildrenToString(std::wstring* query) const; | 173 int AppendChildrenToString(std::wstring* query) const; |
168 | 174 |
169 QueryNodeVector children_; | 175 QueryNodeVector children_; |
170 }; | 176 }; |
171 | 177 |
172 QueryNodeList::~QueryNodeList() { | 178 QueryNodeList::~QueryNodeList() { |
173 for (QueryNodeVector::iterator node = children_.begin(); | 179 for (QueryNodeVector::iterator node = children_.begin(); |
174 node != children_.end(); ++node) | 180 node != children_.end(); ++node) |
175 delete *node; | 181 delete *node; |
176 } | 182 } |
177 | 183 |
| 184 void QueryNodeList::RemoveEmptySubnodes() { |
| 185 for (size_t i = 0; i < children_.size(); ++i) { |
| 186 if (children_[i]->IsWord()) |
| 187 continue; |
| 188 |
| 189 QueryNodeList* list_node = static_cast<QueryNodeList*>(children_[i]); |
| 190 list_node->RemoveEmptySubnodes(); |
| 191 if (list_node->children()->empty()) { |
| 192 children_.erase(children_.begin() + i); |
| 193 --i; |
| 194 delete list_node; |
| 195 } |
| 196 } |
| 197 } |
| 198 |
| 199 void QueryNodeList::AppendWords(std::vector<std::wstring>* words) const { |
| 200 for (size_t i = 0; i < children_.size(); ++i) |
| 201 children_[i]->AppendWords(words); |
| 202 } |
| 203 |
178 int QueryNodeList::AppendChildrenToString(std::wstring* query) const { | 204 int QueryNodeList::AppendChildrenToString(std::wstring* query) const { |
179 int num_words = 0; | 205 int num_words = 0; |
180 for (QueryNodeVector::const_iterator node = children_.begin(); | 206 for (QueryNodeVector::const_iterator node = children_.begin(); |
181 node != children_.end(); ++node) { | 207 node != children_.end(); ++node) { |
182 if (node != children_.begin()) | 208 if (node != children_.begin()) |
183 query->push_back(L' '); | 209 query->push_back(L' '); |
184 num_words += (*node)->AppendToSQLiteQuery(query); | 210 num_words += (*node)->AppendToSQLiteQuery(query); |
185 } | 211 } |
186 return num_words; | 212 return num_words; |
187 } | 213 } |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
252 return root.AppendToSQLiteQuery(sqlite_query); | 278 return root.AppendToSQLiteQuery(sqlite_query); |
253 } | 279 } |
254 | 280 |
255 void QueryParser::ParseQuery(const std::wstring& query, | 281 void QueryParser::ParseQuery(const std::wstring& query, |
256 std::vector<QueryNode*>* nodes) { | 282 std::vector<QueryNode*>* nodes) { |
257 QueryNodeList root; | 283 QueryNodeList root; |
258 if (ParseQueryImpl(l10n_util::ToLower(query), &root)) | 284 if (ParseQueryImpl(l10n_util::ToLower(query), &root)) |
259 nodes->swap(*root.children()); | 285 nodes->swap(*root.children()); |
260 } | 286 } |
261 | 287 |
| 288 |
| 289 void QueryParser::ExtractQueryWords(const std::wstring& query, |
| 290 std::vector<std::wstring>* words) { |
| 291 QueryNodeList root; |
| 292 if (!ParseQueryImpl(query, &root)) |
| 293 return; |
| 294 root.AppendWords(words); |
| 295 } |
| 296 |
262 bool QueryParser::DoesQueryMatch(const std::wstring& text, | 297 bool QueryParser::DoesQueryMatch(const std::wstring& text, |
263 const std::vector<QueryNode*>& query_nodes, | 298 const std::vector<QueryNode*>& query_nodes, |
264 Snippet::MatchPositions* match_positions) { | 299 Snippet::MatchPositions* match_positions) { |
265 if (query_nodes.empty()) | 300 if (query_nodes.empty()) |
266 return false; | 301 return false; |
267 | 302 |
268 std::vector<QueryWord> query_words; | 303 std::vector<QueryWord> query_words; |
269 ExtractQueryWords(l10n_util::ToLower(text), &query_words); | 304 ExtractQueryWords(l10n_util::ToLower(text), &query_words); |
270 | 305 |
271 if (query_words.empty()) | 306 if (query_words.empty()) |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 if (iter.IsWord()) { | 373 if (iter.IsWord()) { |
339 std::wstring word = iter.GetWord(); | 374 std::wstring word = iter.GetWord(); |
340 if (!word.empty()) { | 375 if (!word.empty()) { |
341 words->push_back(QueryWord()); | 376 words->push_back(QueryWord()); |
342 words->back().word = word; | 377 words->back().word = word; |
343 words->back().position = iter.prev(); | 378 words->back().position = iter.prev(); |
344 } | 379 } |
345 } | 380 } |
346 } | 381 } |
347 } | 382 } |
348 | |
349 void QueryNodeList::RemoveEmptySubnodes() { | |
350 for (size_t i = 0; i < children_.size(); ++i) { | |
351 if (children_[i]->IsWord()) | |
352 continue; | |
353 | |
354 QueryNodeList* list_node = static_cast<QueryNodeList*>(children_[i]); | |
355 list_node->RemoveEmptySubnodes(); | |
356 if (list_node->children()->empty()) { | |
357 children_.erase(children_.begin() + i); | |
358 --i; | |
359 delete list_node; | |
360 } | |
361 } | |
362 } | |
OLD | NEW |