// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROME_BROWSER_DOWNLOAD_DOWNLOAD_QUERY_H_ #define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_QUERY_H_ #include <map> #include <string> #include <vector> #include "base/callback_forward.h" #include "content/public/browser/download_item.h" namespace base { class Value; } // Filter and sort a vector of DownloadItem*s. // // The following example copies from |all_items| to |results| those // DownloadItem*s whose start time is 0 and whose id is odd, sorts primarily by // bytes received ascending and secondarily by url descending, and limits the // results to 20 items. Any number of filters or sorters is allowed. If all // sorters compare two DownloadItems equivalently, then they are sorted by their // id ascending. // // DownloadQuery query; // scoped_ptr<base::Value> start_time(base::Balue::CreateIntegerValue(0)); // CHECK(query.AddFilter(FILTER_START_TIME, *start_time.get())); // bool FilterOutOddDownloads(const DownloadItem& item) { // return 0 == (item.GetId() % 2); // } // CHECK(query.AddFilter(base::Bind(&FilterOutOddDownloads))); // query.AddSorter(SORT_BYTES_RECEIVED, ASCENDING); // query.AddSorter(SORT_URL, DESCENDING); // query.Limit(20); // DownloadVector all_items, results; // query.Search(all_items.begin(), all_items.end(), &results); class DownloadQuery { public: typedef std::vector<content::DownloadItem*> DownloadVector; // FilterCallback is a Callback that takes a DownloadItem and returns true if // the item matches the filter and false otherwise. // query.AddFilter(base::Bind(&YourFilterFunction)); typedef base::Callback<bool(const content::DownloadItem&)> FilterCallback; // All times are ISO 8601 strings. enum FilterType { FILTER_BYTES_RECEIVED, // int FILTER_DANGER_ACCEPTED, // bool FILTER_ENDED_AFTER, // string FILTER_ENDED_BEFORE, // string FILTER_END_TIME, // string FILTER_EXISTS, // bool FILTER_FILENAME, // string FILTER_FILENAME_REGEX, // string FILTER_MIME, // string FILTER_PAUSED, // bool FILTER_QUERY, // vector<base::string16> FILTER_STARTED_AFTER, // string FILTER_STARTED_BEFORE, // string FILTER_START_TIME, // string FILTER_TOTAL_BYTES, // int FILTER_TOTAL_BYTES_GREATER, // int FILTER_TOTAL_BYTES_LESS, // int FILTER_URL, // string FILTER_URL_REGEX, // string }; enum SortType { SORT_BYTES_RECEIVED, SORT_DANGER, SORT_DANGER_ACCEPTED, SORT_END_TIME, SORT_EXISTS, SORT_FILENAME, SORT_MIME, SORT_PAUSED, SORT_START_TIME, SORT_STATE, SORT_TOTAL_BYTES, SORT_URL, }; enum SortDirection { ASCENDING, DESCENDING, }; DownloadQuery(); ~DownloadQuery(); // Adds a new filter of type |type| with value |value| and returns true if // |type| is valid and |value| is the correct Value-type and well-formed. // Returns false if |type| is invalid or |value| is the incorrect Value-type // or malformed. Search() will filter out all DownloadItem*s that do not // match all filters. Multiple instances of the same FilterType are allowed, // so you can pass two regexes to AddFilter(URL_REGEX,...) in order to // Search() for items whose url matches both regexes. You can also pass two // different DownloadStates to AddFilter(), which will cause Search() to // filter out all items. bool AddFilter(const FilterCallback& filter); bool AddFilter(FilterType type, const base::Value& value); void AddFilter(content::DownloadDangerType danger); void AddFilter(content::DownloadItem::DownloadState state); // Adds a new sorter of type |type| with direction |direction|. After // filtering DownloadItem*s, Search() will sort the results primarily by the // sorter from the first call to Sort(), secondarily by the sorter from the // second call to Sort(), and so on. For example, if the InputIterator passed // to Search() yields four DownloadItems {id:0, error:0, start_time:0}, {id:1, // error:0, start_time:1}, {id:2, error:1, start_time:0}, {id:3, error:1, // start_time:1}, and Sort is called twice, once with (SORT_ERROR, ASCENDING) // then with (SORT_START_TIME, DESCENDING), then Search() will return items // ordered 1,0,3,2. void AddSorter(SortType type, SortDirection direction); // Limit the size of search results to |limit|. void Limit(size_t limit) { limit_ = limit; } // Filters DownloadItem*s from |iter| to |last| into |results|, sorts // |results|, and limits the size of |results|. |results| must be non-NULL. template <typename InputIterator> void Search(InputIterator iter, const InputIterator last, DownloadVector* results) const { results->clear(); for (; iter != last; ++iter) { if (Matches(**iter)) results->push_back(*iter); } FinishSearch(results); } private: struct Sorter; class DownloadComparator; typedef std::vector<FilterCallback> FilterCallbackVector; typedef std::vector<Sorter> SorterVector; bool FilterRegex(const std::string& regex_str, const base::Callback<std::string( const content::DownloadItem&)>& accessor); bool Matches(const content::DownloadItem& item) const; void FinishSearch(DownloadVector* results) const; FilterCallbackVector filters_; SorterVector sorters_; size_t limit_; DISALLOW_COPY_AND_ASSIGN(DownloadQuery); }; #endif // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_QUERY_H_