• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
3 // found in the LICENSE file.
4 
5 #ifndef CHROME_BROWSER_DOWNLOAD_DOWNLOAD_QUERY_H_
6 #define CHROME_BROWSER_DOWNLOAD_DOWNLOAD_QUERY_H_
7 
8 #include <map>
9 #include <string>
10 #include <vector>
11 
12 #include "base/callback_forward.h"
13 #include "content/public/browser/download_item.h"
14 
15 namespace base {
16 class Value;
17 }
18 
19 // Filter and sort a vector of DownloadItem*s.
20 //
21 // The following example copies from |all_items| to |results| those
22 // DownloadItem*s whose start time is 0 and whose id is odd, sorts primarily by
23 // bytes received ascending and secondarily by url descending, and limits the
24 // results to 20 items. Any number of filters or sorters is allowed. If all
25 // sorters compare two DownloadItems equivalently, then they are sorted by their
26 // id ascending.
27 //
28 // DownloadQuery query;
29 // scoped_ptr<base::Value> start_time(base::Balue::CreateIntegerValue(0));
30 // CHECK(query.AddFilter(FILTER_START_TIME, *start_time.get()));
31 // bool FilterOutOddDownloads(const DownloadItem& item) {
32 //   return 0 == (item.GetId() % 2);
33 // }
34 // CHECK(query.AddFilter(base::Bind(&FilterOutOddDownloads)));
35 // query.AddSorter(SORT_BYTES_RECEIVED, ASCENDING);
36 // query.AddSorter(SORT_URL, DESCENDING);
37 // query.Limit(20);
38 // DownloadVector all_items, results;
39 // query.Search(all_items.begin(), all_items.end(), &results);
40 class DownloadQuery {
41  public:
42   typedef std::vector<content::DownloadItem*> DownloadVector;
43 
44   // FilterCallback is a Callback that takes a DownloadItem and returns true if
45   // the item matches the filter and false otherwise.
46   // query.AddFilter(base::Bind(&YourFilterFunction));
47   typedef base::Callback<bool(const content::DownloadItem&)> FilterCallback;
48 
49   // All times are ISO 8601 strings.
50   enum FilterType {
51     FILTER_BYTES_RECEIVED,       // int
52     FILTER_DANGER_ACCEPTED,      // bool
53     FILTER_ENDED_AFTER,          // string
54     FILTER_ENDED_BEFORE,         // string
55     FILTER_END_TIME,             // string
56     FILTER_EXISTS,               // bool
57     FILTER_FILENAME,             // string
58     FILTER_FILENAME_REGEX,       // string
59     FILTER_MIME,                 // string
60     FILTER_PAUSED,               // bool
61     FILTER_QUERY,                // vector<base::string16>
62     FILTER_STARTED_AFTER,        // string
63     FILTER_STARTED_BEFORE,       // string
64     FILTER_START_TIME,           // string
65     FILTER_TOTAL_BYTES,          // int
66     FILTER_TOTAL_BYTES_GREATER,  // int
67     FILTER_TOTAL_BYTES_LESS,     // int
68     FILTER_URL,                  // string
69     FILTER_URL_REGEX,            // string
70   };
71 
72   enum SortType {
73     SORT_BYTES_RECEIVED,
74     SORT_DANGER,
75     SORT_DANGER_ACCEPTED,
76     SORT_END_TIME,
77     SORT_EXISTS,
78     SORT_FILENAME,
79     SORT_MIME,
80     SORT_PAUSED,
81     SORT_START_TIME,
82     SORT_STATE,
83     SORT_TOTAL_BYTES,
84     SORT_URL,
85   };
86 
87   enum SortDirection {
88     ASCENDING,
89     DESCENDING,
90   };
91 
92   DownloadQuery();
93   ~DownloadQuery();
94 
95   // Adds a new filter of type |type| with value |value| and returns true if
96   // |type| is valid and |value| is the correct Value-type and well-formed.
97   // Returns false if |type| is invalid or |value| is the incorrect Value-type
98   // or malformed.  Search() will filter out all DownloadItem*s that do not
99   // match all filters.  Multiple instances of the same FilterType are allowed,
100   // so you can pass two regexes to AddFilter(URL_REGEX,...) in order to
101   // Search() for items whose url matches both regexes. You can also pass two
102   // different DownloadStates to AddFilter(), which will cause Search() to
103   // filter out all items.
104   bool AddFilter(const FilterCallback& filter);
105   bool AddFilter(FilterType type, const base::Value& value);
106   void AddFilter(content::DownloadDangerType danger);
107   void AddFilter(content::DownloadItem::DownloadState state);
108 
109   // Adds a new sorter of type |type| with direction |direction|.  After
110   // filtering DownloadItem*s, Search() will sort the results primarily by the
111   // sorter from the first call to Sort(), secondarily by the sorter from the
112   // second call to Sort(), and so on. For example, if the InputIterator passed
113   // to Search() yields four DownloadItems {id:0, error:0, start_time:0}, {id:1,
114   // error:0, start_time:1}, {id:2, error:1, start_time:0}, {id:3, error:1,
115   // start_time:1}, and Sort is called twice, once with (SORT_ERROR, ASCENDING)
116   // then with (SORT_START_TIME, DESCENDING), then Search() will return items
117   // ordered 1,0,3,2.
118   void AddSorter(SortType type, SortDirection direction);
119 
120   // Limit the size of search results to |limit|.
Limit(size_t limit)121   void Limit(size_t limit) { limit_ = limit; }
122 
123   // Filters DownloadItem*s from |iter| to |last| into |results|, sorts
124   // |results|, and limits the size of |results|. |results| must be non-NULL.
125   template <typename InputIterator>
Search(InputIterator iter,const InputIterator last,DownloadVector * results)126   void Search(InputIterator iter, const InputIterator last,
127               DownloadVector* results) const {
128     results->clear();
129     for (; iter != last; ++iter) {
130       if (Matches(**iter)) results->push_back(*iter);
131     }
132     FinishSearch(results);
133   }
134 
135  private:
136   struct Sorter;
137   class DownloadComparator;
138   typedef std::vector<FilterCallback> FilterCallbackVector;
139   typedef std::vector<Sorter> SorterVector;
140 
141   bool FilterRegex(const std::string& regex_str,
142                    const base::Callback<std::string(
143                        const content::DownloadItem&)>& accessor);
144   bool Matches(const content::DownloadItem& item) const;
145   void FinishSearch(DownloadVector* results) const;
146 
147   FilterCallbackVector filters_;
148   SorterVector sorters_;
149   size_t limit_;
150 
151   DISALLOW_COPY_AND_ASSIGN(DownloadQuery);
152 };
153 
154 #endif  // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_QUERY_H_
155