15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/download/download_query.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/case_conversion.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/string_search.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/prefs/pref_service.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h" 22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/profiles/profile.h" 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/pref_names.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/content_browser_client.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/download_item.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h" 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "third_party/re2/re2/re2.h" 32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::DownloadDangerType; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::DownloadItem; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Templatized base::Value::GetAs*(). 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename T> bool GetAs(const base::Value& in, T* out); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<> bool GetAs(const base::Value& in, bool* out) { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return in.GetAsBoolean(out); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<> bool GetAs(const base::Value& in, int* out) { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return in.GetAsInteger(out); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<> bool GetAs(const base::Value& in, std::string* out) { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return in.GetAsString(out); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)template<> bool GetAs(const base::Value& in, base::string16* out) { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return in.GetAsString(out); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template<> bool GetAs(const base::Value& in, std::vector<base::string16>* out) { 54558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch out->clear(); 55558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch const base::ListValue* list = NULL; 56558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (!in.GetAsList(&list)) 57558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return false; 58558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch for (size_t i = 0; i < list->GetSize(); ++i) { 59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 element; 60558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (!list->GetString(i, &element)) { 61558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch out->clear(); 62558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return false; 63558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 64558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch out->push_back(element); 65558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 66558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return true; 67558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The next several functions are helpers for making Callbacks that access 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DownloadItem fields. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 72558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochstatic bool MatchesQuery( 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::vector<base::string16>& query_terms, 74558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch const DownloadItem& item) { 75558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch DCHECK(!query_terms.empty()); 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::string16 url_raw(base::UTF8ToUTF16(item.GetOriginalUrl().spec())); 77a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 url_formatted = url_raw; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (item.GetBrowserContext()) { 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Profile* profile = Profile::FromBrowserContext(item.GetBrowserContext()); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) url_formatted = net::FormatUrl( 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) item.GetOriginalUrl(), 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) profile->GetPrefs()->GetString(prefs::kAcceptLanguages)); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 path(item.GetTargetFilePath().LossyDisplayName()); 85558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (std::vector<base::string16>::const_iterator it = query_terms.begin(); 87558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch it != query_terms.end(); ++it) { 88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 term = base::i18n::ToLower(*it); 89558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (!base::i18n::StringSearchIgnoringCaseAndAccents( 90558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch term, url_raw, NULL, NULL) && 91558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch !base::i18n::StringSearchIgnoringCaseAndAccents( 92558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch term, url_formatted, NULL, NULL) && 93558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch !base::i18n::StringSearchIgnoringCaseAndAccents( 94558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch term, path, NULL, NULL)) { 95558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return false; 96558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 97558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch } 98558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return true; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int64 GetStartTimeMsEpoch(const DownloadItem& item) { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (item.GetStartTime() - base::Time::UnixEpoch()).InMilliseconds(); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static int64 GetEndTimeMsEpoch(const DownloadItem& item) { 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return (item.GetEndTime() - base::Time::UnixEpoch()).InMilliseconds(); 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string TimeToISO8601(const base::Time& t) { 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Time::Exploded exploded; 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) t.UTCExplode(&exploded); 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::StringPrintf( 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ", exploded.year, exploded.month, 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) exploded.day_of_month, exploded.hour, exploded.minute, exploded.second, 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) exploded.millisecond); 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static std::string GetStartTime(const DownloadItem& item) { 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return TimeToISO8601(item.GetStartTime()); 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static std::string GetEndTime(const DownloadItem& item) { 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return TimeToISO8601(item.GetEndTime()); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool GetDangerAccepted(const DownloadItem& item) { 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return (item.GetDangerType() == 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::DOWNLOAD_DANGER_TYPE_USER_VALIDATED); 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static bool GetExists(const DownloadItem& item) { 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return !item.GetFileExternallyRemoved(); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)static base::string16 GetFilename(const DownloadItem& item) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This filename will be compared with strings that could be passed in by the 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // user, who only sees LossyDisplayNames. 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return item.GetTargetFilePath().LossyDisplayName(); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static std::string GetFilenameUTF8(const DownloadItem& item) { 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return base::UTF16ToUTF8(GetFilename(item)); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static std::string GetUrl(const DownloadItem& item) { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return item.GetOriginalUrl().spec(); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static DownloadItem::DownloadState GetState(const DownloadItem& item) { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return item.GetState(); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static DownloadDangerType GetDangerType(const DownloadItem& item) { 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return item.GetDangerType(); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int GetReceivedBytes(const DownloadItem& item) { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return item.GetReceivedBytes(); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int GetTotalBytes(const DownloadItem& item) { 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return item.GetTotalBytes(); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static std::string GetMimeType(const DownloadItem& item) { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return item.GetMimeType(); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool IsPaused(const DownloadItem& item) { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return item.IsPaused(); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum ComparisonType {LT, EQ, GT}; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns true if |item| matches the filter specified by |value|, |cmptype|, 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and |accessor|. |accessor| is conceptually a function that takes a 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DownloadItem and returns one of its fields, which is then compared to 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |value|. 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename ValueType> 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool FieldMatches( 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ValueType& value, 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ComparisonType cmptype, 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Callback<ValueType(const DownloadItem&)>& accessor, 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DownloadItem& item) { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (cmptype) { 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case LT: return accessor.Run(item) < value; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EQ: return accessor.Run(item) == value; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case GT: return accessor.Run(item) > value; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper for building a Callback to FieldMatches<>(). 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename ValueType> DownloadQuery::FilterCallback BuildFilter( 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Value& value, ComparisonType cmptype, 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValueType (*accessor)(const DownloadItem&)) { 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValueType cpp_value; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetAs(value, &cpp_value)) return DownloadQuery::FilterCallback(); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::Bind(&FieldMatches<ValueType>, cpp_value, cmptype, 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(accessor)); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns true if |accessor.Run(item)| matches |pattern|. 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool FindRegex( 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) RE2* pattern, 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Callback<std::string(const DownloadItem&)>& accessor, 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DownloadItem& item) { 209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return RE2::PartialMatch(accessor.Run(item), *pattern); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper for building a Callback to FindRegex(). 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DownloadQuery::FilterCallback BuildRegexFilter( 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Value& regex_value, 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string (*accessor)(const DownloadItem&)) { 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string regex_str; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetAs(regex_value, ®ex_str)) return DownloadQuery::FilterCallback(); 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<RE2> pattern(new RE2(regex_str)); 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!pattern->ok()) return DownloadQuery::FilterCallback(); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base::Bind(&FindRegex, base::Owned(pattern.release()), 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(accessor)); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns a ComparisonType to indicate whether a field in |left| is less than, 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// greater than or equal to the same field in |right|. 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename ValueType> 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static ComparisonType Compare( 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Callback<ValueType(const DownloadItem&)>& accessor, 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DownloadItem& left, const DownloadItem& right) { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValueType left_value = accessor.Run(left); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValueType right_value = accessor.Run(right); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (left_value > right_value) return GT; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (left_value < right_value) return LT; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(left_value, right_value); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return EQ; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // anonymous namespace 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DownloadQuery::DownloadQuery() 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : limit_(kuint32max) { 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DownloadQuery::~DownloadQuery() { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AddFilter() pushes a new FilterCallback to filters_. Most FilterCallbacks are 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Callbacks to FieldMatches<>(). Search() iterates over given DownloadItems, 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// discarding items for which any filter returns false. A DownloadQuery may have 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// zero or more FilterCallbacks. 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DownloadQuery::AddFilter(const DownloadQuery::FilterCallback& value) { 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (value.is_null()) return false; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filters_.push_back(value); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DownloadQuery::AddFilter(DownloadItem::DownloadState state) { 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddFilter(base::Bind(&FieldMatches<DownloadItem::DownloadState>, state, EQ, 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GetState))); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DownloadQuery::AddFilter(DownloadDangerType danger) { 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AddFilter(base::Bind(&FieldMatches<DownloadDangerType>, danger, EQ, 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&GetDangerType))); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DownloadQuery::AddFilter(DownloadQuery::FilterType type, 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Value& value) { 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FILTER_BYTES_RECEIVED: 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddFilter(BuildFilter<int>(value, EQ, &GetReceivedBytes)); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FILTER_DANGER_ACCEPTED: 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddFilter(BuildFilter<bool>(value, EQ, &GetDangerAccepted)); 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case FILTER_EXISTS: 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return AddFilter(BuildFilter<bool>(value, EQ, &GetExists)); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FILTER_FILENAME: 2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return AddFilter(BuildFilter<base::string16>(value, EQ, &GetFilename)); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FILTER_FILENAME_REGEX: 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddFilter(BuildRegexFilter(value, &GetFilenameUTF8)); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FILTER_MIME: 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddFilter(BuildFilter<std::string>(value, EQ, &GetMimeType)); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FILTER_PAUSED: 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddFilter(BuildFilter<bool>(value, EQ, &IsPaused)); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FILTER_QUERY: { 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<base::string16> query_terms; 287558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return GetAs(value, &query_terms) && 288558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch (query_terms.empty() || 289558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch AddFilter(base::Bind(&MatchesQuery, query_terms))); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case FILTER_ENDED_AFTER: 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return AddFilter(BuildFilter<std::string>(value, GT, &GetEndTime)); 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case FILTER_ENDED_BEFORE: 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return AddFilter(BuildFilter<std::string>(value, LT, &GetEndTime)); 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case FILTER_END_TIME: 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return AddFilter(BuildFilter<std::string>(value, EQ, &GetEndTime)); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FILTER_STARTED_AFTER: 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return AddFilter(BuildFilter<std::string>(value, GT, &GetStartTime)); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FILTER_STARTED_BEFORE: 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return AddFilter(BuildFilter<std::string>(value, LT, &GetStartTime)); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FILTER_START_TIME: 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return AddFilter(BuildFilter<std::string>(value, EQ, &GetStartTime)); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FILTER_TOTAL_BYTES: 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddFilter(BuildFilter<int>(value, EQ, &GetTotalBytes)); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FILTER_TOTAL_BYTES_GREATER: 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddFilter(BuildFilter<int>(value, GT, &GetTotalBytes)); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FILTER_TOTAL_BYTES_LESS: 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddFilter(BuildFilter<int>(value, LT, &GetTotalBytes)); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FILTER_URL: 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddFilter(BuildFilter<std::string>(value, EQ, &GetUrl)); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case FILTER_URL_REGEX: 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return AddFilter(BuildRegexFilter(value, &GetUrl)); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DownloadQuery::Matches(const DownloadItem& item) const { 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (FilterCallbackVector::const_iterator filter = filters_.begin(); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter != filters_.end(); ++filter) { 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!filter->Run(item)) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AddSorter() creates a Sorter and pushes it onto sorters_. A Sorter is a 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// direction and a Callback to Compare<>(). After filtering, Search() makes a 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DownloadComparator functor from the sorters_ and passes the 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DownloadComparator to std::partial_sort. std::partial_sort calls the 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DownloadComparator with different pairs of DownloadItems. DownloadComparator 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// iterates over the sorters until a callback returns ComparisonType LT or GT. 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DownloadComparator returns true or false depending on that ComparisonType and 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the sorter's direction in order to indicate to std::partial_sort whether the 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// left item is after or before the right item. If all sorters return EQ, then 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DownloadComparator compares GetId. A DownloadQuery may have zero or more 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sorters, but there is one DownloadComparator per call to Search(). 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct DownloadQuery::Sorter { 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef base::Callback<ComparisonType( 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DownloadItem&, const DownloadItem&)> SortType; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) template<typename ValueType> 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static Sorter Build(DownloadQuery::SortDirection adirection, 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ValueType (*accessor)(const DownloadItem&)) { 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Sorter(adirection, base::Bind(&Compare<ValueType>, 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(accessor))); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Sorter(DownloadQuery::SortDirection adirection, 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SortType& asorter) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : direction(adirection), 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sorter(asorter) { 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~Sorter() {} 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadQuery::SortDirection direction; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SortType sorter; 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DownloadQuery::DownloadComparator { 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit DownloadComparator(const DownloadQuery::SorterVector& terms) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : terms_(terms) { 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if |left| sorts before |right|. 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool operator() (const DownloadItem* left, const DownloadItem* right); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DownloadQuery::SorterVector& terms_; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // std::sort requires this class to be copyable. 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DownloadQuery::DownloadComparator::operator() ( 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DownloadItem* left, const DownloadItem* right) { 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (DownloadQuery::SorterVector::const_iterator term = terms_.begin(); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) term != terms_.end(); ++term) { 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (term->sorter.Run(*left, *right)) { 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case LT: return term->direction == DownloadQuery::ASCENDING; 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case GT: return term->direction == DownloadQuery::DESCENDING; 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EQ: break; // break the switch but not the loop 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_NE(left->GetId(), right->GetId()); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return left->GetId() < right->GetId(); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DownloadQuery::AddSorter(DownloadQuery::SortType type, 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadQuery::SortDirection direction) { 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case SORT_END_TIME: 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sorters_.push_back(Sorter::Build<int64>(direction, &GetEndTimeMsEpoch)); 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SORT_START_TIME: 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sorters_.push_back(Sorter::Build<int64>(direction, &GetStartTimeMsEpoch)); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SORT_URL: 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sorters_.push_back(Sorter::Build<std::string>(direction, &GetUrl)); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SORT_FILENAME: 4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sorters_.push_back( 4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Sorter::Build<base::string16>(direction, &GetFilename)); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SORT_DANGER: 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sorters_.push_back(Sorter::Build<DownloadDangerType>( 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) direction, &GetDangerType)); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SORT_DANGER_ACCEPTED: 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sorters_.push_back(Sorter::Build<bool>(direction, &GetDangerAccepted)); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case SORT_EXISTS: 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sorters_.push_back(Sorter::Build<bool>(direction, &GetExists)); 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SORT_STATE: 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sorters_.push_back(Sorter::Build<DownloadItem::DownloadState>( 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) direction, &GetState)); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SORT_PAUSED: 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sorters_.push_back(Sorter::Build<bool>(direction, &IsPaused)); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SORT_MIME: 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sorters_.push_back(Sorter::Build<std::string>(direction, &GetMimeType)); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SORT_BYTES_RECEIVED: 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sorters_.push_back(Sorter::Build<int>(direction, &GetReceivedBytes)); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case SORT_TOTAL_BYTES: 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sorters_.push_back(Sorter::Build<int>(direction, &GetTotalBytes)); 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DownloadQuery::FinishSearch(DownloadQuery::DownloadVector* results) const { 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!sorters_.empty()) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::partial_sort(results->begin(), 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) results->begin() + std::min(limit_, results->size()), 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) results->end(), 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DownloadComparator(sorters_)); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (results->size() > limit_) 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) results->resize(limit_); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 443