Index: chrome/browser/extensions/api/downloads/downloads_api.cc |
diff --git a/chrome/browser/extensions/api/downloads/downloads_api.cc b/chrome/browser/extensions/api/downloads/downloads_api.cc |
index 085fd949f699cdc3a849d48d03ad965641378e60..69081591346d047ac7992c74b96766a30bff8548 100644 |
--- a/chrome/browser/extensions/api/downloads/downloads_api.cc |
+++ b/chrome/browser/extensions/api/downloads/downloads_api.cc |
@@ -6,6 +6,8 @@ |
#include <stddef.h> |
#include <stdint.h> |
+ |
+#include <algorithm> |
#include <memory> |
#include <set> |
#include <string> |
@@ -158,6 +160,8 @@ const char kExistsKey[] = "exists"; |
const char kFileSizeKey[] = "fileSize"; |
const char kFilenameKey[] = "filename"; |
const char kFilenameRegexKey[] = "filenameRegex"; |
+const char kFinalUrlKey[] = "finalUrl"; |
+const char kFinalUrlRegexKey[] = "finalUrlRegex"; |
const char kIdKey[] = "id"; |
const char kIncognitoKey[] = "incognito"; |
const char kMimeKey[] = "mime"; |
@@ -176,8 +180,48 @@ const char kTotalBytesKey[] = "totalBytes"; |
const char kTotalBytesLessKey[] = "totalBytesLess"; |
const char kUrlKey[] = "url"; |
const char kUrlRegexKey[] = "urlRegex"; |
-const char kFinalUrlKey[] = "finalUrl"; |
-const char kFinalUrlRegexKey[] = "finalUrlRegex"; |
+ |
+// This list must be in order as determined by strcmp. The test |
+// DownloadsApiInternalUnitTest.FilterTypeSorted will verify this. |
+constexpr DownloadQueryFilterTypePair kFilterTypes[] = { |
+ {kBytesReceivedKey, DownloadQuery::FILTER_BYTES_RECEIVED}, |
+ {kEndTimeKey, DownloadQuery::FILTER_END_TIME}, |
+ {kEndedAfterKey, DownloadQuery::FILTER_ENDED_AFTER}, |
+ {kEndedBeforeKey, DownloadQuery::FILTER_ENDED_BEFORE}, |
+ {kExistsKey, DownloadQuery::FILTER_EXISTS}, |
+ {kFilenameKey, DownloadQuery::FILTER_FILENAME}, |
+ {kFilenameRegexKey, DownloadQuery::FILTER_FILENAME_REGEX}, |
+ {kFinalUrlKey, DownloadQuery::FILTER_URL}, |
+ {kFinalUrlRegexKey, DownloadQuery::FILTER_URL_REGEX}, |
+ {kMimeKey, DownloadQuery::FILTER_MIME}, |
+ {kPausedKey, DownloadQuery::FILTER_PAUSED}, |
+ {kQueryKey, DownloadQuery::FILTER_QUERY}, |
+ {kStartTimeKey, DownloadQuery::FILTER_START_TIME}, |
+ {kStartedAfterKey, DownloadQuery::FILTER_STARTED_AFTER}, |
+ {kStartedBeforeKey, DownloadQuery::FILTER_STARTED_BEFORE}, |
+ {kTotalBytesKey, DownloadQuery::FILTER_TOTAL_BYTES}, |
+ {kTotalBytesGreaterKey, DownloadQuery::FILTER_TOTAL_BYTES_GREATER}, |
+ {kTotalBytesLessKey, DownloadQuery::FILTER_TOTAL_BYTES_LESS}, |
+ {kUrlKey, DownloadQuery::FILTER_ORIGINAL_URL}, |
+ {kUrlRegexKey, DownloadQuery::FILTER_ORIGINAL_URL_REGEX}, |
+}; |
+ |
+// This list must be in order as determined by strcmp. The test |
+// DownloadsApiInternalUnitTest.SortTypeSorted will verify this. |
+constexpr DownloadQuerySortTypePair kSortTypes[] = { |
+ {kBytesReceivedKey, DownloadQuery::SORT_BYTES_RECEIVED}, |
+ {kDangerKey, DownloadQuery::SORT_DANGER}, |
+ {kEndTimeKey, DownloadQuery::SORT_END_TIME}, |
+ {kExistsKey, DownloadQuery::SORT_EXISTS}, |
+ {kFilenameKey, DownloadQuery::SORT_FILENAME}, |
+ {kFinalUrlKey, DownloadQuery::SORT_URL}, |
+ {kMimeKey, DownloadQuery::SORT_MIME}, |
+ {kPausedKey, DownloadQuery::SORT_PAUSED}, |
+ {kStartTimeKey, DownloadQuery::SORT_START_TIME}, |
+ {kStateKey, DownloadQuery::SORT_STATE}, |
+ {kTotalBytesKey, DownloadQuery::SORT_TOTAL_BYTES}, |
+ {kUrlKey, DownloadQuery::SORT_ORIGINAL_URL}, |
+}; |
// Note: Any change to the danger type strings, should be accompanied by a |
// corresponding change to downloads.json. |
@@ -362,51 +406,6 @@ IconLoader::IconSize IconLoaderSizeFromPixelSize(int pixel_size) { |
} |
} |
-typedef base::hash_map<std::string, DownloadQuery::FilterType> FilterTypeMap; |
- |
-void InitFilterTypeMap(FilterTypeMap* filter_types_ptr) { |
- FilterTypeMap& filter_types = *filter_types_ptr; |
- filter_types[kBytesReceivedKey] = DownloadQuery::FILTER_BYTES_RECEIVED; |
- filter_types[kExistsKey] = DownloadQuery::FILTER_EXISTS; |
- filter_types[kFilenameKey] = DownloadQuery::FILTER_FILENAME; |
- filter_types[kFilenameRegexKey] = DownloadQuery::FILTER_FILENAME_REGEX; |
- filter_types[kMimeKey] = DownloadQuery::FILTER_MIME; |
- filter_types[kPausedKey] = DownloadQuery::FILTER_PAUSED; |
- filter_types[kQueryKey] = DownloadQuery::FILTER_QUERY; |
- filter_types[kEndedAfterKey] = DownloadQuery::FILTER_ENDED_AFTER; |
- filter_types[kEndedBeforeKey] = DownloadQuery::FILTER_ENDED_BEFORE; |
- filter_types[kEndTimeKey] = DownloadQuery::FILTER_END_TIME; |
- filter_types[kStartedAfterKey] = DownloadQuery::FILTER_STARTED_AFTER; |
- filter_types[kStartedBeforeKey] = DownloadQuery::FILTER_STARTED_BEFORE; |
- filter_types[kStartTimeKey] = DownloadQuery::FILTER_START_TIME; |
- filter_types[kTotalBytesKey] = DownloadQuery::FILTER_TOTAL_BYTES; |
- filter_types[kTotalBytesGreaterKey] = |
- DownloadQuery::FILTER_TOTAL_BYTES_GREATER; |
- filter_types[kTotalBytesLessKey] = DownloadQuery::FILTER_TOTAL_BYTES_LESS; |
- filter_types[kUrlKey] = DownloadQuery::FILTER_ORIGINAL_URL; |
- filter_types[kUrlRegexKey] = DownloadQuery::FILTER_ORIGINAL_URL_REGEX; |
- filter_types[kFinalUrlKey] = DownloadQuery::FILTER_URL; |
- filter_types[kFinalUrlRegexKey] = DownloadQuery::FILTER_URL_REGEX; |
-} |
- |
-typedef base::hash_map<std::string, DownloadQuery::SortType> SortTypeMap; |
- |
-void InitSortTypeMap(SortTypeMap* sorter_types_ptr) { |
- SortTypeMap& sorter_types = *sorter_types_ptr; |
- sorter_types[kBytesReceivedKey] = DownloadQuery::SORT_BYTES_RECEIVED; |
- sorter_types[kDangerKey] = DownloadQuery::SORT_DANGER; |
- sorter_types[kEndTimeKey] = DownloadQuery::SORT_END_TIME; |
- sorter_types[kExistsKey] = DownloadQuery::SORT_EXISTS; |
- sorter_types[kFilenameKey] = DownloadQuery::SORT_FILENAME; |
- sorter_types[kMimeKey] = DownloadQuery::SORT_MIME; |
- sorter_types[kPausedKey] = DownloadQuery::SORT_PAUSED; |
- sorter_types[kStartTimeKey] = DownloadQuery::SORT_START_TIME; |
- sorter_types[kStateKey] = DownloadQuery::SORT_STATE; |
- sorter_types[kTotalBytesKey] = DownloadQuery::SORT_TOTAL_BYTES; |
- sorter_types[kUrlKey] = DownloadQuery::SORT_ORIGINAL_URL; |
- sorter_types[kFinalUrlKey] = DownloadQuery::SORT_URL; |
-} |
- |
bool IsNotTemporaryDownloadFilter(const DownloadItem& download_item) { |
return !download_item.IsTemporary(); |
} |
@@ -476,13 +475,6 @@ void CompileDownloadQueryOrderBy( |
const std::vector<std::string>& order_by_strs, |
std::string* error, |
DownloadQuery* query) { |
- // TODO(benjhayden): Consider switching from LazyInstance to explicit string |
- // comparisons. |
- static base::LazyInstance<SortTypeMap>::DestructorAtExit sorter_types = |
- LAZY_INSTANCE_INITIALIZER; |
- if (sorter_types.Get().empty()) |
- InitSortTypeMap(sorter_types.Pointer()); |
- |
for (std::vector<std::string>::const_iterator iter = order_by_strs.begin(); |
iter != order_by_strs.end(); ++iter) { |
std::string term_str = *iter; |
@@ -493,13 +485,13 @@ void CompileDownloadQueryOrderBy( |
direction = DownloadQuery::DESCENDING; |
term_str = term_str.substr(1); |
} |
- SortTypeMap::const_iterator sorter_type = |
- sorter_types.Get().find(term_str); |
- if (sorter_type == sorter_types.Get().end()) { |
+ const DownloadQuerySortTypePair* found_sort = |
+ FindDownloadSortTypeByString(term_str.c_str()); |
+ if (!found_sort) { |
*error = errors::kInvalidOrderBy; |
return; |
} |
- query->AddSorter(sorter_type->second, direction); |
+ query->AddSorter(found_sort->second, direction); |
} |
} |
@@ -509,13 +501,6 @@ void RunDownloadQuery( |
DownloadManager* incognito_manager, |
std::string* error, |
DownloadQuery::DownloadVector* results) { |
- // TODO(benjhayden): Consider switching from LazyInstance to explicit string |
- // comparisons. |
- static base::LazyInstance<FilterTypeMap>::DestructorAtExit filter_types = |
- LAZY_INSTANCE_INITIALIZER; |
- if (filter_types.Get().empty()) |
- InitFilterTypeMap(filter_types.Pointer()); |
- |
DownloadQuery query_out; |
size_t limit = 1000; |
@@ -559,10 +544,11 @@ void RunDownloadQuery( |
std::unique_ptr<base::DictionaryValue> query_in_value(query_in.ToValue()); |
for (base::DictionaryValue::Iterator query_json_field(*query_in_value); |
!query_json_field.IsAtEnd(); query_json_field.Advance()) { |
- FilterTypeMap::const_iterator filter_type = |
- filter_types.Get().find(query_json_field.key()); |
- if (filter_type != filter_types.Get().end()) { |
- if (!query_out.AddFilter(filter_type->second, query_json_field.value())) { |
+ const DownloadQueryFilterTypePair* found_filter = |
+ FindDownloadFilterTypeByString(query_json_field.key().c_str()); |
+ if (found_filter) { |
+ if (!query_out.AddFilter(found_filter->second, |
+ query_json_field.value())) { |
*error = errors::kInvalidFilter; |
return; |
} |
@@ -1967,4 +1953,50 @@ void ExtensionDownloadsEventRouter::CheckForHistoryFilesRemoval() { |
manager->CheckForHistoryFilesRemoval(); |
} |
+const DownloadQueryFilterTypePair* FindDownloadFilterTypeByString( |
+ const char* key) { |
+ struct FilterTypeKeyLess { |
+ bool operator()(const DownloadQueryFilterTypePair& a, const char* b) const { |
+ return strcmp(a.first, b) < 0; |
+ } |
+ }; |
+ |
+ const DownloadQueryFilterTypePair* found = |
+ std::lower_bound(std::begin(kFilterTypes), std::end(kFilterTypes), key, |
+ FilterTypeKeyLess()); |
+ if (found == std::end(kFilterTypes) || strcmp(key, found->first) != 0) |
+ return nullptr; |
+ return found; |
+} |
+ |
+const DownloadQuerySortTypePair* FindDownloadSortTypeByString(const char* key) { |
+ struct SortTypeKeyLess { |
+ bool operator()(const DownloadQuerySortTypePair& a, const char* b) const { |
+ return strcmp(a.first, b) < 0; |
+ } |
+ }; |
+ |
+ const DownloadQuerySortTypePair* found = std::lower_bound( |
+ std::begin(kSortTypes), std::end(kSortTypes), key, SortTypeKeyLess()); |
+ if (found == std::end(kSortTypes) || strcmp(key, found->first) != 0) |
+ return nullptr; |
+ return found; |
+} |
+ |
+const DownloadQueryFilterTypePair* DownloadQueryFilterTypeBeginForTest() { |
+ return std::begin(kFilterTypes); |
+} |
+ |
+const DownloadQueryFilterTypePair* DownloadQueryFilterTypeEndForTest() { |
+ return std::end(kFilterTypes); |
+} |
+ |
+const DownloadQuerySortTypePair* DownloadQuerySortTypeBeginForTest() { |
+ return std::begin(kSortTypes); |
+} |
+ |
+const DownloadQuerySortTypePair* DownloadQuerySortTypeEndForTest() { |
+ return std::end(kSortTypes); |
+} |
+ |
} // namespace extensions |