| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/browser/download/download_query.h" | 5 #include "chrome/browser/download/download_query.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <limits> | 10 #include <limits> |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 return false; | 63 return false; |
| 64 } | 64 } |
| 65 out->push_back(element); | 65 out->push_back(element); |
| 66 } | 66 } |
| 67 return true; | 67 return true; |
| 68 } | 68 } |
| 69 | 69 |
| 70 // The next several functions are helpers for making Callbacks that access | 70 // The next several functions are helpers for making Callbacks that access |
| 71 // DownloadItem fields. | 71 // DownloadItem fields. |
| 72 | 72 |
| 73 static int64_t GetStartTimeMsEpoch(const DownloadItem& item) { | 73 int64_t GetStartTimeMsEpoch(const DownloadItem& item) { |
| 74 return (item.GetStartTime() - base::Time::UnixEpoch()).InMilliseconds(); | 74 return (item.GetStartTime() - base::Time::UnixEpoch()).InMilliseconds(); |
| 75 } | 75 } |
| 76 | 76 |
| 77 static int64_t GetEndTimeMsEpoch(const DownloadItem& item) { | 77 int64_t GetEndTimeMsEpoch(const DownloadItem& item) { |
| 78 return (item.GetEndTime() - base::Time::UnixEpoch()).InMilliseconds(); | 78 return (item.GetEndTime() - base::Time::UnixEpoch()).InMilliseconds(); |
| 79 } | 79 } |
| 80 | 80 |
| 81 std::string TimeToISO8601(const base::Time& t) { | 81 std::string TimeToISO8601(const base::Time& t) { |
| 82 base::Time::Exploded exploded; | 82 base::Time::Exploded exploded; |
| 83 t.UTCExplode(&exploded); | 83 t.UTCExplode(&exploded); |
| 84 return base::StringPrintf( | 84 return base::StringPrintf( |
| 85 "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", exploded.year, exploded.month, | 85 "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", exploded.year, exploded.month, |
| 86 exploded.day_of_month, exploded.hour, exploded.minute, exploded.second, | 86 exploded.day_of_month, exploded.hour, exploded.minute, exploded.second, |
| 87 exploded.millisecond); | 87 exploded.millisecond); |
| 88 } | 88 } |
| 89 | 89 |
| 90 static std::string GetStartTime(const DownloadItem& item) { | 90 std::string GetStartTime(const DownloadItem& item) { |
| 91 return TimeToISO8601(item.GetStartTime()); | 91 return TimeToISO8601(item.GetStartTime()); |
| 92 } | 92 } |
| 93 | 93 |
| 94 static std::string GetEndTime(const DownloadItem& item) { | 94 std::string GetEndTime(const DownloadItem& item) { |
| 95 return TimeToISO8601(item.GetEndTime()); | 95 return TimeToISO8601(item.GetEndTime()); |
| 96 } | 96 } |
| 97 | 97 |
| 98 static bool GetDangerAccepted(const DownloadItem& item) { | 98 bool GetDangerAccepted(const DownloadItem& item) { |
| 99 return (item.GetDangerType() == | 99 return (item.GetDangerType() == |
| 100 content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED); | 100 content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED); |
| 101 } | 101 } |
| 102 | 102 |
| 103 static bool GetExists(const DownloadItem& item) { | 103 bool GetExists(const DownloadItem& item) { |
| 104 return !item.GetFileExternallyRemoved(); | 104 return !item.GetFileExternallyRemoved(); |
| 105 } | 105 } |
| 106 | 106 |
| 107 static base::string16 GetFilename(const DownloadItem& item) { | 107 base::string16 GetFilename(const DownloadItem& item) { |
| 108 // This filename will be compared with strings that could be passed in by the | 108 // This filename will be compared with strings that could be passed in by the |
| 109 // user, who only sees LossyDisplayNames. | 109 // user, who only sees LossyDisplayNames. |
| 110 return item.GetTargetFilePath().LossyDisplayName(); | 110 return item.GetTargetFilePath().LossyDisplayName(); |
| 111 } | 111 } |
| 112 | 112 |
| 113 static std::string GetFilenameUTF8(const DownloadItem& item) { | 113 std::string GetFilenameUTF8(const DownloadItem& item) { |
| 114 return base::UTF16ToUTF8(GetFilename(item)); | 114 return base::UTF16ToUTF8(GetFilename(item)); |
| 115 } | 115 } |
| 116 | 116 |
| 117 static std::string GetUrl(const DownloadItem& item) { | 117 std::string GetOriginalUrl(const DownloadItem& item) { |
| 118 return item.GetOriginalUrl().spec(); | 118 return item.GetOriginalUrl().spec(); |
| 119 } | 119 } |
| 120 | 120 |
| 121 static DownloadItem::DownloadState GetState(const DownloadItem& item) { | 121 std::string GetUrl(const DownloadItem& item) { |
| 122 return item.GetURL().spec(); |
| 123 } |
| 124 |
| 125 DownloadItem::DownloadState GetState(const DownloadItem& item) { |
| 122 return item.GetState(); | 126 return item.GetState(); |
| 123 } | 127 } |
| 124 | 128 |
| 125 static DownloadDangerType GetDangerType(const DownloadItem& item) { | 129 DownloadDangerType GetDangerType(const DownloadItem& item) { |
| 126 return item.GetDangerType(); | 130 return item.GetDangerType(); |
| 127 } | 131 } |
| 128 | 132 |
| 129 static double GetReceivedBytes(const DownloadItem& item) { | 133 double GetReceivedBytes(const DownloadItem& item) { |
| 130 return item.GetReceivedBytes(); | 134 return item.GetReceivedBytes(); |
| 131 } | 135 } |
| 132 | 136 |
| 133 static double GetTotalBytes(const DownloadItem& item) { | 137 double GetTotalBytes(const DownloadItem& item) { |
| 134 return item.GetTotalBytes(); | 138 return item.GetTotalBytes(); |
| 135 } | 139 } |
| 136 | 140 |
| 137 static std::string GetMimeType(const DownloadItem& item) { | 141 std::string GetMimeType(const DownloadItem& item) { |
| 138 return item.GetMimeType(); | 142 return item.GetMimeType(); |
| 139 } | 143 } |
| 140 | 144 |
| 141 static bool IsPaused(const DownloadItem& item) { | 145 bool IsPaused(const DownloadItem& item) { |
| 142 return item.IsPaused(); | 146 return item.IsPaused(); |
| 143 } | 147 } |
| 144 | 148 |
| 145 enum ComparisonType {LT, EQ, GT}; | 149 enum ComparisonType {LT, EQ, GT}; |
| 146 | 150 |
| 147 // Returns true if |item| matches the filter specified by |value|, |cmptype|, | 151 // Returns true if |item| matches the filter specified by |value|, |cmptype|, |
| 148 // and |accessor|. |accessor| is conceptually a function that takes a | 152 // and |accessor|. |accessor| is conceptually a function that takes a |
| 149 // DownloadItem and returns one of its fields, which is then compared to | 153 // DownloadItem and returns one of its fields, which is then compared to |
| 150 // |value|. | 154 // |value|. |
| 151 template<typename ValueType> | 155 template<typename ValueType> |
| 152 static bool FieldMatches( | 156 bool FieldMatches( |
| 153 const ValueType& value, | 157 const ValueType& value, |
| 154 ComparisonType cmptype, | 158 ComparisonType cmptype, |
| 155 const base::Callback<ValueType(const DownloadItem&)>& accessor, | 159 const base::Callback<ValueType(const DownloadItem&)>& accessor, |
| 156 const DownloadItem& item) { | 160 const DownloadItem& item) { |
| 157 switch (cmptype) { | 161 switch (cmptype) { |
| 158 case LT: return accessor.Run(item) < value; | 162 case LT: return accessor.Run(item) < value; |
| 159 case EQ: return accessor.Run(item) == value; | 163 case EQ: return accessor.Run(item) == value; |
| 160 case GT: return accessor.Run(item) > value; | 164 case GT: return accessor.Run(item) > value; |
| 161 } | 165 } |
| 162 NOTREACHED(); | 166 NOTREACHED(); |
| 163 return false; | 167 return false; |
| 164 } | 168 } |
| 165 | 169 |
| 166 // Helper for building a Callback to FieldMatches<>(). | 170 // Helper for building a Callback to FieldMatches<>(). |
| 167 template <typename ValueType> DownloadQuery::FilterCallback BuildFilter( | 171 template <typename ValueType> DownloadQuery::FilterCallback BuildFilter( |
| 168 const base::Value& value, ComparisonType cmptype, | 172 const base::Value& value, ComparisonType cmptype, |
| 169 ValueType (*accessor)(const DownloadItem&)) { | 173 ValueType (*accessor)(const DownloadItem&)) { |
| 170 ValueType cpp_value; | 174 ValueType cpp_value; |
| 171 if (!GetAs(value, &cpp_value)) return DownloadQuery::FilterCallback(); | 175 if (!GetAs(value, &cpp_value)) return DownloadQuery::FilterCallback(); |
| 172 return base::Bind(&FieldMatches<ValueType>, cpp_value, cmptype, | 176 return base::Bind(&FieldMatches<ValueType>, cpp_value, cmptype, |
| 173 base::Bind(accessor)); | 177 base::Bind(accessor)); |
| 174 } | 178 } |
| 175 | 179 |
| 176 // Returns true if |accessor.Run(item)| matches |pattern|. | 180 // Returns true if |accessor.Run(item)| matches |pattern|. |
| 177 static bool FindRegex( | 181 bool FindRegex( |
| 178 RE2* pattern, | 182 RE2* pattern, |
| 179 const base::Callback<std::string(const DownloadItem&)>& accessor, | 183 const base::Callback<std::string(const DownloadItem&)>& accessor, |
| 180 const DownloadItem& item) { | 184 const DownloadItem& item) { |
| 181 return RE2::PartialMatch(accessor.Run(item), *pattern); | 185 return RE2::PartialMatch(accessor.Run(item), *pattern); |
| 182 } | 186 } |
| 183 | 187 |
| 184 // Helper for building a Callback to FindRegex(). | 188 // Helper for building a Callback to FindRegex(). |
| 185 DownloadQuery::FilterCallback BuildRegexFilter( | 189 DownloadQuery::FilterCallback BuildRegexFilter( |
| 186 const base::Value& regex_value, | 190 const base::Value& regex_value, |
| 187 std::string (*accessor)(const DownloadItem&)) { | 191 std::string (*accessor)(const DownloadItem&)) { |
| 188 std::string regex_str; | 192 std::string regex_str; |
| 189 if (!GetAs(regex_value, ®ex_str)) return DownloadQuery::FilterCallback(); | 193 if (!GetAs(regex_value, ®ex_str)) return DownloadQuery::FilterCallback(); |
| 190 std::unique_ptr<RE2> pattern(new RE2(regex_str)); | 194 std::unique_ptr<RE2> pattern(new RE2(regex_str)); |
| 191 if (!pattern->ok()) return DownloadQuery::FilterCallback(); | 195 if (!pattern->ok()) return DownloadQuery::FilterCallback(); |
| 192 return base::Bind(&FindRegex, base::Owned(pattern.release()), | 196 return base::Bind(&FindRegex, base::Owned(pattern.release()), |
| 193 base::Bind(accessor)); | 197 base::Bind(accessor)); |
| 194 } | 198 } |
| 195 | 199 |
| 196 // Returns a ComparisonType to indicate whether a field in |left| is less than, | 200 // Returns a ComparisonType to indicate whether a field in |left| is less than, |
| 197 // greater than or equal to the same field in |right|. | 201 // greater than or equal to the same field in |right|. |
| 198 template<typename ValueType> | 202 template<typename ValueType> |
| 199 static ComparisonType Compare( | 203 ComparisonType Compare( |
| 200 const base::Callback<ValueType(const DownloadItem&)>& accessor, | 204 const base::Callback<ValueType(const DownloadItem&)>& accessor, |
| 201 const DownloadItem& left, const DownloadItem& right) { | 205 const DownloadItem& left, const DownloadItem& right) { |
| 202 ValueType left_value = accessor.Run(left); | 206 ValueType left_value = accessor.Run(left); |
| 203 ValueType right_value = accessor.Run(right); | 207 ValueType right_value = accessor.Run(right); |
| 204 if (left_value > right_value) return GT; | 208 if (left_value > right_value) return GT; |
| 205 if (left_value < right_value) return LT; | 209 if (left_value < right_value) return LT; |
| 206 DCHECK_EQ(left_value, right_value); | 210 DCHECK_EQ(left_value, right_value); |
| 207 return EQ; | 211 return EQ; |
| 208 } | 212 } |
| 209 | 213 |
| 210 } // anonymous namespace | 214 } // anonymous namespace |
| 211 | 215 |
| 212 // static | 216 // static |
| 213 bool DownloadQuery::MatchesQuery(const std::vector<base::string16>& query_terms, | 217 bool DownloadQuery::MatchesQuery(const std::vector<base::string16>& query_terms, |
| 214 const DownloadItem& item) { | 218 const DownloadItem& item) { |
| 215 if (query_terms.empty()) | 219 if (query_terms.empty()) |
| 216 return true; | 220 return true; |
| 217 | 221 |
| 218 base::string16 url_raw(base::UTF8ToUTF16(item.GetOriginalUrl().spec())); | 222 base::string16 original_url_raw( |
| 219 base::string16 url_formatted = url_raw; | 223 base::UTF8ToUTF16(item.GetOriginalUrl().spec())); |
| 220 if (item.GetBrowserContext()) | 224 base::string16 url_raw(base::UTF8ToUTF16(item.GetURL().spec())); |
| 221 url_formatted = url_formatter::FormatUrl(item.GetOriginalUrl()); | 225 // Try to also match query with above URLs formatted in user display friendly |
| 226 // way. This will unescape characters (including spaces) and trim all extra |
| 227 // data (like username and password) from raw url so that for example raw url |
| 228 // "http://some.server.org/example%20download/file.zip" will be matched with |
| 229 // search term "example download". |
| 230 base::string16 original_url_formatted( |
| 231 url_formatter::FormatUrl(item.GetOriginalUrl())); |
| 232 base::string16 url_formatted(url_formatter::FormatUrl(item.GetURL())); |
| 222 base::string16 path(item.GetTargetFilePath().LossyDisplayName()); | 233 base::string16 path(item.GetTargetFilePath().LossyDisplayName()); |
| 223 | 234 |
| 224 for (std::vector<base::string16>::const_iterator it = query_terms.begin(); | 235 for (std::vector<base::string16>::const_iterator it = query_terms.begin(); |
| 225 it != query_terms.end(); ++it) { | 236 it != query_terms.end(); ++it) { |
| 226 base::string16 term = base::i18n::ToLower(*it); | 237 base::string16 term = base::i18n::ToLower(*it); |
| 227 if (!base::i18n::StringSearchIgnoringCaseAndAccents( | 238 if (!base::i18n::StringSearchIgnoringCaseAndAccents( |
| 239 term, original_url_raw, NULL, NULL) && |
| 240 !base::i18n::StringSearchIgnoringCaseAndAccents( |
| 241 term, original_url_formatted, NULL, NULL) && |
| 242 !base::i18n::StringSearchIgnoringCaseAndAccents( |
| 228 term, url_raw, NULL, NULL) && | 243 term, url_raw, NULL, NULL) && |
| 229 !base::i18n::StringSearchIgnoringCaseAndAccents( | 244 !base::i18n::StringSearchIgnoringCaseAndAccents( |
| 230 term, url_formatted, NULL, NULL) && | 245 term, url_formatted, NULL, NULL) && |
| 231 !base::i18n::StringSearchIgnoringCaseAndAccents( | 246 !base::i18n::StringSearchIgnoringCaseAndAccents( |
| 232 term, path, NULL, NULL)) { | 247 term, path, NULL, NULL)) { |
| 233 return false; | 248 return false; |
| 234 } | 249 } |
| 235 } | 250 } |
| 236 return true; | 251 return true; |
| 237 } | 252 } |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 case FILTER_STARTED_BEFORE: | 309 case FILTER_STARTED_BEFORE: |
| 295 return AddFilter(BuildFilter<std::string>(value, LT, &GetStartTime)); | 310 return AddFilter(BuildFilter<std::string>(value, LT, &GetStartTime)); |
| 296 case FILTER_START_TIME: | 311 case FILTER_START_TIME: |
| 297 return AddFilter(BuildFilter<std::string>(value, EQ, &GetStartTime)); | 312 return AddFilter(BuildFilter<std::string>(value, EQ, &GetStartTime)); |
| 298 case FILTER_TOTAL_BYTES: | 313 case FILTER_TOTAL_BYTES: |
| 299 return AddFilter(BuildFilter<double>(value, EQ, &GetTotalBytes)); | 314 return AddFilter(BuildFilter<double>(value, EQ, &GetTotalBytes)); |
| 300 case FILTER_TOTAL_BYTES_GREATER: | 315 case FILTER_TOTAL_BYTES_GREATER: |
| 301 return AddFilter(BuildFilter<double>(value, GT, &GetTotalBytes)); | 316 return AddFilter(BuildFilter<double>(value, GT, &GetTotalBytes)); |
| 302 case FILTER_TOTAL_BYTES_LESS: | 317 case FILTER_TOTAL_BYTES_LESS: |
| 303 return AddFilter(BuildFilter<double>(value, LT, &GetTotalBytes)); | 318 return AddFilter(BuildFilter<double>(value, LT, &GetTotalBytes)); |
| 319 case FILTER_ORIGINAL_URL: |
| 320 return AddFilter(BuildFilter<std::string>(value, EQ, &GetOriginalUrl)); |
| 321 case FILTER_ORIGINAL_URL_REGEX: |
| 322 return AddFilter(BuildRegexFilter(value, &GetOriginalUrl)); |
| 304 case FILTER_URL: | 323 case FILTER_URL: |
| 305 return AddFilter(BuildFilter<std::string>(value, EQ, &GetUrl)); | 324 return AddFilter(BuildFilter<std::string>(value, EQ, &GetUrl)); |
| 306 case FILTER_URL_REGEX: | 325 case FILTER_URL_REGEX: |
| 307 return AddFilter(BuildRegexFilter(value, &GetUrl)); | 326 return AddFilter(BuildRegexFilter(value, &GetUrl)); |
| 308 } | 327 } |
| 309 return false; | 328 return false; |
| 310 } | 329 } |
| 311 | 330 |
| 312 bool DownloadQuery::Matches(const DownloadItem& item) const { | 331 bool DownloadQuery::Matches(const DownloadItem& item) const { |
| 313 for (FilterCallbackVector::const_iterator filter = filters_.begin(); | 332 for (FilterCallbackVector::const_iterator filter = filters_.begin(); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 384 void DownloadQuery::AddSorter(DownloadQuery::SortType type, | 403 void DownloadQuery::AddSorter(DownloadQuery::SortType type, |
| 385 DownloadQuery::SortDirection direction) { | 404 DownloadQuery::SortDirection direction) { |
| 386 switch (type) { | 405 switch (type) { |
| 387 case SORT_END_TIME: | 406 case SORT_END_TIME: |
| 388 sorters_.push_back(Sorter::Build<int64_t>(direction, &GetEndTimeMsEpoch)); | 407 sorters_.push_back(Sorter::Build<int64_t>(direction, &GetEndTimeMsEpoch)); |
| 389 break; | 408 break; |
| 390 case SORT_START_TIME: | 409 case SORT_START_TIME: |
| 391 sorters_.push_back( | 410 sorters_.push_back( |
| 392 Sorter::Build<int64_t>(direction, &GetStartTimeMsEpoch)); | 411 Sorter::Build<int64_t>(direction, &GetStartTimeMsEpoch)); |
| 393 break; | 412 break; |
| 413 case SORT_ORIGINAL_URL: |
| 414 sorters_.push_back( |
| 415 Sorter::Build<std::string>(direction, &GetOriginalUrl)); |
| 416 break; |
| 394 case SORT_URL: | 417 case SORT_URL: |
| 395 sorters_.push_back(Sorter::Build<std::string>(direction, &GetUrl)); | 418 sorters_.push_back(Sorter::Build<std::string>(direction, &GetUrl)); |
| 396 break; | 419 break; |
| 397 case SORT_FILENAME: | 420 case SORT_FILENAME: |
| 398 sorters_.push_back( | 421 sorters_.push_back( |
| 399 Sorter::Build<base::string16>(direction, &GetFilename)); | 422 Sorter::Build<base::string16>(direction, &GetFilename)); |
| 400 break; | 423 break; |
| 401 case SORT_DANGER: | 424 case SORT_DANGER: |
| 402 sorters_.push_back(Sorter::Build<DownloadDangerType>( | 425 sorters_.push_back(Sorter::Build<DownloadDangerType>( |
| 403 direction, &GetDangerType)); | 426 direction, &GetDangerType)); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 431 if (!sorters_.empty()) { | 454 if (!sorters_.empty()) { |
| 432 std::partial_sort(results->begin(), | 455 std::partial_sort(results->begin(), |
| 433 results->begin() + std::min(limit_, results->size()), | 456 results->begin() + std::min(limit_, results->size()), |
| 434 results->end(), | 457 results->end(), |
| 435 DownloadComparator(sorters_)); | 458 DownloadComparator(sorters_)); |
| 436 } | 459 } |
| 437 | 460 |
| 438 if (results->size() > limit_) | 461 if (results->size() > limit_) |
| 439 results->resize(limit_); | 462 results->resize(limit_); |
| 440 } | 463 } |
| OLD | NEW |