Home | History | Annotate | Download | only in 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<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|.
    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>
    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