Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2193)

Unified Diff: chrome/browser/download/download_query.cc

Issue 7192016: chrome.experimental.downloads (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: merged db_handle, id; onCreated, onErased Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/download/download_query.h ('k') | chrome/browser/download/download_query_fields.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/download/download_query.cc
diff --git a/chrome/browser/download/download_query.cc b/chrome/browser/download/download_query.cc
new file mode 100644
index 0000000000000000000000000000000000000000..2f540bec3533613d303b2eb83e2c3454725b46bb
--- /dev/null
+++ b/chrome/browser/download/download_query.cc
@@ -0,0 +1,366 @@
+// Copyright (c) 2011 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.
+
+#include "chrome/browser/download/download_query.h"
+
+#include <string>
+#include <vector>
+
+#include "base/memory/scoped_ptr.h"
+#include "base/stl_util-inl.h"
+#include "base/string16.h"
+#include "base/string_split.h"
+#include "base/values.h"
+#include "unicode/regex.h"
+#include "chrome/browser/download/download_item.h"
+
+namespace {
+typedef std::vector<std::string> Strings;
+typedef std::vector<DownloadItem*> DownloadItems;
+
+struct SimpleDownloadItem {
+ static const char STATE_IN_PROGRESS[];
+ static const char STATE_COMPLETE[];
+ static const char STATE_INTERRUPTED[];
+ static const char DANGER_SAFE[];
+ static const char DANGER_FILE[];
+ static const char DANGER_URL[];
+
+ explicit SimpleDownloadItem(DownloadItem* download)
+ : item(download) {
+ CHECK(item);
+ }
+
+ int id() const { return item->id(); }
+ std::string url() const { return item->original_url().spec(); }
+ std::string filename() const {
+ return item->GetFileNameToReportUser().value();
+ }
+ std::string danger() const { return DangerString(item->GetDangerType()); }
+ bool dangerAccepted() const {
+ return item->safety_state() == DownloadItem::DANGEROUS_BUT_VALIDATED;
+ }
+ std::string state() const { return StateString(item->state()); }
+ bool paused() const { return item->is_paused(); }
+ std::string mime() const { return item->mime_type(); }
+ int startTime() const {
+ return (item->start_time() - base::Time::UnixEpoch()).InMilliseconds();
+ }
+ int endTime() const { return -1; }
+ int bytesReceived() const { return item->received_bytes(); }
+ int totalBytes() const { return item->total_bytes(); }
+ int fileSize() const { return -1; }
+ int error() const { return 0; }
+
+ DictionaryValue* ToJSON() const;
+
+ static std::string DangerString(DownloadItem::DangerType danger) {
+ switch (danger) {
+ case DownloadItem::NOT_DANGEROUS: return DANGER_SAFE;
+ case DownloadItem::DANGEROUS_FILE: return DANGER_FILE;
+ case DownloadItem::DANGEROUS_URL: return DANGER_URL;
+ case DownloadItem::DANGEROUS_TYPE_MAX:
+ default:
+ NOTREACHED();
+ return "";
+ }
+ }
+
+ static std::string StateString(DownloadItem::DownloadState state) {
+ switch (state) {
+ case DownloadItem::IN_PROGRESS: return STATE_IN_PROGRESS;
+ case DownloadItem::COMPLETE: return STATE_COMPLETE;
+ case DownloadItem::INTERRUPTED: // fall through
+ case DownloadItem::CANCELLED: return STATE_INTERRUPTED;
+ case DownloadItem::REMOVING:
+ case DownloadItem::MAX_DOWNLOAD_STATE:
+ default:
+ NOTREACHED();
+ return "";
+ }
+ }
+
+ DownloadItem* item;
+ // Allow copy and assign.
+};
+
+typedef std::vector<SimpleDownloadItem*> SimpleItems;
+
+// Functor passed to std::sort to sort SimpleDownloadItems.
+class DownloadComparator {
+ public:
+ DownloadComparator(std::string* error_msg, Strings* order_terms)
+ : error_msg_(error_msg),
+ order_terms_(order_terms) {
+ }
+
+ bool operator() (const SimpleDownloadItem* left,
+ const SimpleDownloadItem* right);
+ private:
+ static const char kDash = '-';
+
+ template <typename FieldType> bool CompareField(
+ std::string term,
+ std::string field,
+ FieldType left,
+ FieldType right,
+ bool* matched_term,
+ bool* cmp) const;
+
+ std::string* error_msg_;
+ Strings* order_terms_;
+ // std::sort requires this class to be copyable.
+};
+
+using download_util::DownloadQuery;
+
+class DownloadSearch : DownloadQuery {
+ public:
+ DownloadSearch(const DownloadQuery& query, DownloadItems* items);
+ ~DownloadSearch() {}
+
+ bool IsWellFormed(std::string* error_msg);
+ bool Matches(const SimpleDownloadItem& item);
+
+ SimpleItems::const_iterator begin() const { return simple_items_.begin(); }
+ SimpleItems::const_iterator end() const { return simple_items_.end(); }
+
+ bool ReachedLimit(int num_results) {
+ return has_limit_ && (num_results >= limit_);
+ }
+
+ private:
+ std::string error_msg_;
+ Strings order_terms_;
+ SimpleItems simple_items_;
+ STLElementDeleter<SimpleItems> delete_simple_items_;
+ Strings query_terms_;
+ scoped_ptr<icu::RegexPattern> filename_pattern_;
+ scoped_ptr<icu::RegexPattern> url_pattern_;
+ DownloadComparator comparator_;
+
+ DISALLOW_COPY_AND_ASSIGN(DownloadSearch);
+};
+
+DictionaryValue* SimpleDownloadItem::ToJSON() const {
+ DictionaryValue* json = new DictionaryValue();
+#define FIELD(name, type) \
+ json->Set ## type(#name, name());
+#include "chrome/browser/download/simple_download_item_fields.h"
+#undef FIELD
+ return json;
+}
+
+bool DownloadComparator::operator() (
+ const SimpleDownloadItem* left,
+ const SimpleDownloadItem* right) {
+ CHECK(left);
+ CHECK(right);
+ Strings::iterator order_term,
+ last_order_term = order_terms_->end();
+ for (order_term = order_terms_->begin();
+ order_term != last_order_term; ++order_term) {
+ bool matched_term = false;
+ bool cmp = false;
+#define Integer int
+#define Boolean bool
+#define String std::string
+#define FIELD(name, type) \
+ if (CompareField<type>(*order_term, #name, left->name(), right->name(), \
+ &matched_term, &cmp)) return cmp; \
+ if (matched_term) continue;
+#include "chrome/browser/download/simple_download_item_fields.h"
+#undef FIELD
+#undef String
+#undef Boolean
+#undef Integer
+ *error_msg_ += " " + *order_term;
+ order_terms_->erase(order_term);
+ }
+ CHECK_NE(left->id(), right->id());
+ return left->id() < right->id();
+}
+
+// Return true and set cmp if matched_term and left != right.
+template <typename FieldType>
+bool DownloadComparator::CompareField(
+ std::string term,
+ std::string field,
+ FieldType left,
+ FieldType right,
+ bool* matched_term,
+ bool* cmp) const {
+ bool diff = (left != right);
+ if (term == field) {
+ *matched_term = true;
+ if (diff) *cmp = (left < right);
+ }
+ if (term == kDash + field) {
+ *matched_term = true;
+ if (diff) *cmp = (left > right);
+ }
+ return diff && *matched_term;
+}
+
+// NOTE These string constants must match those in
+// chrome/common/extensions/api/extension_api.json
+const char SimpleDownloadItem::STATE_IN_PROGRESS[] = "in progress";
+const char SimpleDownloadItem::STATE_COMPLETE[] = "complete";
+const char SimpleDownloadItem::STATE_INTERRUPTED[] = "interrupted";
+const char SimpleDownloadItem::DANGER_SAFE[] = "safe";
+const char SimpleDownloadItem::DANGER_FILE[] = "file";
+const char SimpleDownloadItem::DANGER_URL[] = "url";
+
+DownloadSearch::DownloadSearch(
+ const DownloadQuery& query, DownloadItems* items)
+ : DownloadQuery(query),
+ delete_simple_items_(&simple_items_),
+ comparator_(&error_msg_, &order_terms_) {
+ if (has_query_) {
+ base::SplitString(query_, ' ', &query_terms_); // TODO handle quopri
+ }
+ if (has_filenameRegex_) {
+ UParseError regex_error; // TODO do these need to outlive the pattern?
+ UErrorCode regex_status = U_ZERO_ERROR;
+ filename_pattern_.reset(icu::RegexPattern::compile(
+ icu::UnicodeString::fromUTF8(filenameRegex_),
+ regex_error, regex_status));
+ if (!U_SUCCESS(regex_status)) {
+ error_msg_ = "bad filenameRegex";
+ return;
+ }
+ }
+ if (has_urlRegex_) {
+ UParseError regex_error;
+ UErrorCode regex_status = U_ZERO_ERROR;
+ url_pattern_.reset(icu::RegexPattern::compile(
+ icu::UnicodeString::fromUTF8(urlRegex_),
+ regex_error, regex_status));
+ if (!U_SUCCESS(regex_status)) {
+ error_msg_ = "bad urlRegex";
+ return;
+ }
+ }
+ for (DownloadItems::const_iterator iter = items->begin();
+ iter != items->end(); ++iter) {
+ if (*iter != NULL) {
+ if (!filter_func_.is_null() && !filter_func_.Run(**iter)) continue;
+ simple_items_.push_back(new SimpleDownloadItem(*iter));
+ }
+ }
+ if (has_orderBy_ && (1 < simple_items_.size())) {
+ base::SplitString(orderBy_, ' ', &order_terms_);
+ std::sort(simple_items_.begin(), simple_items_.end(), comparator_);
+ }
+}
+
+bool DownloadSearch::IsWellFormed(std::string* error_msg) {
+ if (error_msg != NULL) *error_msg = error_msg_;
+ return error_msg_.empty();
+}
+
+bool DownloadSearch::Matches(const SimpleDownloadItem& item) {
+#define FIELD(name, unused_type) \
+ if (has_ ## name ## _ && (item.name() != name ## _)) return false;
+#include "chrome/browser/download/simple_download_item_fields.h"
+#undef FIELD
+ if (has_state_enum_ && (item.item->state() != state_enum_)) return false;
+ if (has_danger_enum_ && (item.item->GetDangerType() != danger_enum_))
+ return false;
+ if (has_startedBefore_ && (item.startTime() > startedBefore_)) return false;
+ if (has_startedAfter_ && (item.startTime() < startedAfter_)) return false;
+ if (has_endedBefore_ && (item.endTime() > endedBefore_)) return false;
+ if (has_endedAfter_ && (item.endTime() < endedAfter_)) return false;
+ if (has_totalBytesGreater_ && (item.totalBytes() < totalBytesGreater_))
+ return false;
+ if (has_totalBytesLess_ && (item.totalBytes() > totalBytesLess_))
+ return false;
+ Strings::const_iterator query_term_iter,
+ query_term_end = query_terms_.end();
+ for (query_term_iter = query_terms_.begin();
+ query_term_iter != query_term_end; ++query_term_iter) {
+ std::string query_term = *query_term_iter;
+ if ((std::string::npos == item.filename().find(query_term)) &&
+ (std::string::npos == item.url().find(query_term))) {
+ return false;
+ }
+ }
+ if (filename_pattern_.get() != NULL) {
+ UErrorCode status = U_ZERO_ERROR;
+ scoped_ptr<icu::RegexMatcher> filename_matcher(filename_pattern_->matcher(
+ icu::UnicodeString::fromUTF8(item.filename()), status));
+ if (U_FAILURE(status)) {
+ return false;
+ }
+ if (!filename_matcher->find(0, status)) return false;
+ }
+ if (url_pattern_.get() != NULL) {
+ UErrorCode status = U_ZERO_ERROR;
+ scoped_ptr<icu::RegexMatcher> url_matcher(url_pattern_->matcher(
+ icu::UnicodeString::fromUTF8(item.url()), status));
+ if (U_FAILURE(status)) {
+ return false;
+ }
+ if (!url_matcher->find(0, status)) return false;
+ }
+ return true;
+}
+} // anonymous namespace
+
+namespace download_util {
+
+DownloadQuery::DownloadQuery() {
+ has_state_enum_ = false;
+ has_danger_enum_ = false;
+#define FIELD(name, type) \
+ has_ ## name ## _ = false;
+#include "chrome/browser/download/download_query_fields.h"
+#undef FIELD
+}
+
+DownloadQuery::DownloadQuery(const DictionaryValue& json) {
+ has_state_enum_ = false;
+ has_danger_enum_ = false;
+#define FIELD(name, type) \
+ has_ ## name ## _ = json.Get ## type(#name, &name ## _);
+#include "chrome/browser/download/download_query_fields.h"
+#undef FIELD
+}
+
+DownloadQuery& DownloadQuery::filter_func(DownloadQuery::FilterType func) {
+ filter_func_ = func;
+ return *this;
+}
+
+DownloadQuery& DownloadQuery::state_enum(
+ DownloadItem::DownloadState stateenum) {
+ has_state_enum_ = true;
+ state_enum_ = stateenum;
+ return *this;
+}
+
+DownloadQuery& DownloadQuery::danger_enum(DownloadItem::DangerType dangerenum) {
+ has_danger_enum_ = true;
+ danger_enum_ = dangerenum;
+ return *this;
+}
+
+bool DownloadQuery::Search(
+ std::vector<DownloadItem*>* items,
+ std::string* error_msg,
+ ListValue* results) const {
+ DownloadSearch search(*this, items);
+ items->clear();
+ if (!search.IsWellFormed(error_msg)) return false;
+ for (SimpleItems::const_iterator iter = search.begin();
+ iter != search.end(); ++iter) {
+ if (!search.Matches(**iter)) continue;
+ items->push_back((*iter)->item);
+ if (results != NULL) results->Append((*iter)->ToJSON());
+ if (search.ReachedLimit(items->size())) break;
+ }
+ return true;
+}
+} // namespace download_util
+
« no previous file with comments | « chrome/browser/download/download_query.h ('k') | chrome/browser/download/download_query_fields.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698