| 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 |