1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/components/places/nsNavHistoryQuery.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1716 @@ 1.4 +//* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/** 1.10 + * This file contains the definitions of nsNavHistoryQuery, 1.11 + * nsNavHistoryQueryOptions, and those functions in nsINavHistory that directly 1.12 + * support queries (specifically QueryStringToQueries and QueriesToQueryString). 1.13 + */ 1.14 + 1.15 +#include "mozilla/DebugOnly.h" 1.16 + 1.17 +#include "nsNavHistory.h" 1.18 +#include "nsNavBookmarks.h" 1.19 +#include "nsEscape.h" 1.20 +#include "nsCOMArray.h" 1.21 +#include "nsNetUtil.h" 1.22 +#include "nsTArray.h" 1.23 +#include "prprf.h" 1.24 + 1.25 +using namespace mozilla; 1.26 + 1.27 +class QueryKeyValuePair 1.28 +{ 1.29 +public: 1.30 + 1.31 + // QueryKeyValuePair 1.32 + // 1.33 + // 01234567890 1.34 + // input : qwerty&key=value&qwerty 1.35 + // ^ ^ ^ 1.36 + // aKeyBegin | aPastEnd (may point to null terminator) 1.37 + // aEquals 1.38 + // 1.39 + // Special case: if aKeyBegin == aEquals, then there is only one string 1.40 + // and no equal sign, so we treat the entire thing as a key with no value 1.41 + 1.42 + QueryKeyValuePair(const nsCSubstring& aSource, int32_t aKeyBegin, 1.43 + int32_t aEquals, int32_t aPastEnd) 1.44 + { 1.45 + if (aEquals == aKeyBegin) 1.46 + aEquals = aPastEnd; 1.47 + key = Substring(aSource, aKeyBegin, aEquals - aKeyBegin); 1.48 + if (aPastEnd - aEquals > 0) 1.49 + value = Substring(aSource, aEquals + 1, aPastEnd - aEquals - 1); 1.50 + } 1.51 + nsCString key; 1.52 + nsCString value; 1.53 +}; 1.54 + 1.55 +static nsresult TokenizeQueryString(const nsACString& aQuery, 1.56 + nsTArray<QueryKeyValuePair>* aTokens); 1.57 +static nsresult ParseQueryBooleanString(const nsCString& aString, 1.58 + bool* aValue); 1.59 + 1.60 +// query getters 1.61 +typedef NS_STDCALL_FUNCPROTO(nsresult, BoolQueryGetter, nsINavHistoryQuery, 1.62 + GetOnlyBookmarked, (bool*)); 1.63 +typedef NS_STDCALL_FUNCPROTO(nsresult, Uint32QueryGetter, nsINavHistoryQuery, 1.64 + GetBeginTimeReference, (uint32_t*)); 1.65 +typedef NS_STDCALL_FUNCPROTO(nsresult, Int64QueryGetter, nsINavHistoryQuery, 1.66 + GetBeginTime, (int64_t*)); 1.67 +static void AppendBoolKeyValueIfTrue(nsACString& aString, 1.68 + const nsCString& aName, 1.69 + nsINavHistoryQuery* aQuery, 1.70 + BoolQueryGetter getter); 1.71 +static void AppendUint32KeyValueIfNonzero(nsACString& aString, 1.72 + const nsCString& aName, 1.73 + nsINavHistoryQuery* aQuery, 1.74 + Uint32QueryGetter getter); 1.75 +static void AppendInt64KeyValueIfNonzero(nsACString& aString, 1.76 + const nsCString& aName, 1.77 + nsINavHistoryQuery* aQuery, 1.78 + Int64QueryGetter getter); 1.79 + 1.80 +// query setters 1.81 +typedef NS_STDCALL_FUNCPROTO(nsresult, BoolQuerySetter, nsINavHistoryQuery, 1.82 + SetOnlyBookmarked, (bool)); 1.83 +typedef NS_STDCALL_FUNCPROTO(nsresult, Uint32QuerySetter, nsINavHistoryQuery, 1.84 + SetBeginTimeReference, (uint32_t)); 1.85 +typedef NS_STDCALL_FUNCPROTO(nsresult, Int64QuerySetter, nsINavHistoryQuery, 1.86 + SetBeginTime, (int64_t)); 1.87 +static void SetQueryKeyBool(const nsCString& aValue, nsINavHistoryQuery* aQuery, 1.88 + BoolQuerySetter setter); 1.89 +static void SetQueryKeyUint32(const nsCString& aValue, nsINavHistoryQuery* aQuery, 1.90 + Uint32QuerySetter setter); 1.91 +static void SetQueryKeyInt64(const nsCString& aValue, nsINavHistoryQuery* aQuery, 1.92 + Int64QuerySetter setter); 1.93 + 1.94 +// options setters 1.95 +typedef NS_STDCALL_FUNCPROTO(nsresult, BoolOptionsSetter, 1.96 + nsINavHistoryQueryOptions, 1.97 + SetExpandQueries, (bool)); 1.98 +typedef NS_STDCALL_FUNCPROTO(nsresult, Uint32OptionsSetter, 1.99 + nsINavHistoryQueryOptions, 1.100 + SetMaxResults, (uint32_t)); 1.101 +typedef NS_STDCALL_FUNCPROTO(nsresult, Uint16OptionsSetter, 1.102 + nsINavHistoryQueryOptions, 1.103 + SetResultType, (uint16_t)); 1.104 +static void SetOptionsKeyBool(const nsCString& aValue, 1.105 + nsINavHistoryQueryOptions* aOptions, 1.106 + BoolOptionsSetter setter); 1.107 +static void SetOptionsKeyUint16(const nsCString& aValue, 1.108 + nsINavHistoryQueryOptions* aOptions, 1.109 + Uint16OptionsSetter setter); 1.110 +static void SetOptionsKeyUint32(const nsCString& aValue, 1.111 + nsINavHistoryQueryOptions* aOptions, 1.112 + Uint32OptionsSetter setter); 1.113 + 1.114 +// Components of a query string. 1.115 +// Note that query strings are also generated in nsNavBookmarks::GetFolderURI 1.116 +// for performance reasons, so if you change these values, change that, too. 1.117 +#define QUERYKEY_BEGIN_TIME "beginTime" 1.118 +#define QUERYKEY_BEGIN_TIME_REFERENCE "beginTimeRef" 1.119 +#define QUERYKEY_END_TIME "endTime" 1.120 +#define QUERYKEY_END_TIME_REFERENCE "endTimeRef" 1.121 +#define QUERYKEY_SEARCH_TERMS "terms" 1.122 +#define QUERYKEY_MIN_VISITS "minVisits" 1.123 +#define QUERYKEY_MAX_VISITS "maxVisits" 1.124 +#define QUERYKEY_ONLY_BOOKMARKED "onlyBookmarked" 1.125 +#define QUERYKEY_DOMAIN_IS_HOST "domainIsHost" 1.126 +#define QUERYKEY_DOMAIN "domain" 1.127 +#define QUERYKEY_FOLDER "folder" 1.128 +#define QUERYKEY_NOTANNOTATION "!annotation" 1.129 +#define QUERYKEY_ANNOTATION "annotation" 1.130 +#define QUERYKEY_URI "uri" 1.131 +#define QUERYKEY_URIISPREFIX "uriIsPrefix" 1.132 +#define QUERYKEY_SEPARATOR "OR" 1.133 +#define QUERYKEY_GROUP "group" 1.134 +#define QUERYKEY_SORT "sort" 1.135 +#define QUERYKEY_SORTING_ANNOTATION "sortingAnnotation" 1.136 +#define QUERYKEY_RESULT_TYPE "type" 1.137 +#define QUERYKEY_EXCLUDE_ITEMS "excludeItems" 1.138 +#define QUERYKEY_EXCLUDE_QUERIES "excludeQueries" 1.139 +#define QUERYKEY_EXCLUDE_READ_ONLY_FOLDERS "excludeReadOnlyFolders" 1.140 +#define QUERYKEY_EXPAND_QUERIES "expandQueries" 1.141 +#define QUERYKEY_FORCE_ORIGINAL_TITLE "originalTitle" 1.142 +#define QUERYKEY_INCLUDE_HIDDEN "includeHidden" 1.143 +#define QUERYKEY_MAX_RESULTS "maxResults" 1.144 +#define QUERYKEY_QUERY_TYPE "queryType" 1.145 +#define QUERYKEY_TAG "tag" 1.146 +#define QUERYKEY_NOTTAGS "!tags" 1.147 +#define QUERYKEY_ASYNC_ENABLED "asyncEnabled" 1.148 +#define QUERYKEY_TRANSITION "transition" 1.149 + 1.150 +inline void AppendAmpersandIfNonempty(nsACString& aString) 1.151 +{ 1.152 + if (! aString.IsEmpty()) 1.153 + aString.Append('&'); 1.154 +} 1.155 +inline void AppendInt16(nsACString& str, int16_t i) 1.156 +{ 1.157 + nsAutoCString tmp; 1.158 + tmp.AppendInt(i); 1.159 + str.Append(tmp); 1.160 +} 1.161 +inline void AppendInt32(nsACString& str, int32_t i) 1.162 +{ 1.163 + nsAutoCString tmp; 1.164 + tmp.AppendInt(i); 1.165 + str.Append(tmp); 1.166 +} 1.167 +inline void AppendInt64(nsACString& str, int64_t i) 1.168 +{ 1.169 + nsCString tmp; 1.170 + tmp.AppendInt(i); 1.171 + str.Append(tmp); 1.172 +} 1.173 + 1.174 +namespace PlacesFolderConversion { 1.175 + #define PLACES_ROOT_FOLDER "PLACES_ROOT" 1.176 + #define BOOKMARKS_MENU_FOLDER "BOOKMARKS_MENU" 1.177 + #define TAGS_FOLDER "TAGS" 1.178 + #define UNFILED_BOOKMARKS_FOLDER "UNFILED_BOOKMARKS" 1.179 + #define TOOLBAR_FOLDER "TOOLBAR" 1.180 + 1.181 + /** 1.182 + * Converts a folder name to a folder id. 1.183 + * 1.184 + * @param aName 1.185 + * The name of the folder to convert to a folder id. 1.186 + * @returns the folder id if aName is a recognizable name, -1 otherwise. 1.187 + */ 1.188 + inline int64_t DecodeFolder(const nsCString &aName) 1.189 + { 1.190 + nsNavBookmarks *bs = nsNavBookmarks::GetBookmarksService(); 1.191 + NS_ENSURE_TRUE(bs, false); 1.192 + int64_t folderID = -1; 1.193 + 1.194 + if (aName.EqualsLiteral(PLACES_ROOT_FOLDER)) 1.195 + (void)bs->GetPlacesRoot(&folderID); 1.196 + else if (aName.EqualsLiteral(BOOKMARKS_MENU_FOLDER)) 1.197 + (void)bs->GetBookmarksMenuFolder(&folderID); 1.198 + else if (aName.EqualsLiteral(TAGS_FOLDER)) 1.199 + (void)bs->GetTagsFolder(&folderID); 1.200 + else if (aName.EqualsLiteral(UNFILED_BOOKMARKS_FOLDER)) 1.201 + (void)bs->GetUnfiledBookmarksFolder(&folderID); 1.202 + else if (aName.EqualsLiteral(TOOLBAR_FOLDER)) 1.203 + (void)bs->GetToolbarFolder(&folderID); 1.204 + 1.205 + return folderID; 1.206 + } 1.207 + 1.208 + /** 1.209 + * Converts a folder id to a named constant, or a string representation of the 1.210 + * folder id if there is no named constant for the folder, and appends it to 1.211 + * aQuery. 1.212 + * 1.213 + * @param aQuery 1.214 + * The string to append the folder string to. This is generally a 1.215 + * query string, but could really be anything. 1.216 + * @param aFolderID 1.217 + * The folder ID to convert to the proper named constant. 1.218 + */ 1.219 + inline nsresult AppendFolder(nsCString &aQuery, int64_t aFolderID) 1.220 + { 1.221 + nsNavBookmarks *bs = nsNavBookmarks::GetBookmarksService(); 1.222 + NS_ENSURE_STATE(bs); 1.223 + int64_t folderID; 1.224 + 1.225 + if (NS_SUCCEEDED(bs->GetPlacesRoot(&folderID)) && 1.226 + aFolderID == folderID) { 1.227 + aQuery.AppendLiteral(PLACES_ROOT_FOLDER); 1.228 + } 1.229 + else if (NS_SUCCEEDED(bs->GetBookmarksMenuFolder(&folderID)) && 1.230 + aFolderID == folderID) { 1.231 + aQuery.AppendLiteral(BOOKMARKS_MENU_FOLDER); 1.232 + } 1.233 + else if (NS_SUCCEEDED(bs->GetTagsFolder(&folderID)) && 1.234 + aFolderID == folderID) { 1.235 + aQuery.AppendLiteral(TAGS_FOLDER); 1.236 + } 1.237 + else if (NS_SUCCEEDED(bs->GetUnfiledBookmarksFolder(&folderID)) && 1.238 + aFolderID == folderID) { 1.239 + aQuery.AppendLiteral(UNFILED_BOOKMARKS_FOLDER); 1.240 + } 1.241 + else if (NS_SUCCEEDED(bs->GetToolbarFolder(&folderID)) && 1.242 + aFolderID == folderID) { 1.243 + aQuery.AppendLiteral(TOOLBAR_FOLDER); 1.244 + } 1.245 + else { 1.246 + // It wasn't one of our named constants, so just convert it to a string. 1.247 + aQuery.AppendInt(aFolderID); 1.248 + } 1.249 + 1.250 + return NS_OK; 1.251 + } 1.252 +} 1.253 + 1.254 +// nsNavHistory::QueryStringToQueries 1.255 +// 1.256 +// From C++ places code, you should use QueryStringToQueryArray, this is 1.257 +// the harder-to-use XPCOM version. 1.258 + 1.259 +NS_IMETHODIMP 1.260 +nsNavHistory::QueryStringToQueries(const nsACString& aQueryString, 1.261 + nsINavHistoryQuery*** aQueries, 1.262 + uint32_t* aResultCount, 1.263 + nsINavHistoryQueryOptions** aOptions) 1.264 +{ 1.265 + NS_ENSURE_ARG_POINTER(aQueries); 1.266 + NS_ENSURE_ARG_POINTER(aResultCount); 1.267 + NS_ENSURE_ARG_POINTER(aOptions); 1.268 + 1.269 + *aQueries = nullptr; 1.270 + *aResultCount = 0; 1.271 + nsCOMPtr<nsNavHistoryQueryOptions> options; 1.272 + nsCOMArray<nsNavHistoryQuery> queries; 1.273 + nsresult rv = QueryStringToQueryArray(aQueryString, &queries, 1.274 + getter_AddRefs(options)); 1.275 + NS_ENSURE_SUCCESS(rv, rv); 1.276 + 1.277 + *aResultCount = queries.Count(); 1.278 + if (queries.Count() > 0) { 1.279 + // convert COM array to raw 1.280 + *aQueries = static_cast<nsINavHistoryQuery**> 1.281 + (nsMemory::Alloc(sizeof(nsINavHistoryQuery*) * queries.Count())); 1.282 + NS_ENSURE_TRUE(*aQueries, NS_ERROR_OUT_OF_MEMORY); 1.283 + for (int32_t i = 0; i < queries.Count(); i ++) { 1.284 + (*aQueries)[i] = queries[i]; 1.285 + NS_ADDREF((*aQueries)[i]); 1.286 + } 1.287 + } 1.288 + NS_ADDREF(*aOptions = options); 1.289 + return NS_OK; 1.290 +} 1.291 + 1.292 + 1.293 +// nsNavHistory::QueryStringToQueryArray 1.294 +// 1.295 +// An internal version of QueryStringToQueries that fills a COM array for 1.296 +// ease-of-use. 1.297 + 1.298 +nsresult 1.299 +nsNavHistory::QueryStringToQueryArray(const nsACString& aQueryString, 1.300 + nsCOMArray<nsNavHistoryQuery>* aQueries, 1.301 + nsNavHistoryQueryOptions** aOptions) 1.302 +{ 1.303 + nsresult rv; 1.304 + aQueries->Clear(); 1.305 + *aOptions = nullptr; 1.306 + 1.307 + nsRefPtr<nsNavHistoryQueryOptions> options(new nsNavHistoryQueryOptions()); 1.308 + if (! options) 1.309 + return NS_ERROR_OUT_OF_MEMORY; 1.310 + 1.311 + nsTArray<QueryKeyValuePair> tokens; 1.312 + rv = TokenizeQueryString(aQueryString, &tokens); 1.313 + NS_ENSURE_SUCCESS(rv, rv); 1.314 + 1.315 + rv = TokensToQueries(tokens, aQueries, options); 1.316 + if (NS_FAILED(rv)) { 1.317 + NS_WARNING("Unable to parse the query string: "); 1.318 + NS_WARNING(PromiseFlatCString(aQueryString).get()); 1.319 + return rv; 1.320 + } 1.321 + 1.322 + NS_ADDREF(*aOptions = options); 1.323 + return NS_OK; 1.324 +} 1.325 + 1.326 + 1.327 +// nsNavHistory::QueriesToQueryString 1.328 + 1.329 +NS_IMETHODIMP 1.330 +nsNavHistory::QueriesToQueryString(nsINavHistoryQuery **aQueries, 1.331 + uint32_t aQueryCount, 1.332 + nsINavHistoryQueryOptions* aOptions, 1.333 + nsACString& aQueryString) 1.334 +{ 1.335 + NS_ENSURE_ARG(aQueries); 1.336 + NS_ENSURE_ARG(aOptions); 1.337 + 1.338 + nsCOMPtr<nsNavHistoryQueryOptions> options = do_QueryInterface(aOptions); 1.339 + NS_ENSURE_TRUE(options, NS_ERROR_INVALID_ARG); 1.340 + 1.341 + nsAutoCString queryString; 1.342 + for (uint32_t queryIndex = 0; queryIndex < aQueryCount; queryIndex ++) { 1.343 + nsCOMPtr<nsNavHistoryQuery> query = do_QueryInterface(aQueries[queryIndex]); 1.344 + if (queryIndex > 0) { 1.345 + AppendAmpersandIfNonempty(queryString); 1.346 + queryString += NS_LITERAL_CSTRING(QUERYKEY_SEPARATOR); 1.347 + } 1.348 + 1.349 + bool hasIt; 1.350 + 1.351 + // begin time 1.352 + query->GetHasBeginTime(&hasIt); 1.353 + if (hasIt) { 1.354 + AppendInt64KeyValueIfNonzero(queryString, 1.355 + NS_LITERAL_CSTRING(QUERYKEY_BEGIN_TIME), 1.356 + query, &nsINavHistoryQuery::GetBeginTime); 1.357 + AppendUint32KeyValueIfNonzero(queryString, 1.358 + NS_LITERAL_CSTRING(QUERYKEY_BEGIN_TIME_REFERENCE), 1.359 + query, &nsINavHistoryQuery::GetBeginTimeReference); 1.360 + } 1.361 + 1.362 + // end time 1.363 + query->GetHasEndTime(&hasIt); 1.364 + if (hasIt) { 1.365 + AppendInt64KeyValueIfNonzero(queryString, 1.366 + NS_LITERAL_CSTRING(QUERYKEY_END_TIME), 1.367 + query, &nsINavHistoryQuery::GetEndTime); 1.368 + AppendUint32KeyValueIfNonzero(queryString, 1.369 + NS_LITERAL_CSTRING(QUERYKEY_END_TIME_REFERENCE), 1.370 + query, &nsINavHistoryQuery::GetEndTimeReference); 1.371 + } 1.372 + 1.373 + // search terms 1.374 + query->GetHasSearchTerms(&hasIt); 1.375 + if (hasIt) { 1.376 + nsAutoString searchTerms; 1.377 + query->GetSearchTerms(searchTerms); 1.378 + nsCString escapedTerms; 1.379 + if (! NS_Escape(NS_ConvertUTF16toUTF8(searchTerms), escapedTerms, 1.380 + url_XAlphas)) 1.381 + return NS_ERROR_OUT_OF_MEMORY; 1.382 + 1.383 + AppendAmpersandIfNonempty(queryString); 1.384 + queryString += NS_LITERAL_CSTRING(QUERYKEY_SEARCH_TERMS "="); 1.385 + queryString += escapedTerms; 1.386 + } 1.387 + 1.388 + // min and max visits 1.389 + int32_t minVisits; 1.390 + if (NS_SUCCEEDED(query->GetMinVisits(&minVisits)) && minVisits >= 0) { 1.391 + AppendAmpersandIfNonempty(queryString); 1.392 + queryString.Append(NS_LITERAL_CSTRING(QUERYKEY_MIN_VISITS "=")); 1.393 + AppendInt32(queryString, minVisits); 1.394 + } 1.395 + 1.396 + int32_t maxVisits; 1.397 + if (NS_SUCCEEDED(query->GetMaxVisits(&maxVisits)) && maxVisits >= 0) { 1.398 + AppendAmpersandIfNonempty(queryString); 1.399 + queryString.Append(NS_LITERAL_CSTRING(QUERYKEY_MAX_VISITS "=")); 1.400 + AppendInt32(queryString, maxVisits); 1.401 + } 1.402 + 1.403 + // only bookmarked 1.404 + AppendBoolKeyValueIfTrue(queryString, 1.405 + NS_LITERAL_CSTRING(QUERYKEY_ONLY_BOOKMARKED), 1.406 + query, &nsINavHistoryQuery::GetOnlyBookmarked); 1.407 + 1.408 + // domain (+ is host), only call if hasDomain, which means non-IsVoid 1.409 + // this means we may get an empty string for the domain in the result, 1.410 + // which is valid 1.411 + query->GetHasDomain(&hasIt); 1.412 + if (hasIt) { 1.413 + AppendBoolKeyValueIfTrue(queryString, 1.414 + NS_LITERAL_CSTRING(QUERYKEY_DOMAIN_IS_HOST), 1.415 + query, &nsINavHistoryQuery::GetDomainIsHost); 1.416 + nsAutoCString domain; 1.417 + nsresult rv = query->GetDomain(domain); 1.418 + NS_ENSURE_SUCCESS(rv, rv); 1.419 + nsCString escapedDomain; 1.420 + bool success = NS_Escape(domain, escapedDomain, url_XAlphas); 1.421 + NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY); 1.422 + 1.423 + AppendAmpersandIfNonempty(queryString); 1.424 + queryString.Append(NS_LITERAL_CSTRING(QUERYKEY_DOMAIN "=")); 1.425 + queryString.Append(escapedDomain); 1.426 + } 1.427 + 1.428 + // uri 1.429 + query->GetHasUri(&hasIt); 1.430 + if (hasIt) { 1.431 + AppendBoolKeyValueIfTrue(aQueryString, 1.432 + NS_LITERAL_CSTRING(QUERYKEY_URIISPREFIX), 1.433 + query, &nsINavHistoryQuery::GetUriIsPrefix); 1.434 + nsCOMPtr<nsIURI> uri; 1.435 + query->GetUri(getter_AddRefs(uri)); 1.436 + NS_ENSURE_TRUE(uri, NS_ERROR_FAILURE); // hasURI should tell is if invalid 1.437 + nsAutoCString uriSpec; 1.438 + nsresult rv = uri->GetSpec(uriSpec); 1.439 + NS_ENSURE_SUCCESS(rv, rv); 1.440 + nsAutoCString escaped; 1.441 + bool success = NS_Escape(uriSpec, escaped, url_XAlphas); 1.442 + NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY); 1.443 + 1.444 + AppendAmpersandIfNonempty(queryString); 1.445 + queryString.Append(NS_LITERAL_CSTRING(QUERYKEY_URI "=")); 1.446 + queryString.Append(escaped); 1.447 + } 1.448 + 1.449 + // annotation 1.450 + query->GetHasAnnotation(&hasIt); 1.451 + if (hasIt) { 1.452 + AppendAmpersandIfNonempty(queryString); 1.453 + bool annotationIsNot; 1.454 + query->GetAnnotationIsNot(&annotationIsNot); 1.455 + if (annotationIsNot) 1.456 + queryString.AppendLiteral(QUERYKEY_NOTANNOTATION "="); 1.457 + else 1.458 + queryString.AppendLiteral(QUERYKEY_ANNOTATION "="); 1.459 + nsAutoCString annot; 1.460 + query->GetAnnotation(annot); 1.461 + nsAutoCString escaped; 1.462 + bool success = NS_Escape(annot, escaped, url_XAlphas); 1.463 + NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY); 1.464 + queryString.Append(escaped); 1.465 + } 1.466 + 1.467 + // folders 1.468 + int64_t *folders = nullptr; 1.469 + uint32_t folderCount = 0; 1.470 + query->GetFolders(&folderCount, &folders); 1.471 + for (uint32_t i = 0; i < folderCount; ++i) { 1.472 + AppendAmpersandIfNonempty(queryString); 1.473 + queryString += NS_LITERAL_CSTRING(QUERYKEY_FOLDER "="); 1.474 + nsresult rv = PlacesFolderConversion::AppendFolder(queryString, folders[i]); 1.475 + NS_ENSURE_SUCCESS(rv, rv); 1.476 + } 1.477 + nsMemory::Free(folders); 1.478 + 1.479 + // tags 1.480 + const nsTArray<nsString> &tags = query->Tags(); 1.481 + for (uint32_t i = 0; i < tags.Length(); ++i) { 1.482 + nsAutoCString escapedTag; 1.483 + if (!NS_Escape(NS_ConvertUTF16toUTF8(tags[i]), escapedTag, url_XAlphas)) 1.484 + return NS_ERROR_OUT_OF_MEMORY; 1.485 + 1.486 + AppendAmpersandIfNonempty(queryString); 1.487 + queryString += NS_LITERAL_CSTRING(QUERYKEY_TAG "="); 1.488 + queryString += escapedTag; 1.489 + } 1.490 + AppendBoolKeyValueIfTrue(queryString, 1.491 + NS_LITERAL_CSTRING(QUERYKEY_NOTTAGS), 1.492 + query, 1.493 + &nsINavHistoryQuery::GetTagsAreNot); 1.494 + 1.495 + // transitions 1.496 + const nsTArray<uint32_t>& transitions = query->Transitions(); 1.497 + for (uint32_t i = 0; i < transitions.Length(); ++i) { 1.498 + AppendAmpersandIfNonempty(queryString); 1.499 + queryString += NS_LITERAL_CSTRING(QUERYKEY_TRANSITION "="); 1.500 + AppendInt64(queryString, transitions[i]); 1.501 + } 1.502 + } 1.503 + 1.504 + // sorting 1.505 + if (options->SortingMode() != nsINavHistoryQueryOptions::SORT_BY_NONE) { 1.506 + AppendAmpersandIfNonempty(queryString); 1.507 + queryString += NS_LITERAL_CSTRING(QUERYKEY_SORT "="); 1.508 + AppendInt16(queryString, options->SortingMode()); 1.509 + if (options->SortingMode() == nsINavHistoryQueryOptions::SORT_BY_ANNOTATION_DESCENDING || 1.510 + options->SortingMode() == nsINavHistoryQueryOptions::SORT_BY_ANNOTATION_ASCENDING) { 1.511 + // sortingAnnotation 1.512 + nsAutoCString sortingAnnotation; 1.513 + if (NS_SUCCEEDED(options->GetSortingAnnotation(sortingAnnotation))) { 1.514 + nsCString escaped; 1.515 + if (!NS_Escape(sortingAnnotation, escaped, url_XAlphas)) 1.516 + return NS_ERROR_OUT_OF_MEMORY; 1.517 + AppendAmpersandIfNonempty(queryString); 1.518 + queryString += NS_LITERAL_CSTRING(QUERYKEY_SORTING_ANNOTATION "="); 1.519 + queryString.Append(escaped); 1.520 + } 1.521 + } 1.522 + } 1.523 + 1.524 + // result type 1.525 + if (options->ResultType() != nsINavHistoryQueryOptions::RESULTS_AS_URI) { 1.526 + AppendAmpersandIfNonempty(queryString); 1.527 + queryString += NS_LITERAL_CSTRING(QUERYKEY_RESULT_TYPE "="); 1.528 + AppendInt16(queryString, options->ResultType()); 1.529 + } 1.530 + 1.531 + // exclude items 1.532 + if (options->ExcludeItems()) { 1.533 + AppendAmpersandIfNonempty(queryString); 1.534 + queryString += NS_LITERAL_CSTRING(QUERYKEY_EXCLUDE_ITEMS "=1"); 1.535 + } 1.536 + 1.537 + // exclude queries 1.538 + if (options->ExcludeQueries()) { 1.539 + AppendAmpersandIfNonempty(queryString); 1.540 + queryString += NS_LITERAL_CSTRING(QUERYKEY_EXCLUDE_QUERIES "=1"); 1.541 + } 1.542 + 1.543 + // exclude read only folders 1.544 + if (options->ExcludeReadOnlyFolders()) { 1.545 + AppendAmpersandIfNonempty(queryString); 1.546 + queryString += NS_LITERAL_CSTRING(QUERYKEY_EXCLUDE_READ_ONLY_FOLDERS "=1"); 1.547 + } 1.548 + 1.549 + // expand queries 1.550 + if (!options->ExpandQueries()) { 1.551 + AppendAmpersandIfNonempty(queryString); 1.552 + queryString += NS_LITERAL_CSTRING(QUERYKEY_EXPAND_QUERIES "=0"); 1.553 + } 1.554 + 1.555 + // include hidden 1.556 + if (options->IncludeHidden()) { 1.557 + AppendAmpersandIfNonempty(queryString); 1.558 + queryString += NS_LITERAL_CSTRING(QUERYKEY_INCLUDE_HIDDEN "=1"); 1.559 + } 1.560 + 1.561 + // max results 1.562 + if (options->MaxResults()) { 1.563 + AppendAmpersandIfNonempty(queryString); 1.564 + queryString += NS_LITERAL_CSTRING(QUERYKEY_MAX_RESULTS "="); 1.565 + AppendInt32(queryString, options->MaxResults()); 1.566 + } 1.567 + 1.568 + // queryType 1.569 + if (options->QueryType() != nsINavHistoryQueryOptions::QUERY_TYPE_HISTORY) { 1.570 + AppendAmpersandIfNonempty(queryString); 1.571 + queryString += NS_LITERAL_CSTRING(QUERYKEY_QUERY_TYPE "="); 1.572 + AppendInt16(queryString, options->QueryType()); 1.573 + } 1.574 + 1.575 + // async enabled 1.576 + if (options->AsyncEnabled()) { 1.577 + AppendAmpersandIfNonempty(queryString); 1.578 + queryString += NS_LITERAL_CSTRING(QUERYKEY_ASYNC_ENABLED "=1"); 1.579 + } 1.580 + 1.581 + aQueryString.Assign(NS_LITERAL_CSTRING("place:") + queryString); 1.582 + return NS_OK; 1.583 +} 1.584 + 1.585 + 1.586 +// TokenizeQueryString 1.587 + 1.588 +nsresult 1.589 +TokenizeQueryString(const nsACString& aQuery, 1.590 + nsTArray<QueryKeyValuePair>* aTokens) 1.591 +{ 1.592 + // Strip off the "place:" prefix 1.593 + const uint32_t prefixlen = 6; // = strlen("place:"); 1.594 + nsCString query; 1.595 + if (aQuery.Length() >= prefixlen && 1.596 + Substring(aQuery, 0, prefixlen).EqualsLiteral("place:")) 1.597 + query = Substring(aQuery, prefixlen); 1.598 + else 1.599 + query = aQuery; 1.600 + 1.601 + int32_t keyFirstIndex = 0; 1.602 + int32_t equalsIndex = 0; 1.603 + for (uint32_t i = 0; i < query.Length(); i ++) { 1.604 + if (query[i] == '&') { 1.605 + // new clause, save last one 1.606 + if (i - keyFirstIndex > 1) { 1.607 + if (! aTokens->AppendElement(QueryKeyValuePair(query, keyFirstIndex, 1.608 + equalsIndex, i))) 1.609 + return NS_ERROR_OUT_OF_MEMORY; 1.610 + } 1.611 + keyFirstIndex = equalsIndex = i + 1; 1.612 + } else if (query[i] == '=') { 1.613 + equalsIndex = i; 1.614 + } 1.615 + } 1.616 + 1.617 + // handle last pair, if any 1.618 + if (query.Length() - keyFirstIndex > 1) { 1.619 + if (! aTokens->AppendElement(QueryKeyValuePair(query, keyFirstIndex, 1.620 + equalsIndex, query.Length()))) 1.621 + return NS_ERROR_OUT_OF_MEMORY; 1.622 + } 1.623 + return NS_OK; 1.624 +} 1.625 + 1.626 +// nsNavHistory::TokensToQueries 1.627 + 1.628 +nsresult 1.629 +nsNavHistory::TokensToQueries(const nsTArray<QueryKeyValuePair>& aTokens, 1.630 + nsCOMArray<nsNavHistoryQuery>* aQueries, 1.631 + nsNavHistoryQueryOptions* aOptions) 1.632 +{ 1.633 + nsresult rv; 1.634 + 1.635 + nsCOMPtr<nsNavHistoryQuery> query(new nsNavHistoryQuery()); 1.636 + if (! query) 1.637 + return NS_ERROR_OUT_OF_MEMORY; 1.638 + if (! aQueries->AppendObject(query)) 1.639 + return NS_ERROR_OUT_OF_MEMORY; 1.640 + 1.641 + if (aTokens.Length() == 0) 1.642 + return NS_OK; // nothing to do 1.643 + 1.644 + nsTArray<int64_t> folders; 1.645 + nsTArray<nsString> tags; 1.646 + nsTArray<uint32_t> transitions; 1.647 + for (uint32_t i = 0; i < aTokens.Length(); i ++) { 1.648 + const QueryKeyValuePair& kvp = aTokens[i]; 1.649 + 1.650 + // begin time 1.651 + if (kvp.key.EqualsLiteral(QUERYKEY_BEGIN_TIME)) { 1.652 + SetQueryKeyInt64(kvp.value, query, &nsINavHistoryQuery::SetBeginTime); 1.653 + 1.654 + // begin time reference 1.655 + } else if (kvp.key.EqualsLiteral(QUERYKEY_BEGIN_TIME_REFERENCE)) { 1.656 + SetQueryKeyUint32(kvp.value, query, &nsINavHistoryQuery::SetBeginTimeReference); 1.657 + 1.658 + // end time 1.659 + } else if (kvp.key.EqualsLiteral(QUERYKEY_END_TIME)) { 1.660 + SetQueryKeyInt64(kvp.value, query, &nsINavHistoryQuery::SetEndTime); 1.661 + 1.662 + // end time reference 1.663 + } else if (kvp.key.EqualsLiteral(QUERYKEY_END_TIME_REFERENCE)) { 1.664 + SetQueryKeyUint32(kvp.value, query, &nsINavHistoryQuery::SetEndTimeReference); 1.665 + 1.666 + // search terms 1.667 + } else if (kvp.key.EqualsLiteral(QUERYKEY_SEARCH_TERMS)) { 1.668 + nsCString unescapedTerms = kvp.value; 1.669 + NS_UnescapeURL(unescapedTerms); // modifies input 1.670 + rv = query->SetSearchTerms(NS_ConvertUTF8toUTF16(unescapedTerms)); 1.671 + NS_ENSURE_SUCCESS(rv, rv); 1.672 + 1.673 + // min visits 1.674 + } else if (kvp.key.EqualsLiteral(QUERYKEY_MIN_VISITS)) { 1.675 + int32_t visits = kvp.value.ToInteger(&rv); 1.676 + if (NS_SUCCEEDED(rv)) 1.677 + query->SetMinVisits(visits); 1.678 + else 1.679 + NS_WARNING("Bad number for minVisits in query"); 1.680 + 1.681 + // max visits 1.682 + } else if (kvp.key.EqualsLiteral(QUERYKEY_MAX_VISITS)) { 1.683 + int32_t visits = kvp.value.ToInteger(&rv); 1.684 + if (NS_SUCCEEDED(rv)) 1.685 + query->SetMaxVisits(visits); 1.686 + else 1.687 + NS_WARNING("Bad number for maxVisits in query"); 1.688 + 1.689 + // onlyBookmarked flag 1.690 + } else if (kvp.key.EqualsLiteral(QUERYKEY_ONLY_BOOKMARKED)) { 1.691 + SetQueryKeyBool(kvp.value, query, &nsINavHistoryQuery::SetOnlyBookmarked); 1.692 + 1.693 + // domainIsHost flag 1.694 + } else if (kvp.key.EqualsLiteral(QUERYKEY_DOMAIN_IS_HOST)) { 1.695 + SetQueryKeyBool(kvp.value, query, &nsINavHistoryQuery::SetDomainIsHost); 1.696 + 1.697 + // domain string 1.698 + } else if (kvp.key.EqualsLiteral(QUERYKEY_DOMAIN)) { 1.699 + nsAutoCString unescapedDomain(kvp.value); 1.700 + NS_UnescapeURL(unescapedDomain); // modifies input 1.701 + rv = query->SetDomain(unescapedDomain); 1.702 + NS_ENSURE_SUCCESS(rv, rv); 1.703 + 1.704 + // folders 1.705 + } else if (kvp.key.EqualsLiteral(QUERYKEY_FOLDER)) { 1.706 + int64_t folder; 1.707 + if (PR_sscanf(kvp.value.get(), "%lld", &folder) == 1) { 1.708 + NS_ENSURE_TRUE(folders.AppendElement(folder), NS_ERROR_OUT_OF_MEMORY); 1.709 + } else { 1.710 + folder = PlacesFolderConversion::DecodeFolder(kvp.value); 1.711 + if (folder != -1) 1.712 + NS_ENSURE_TRUE(folders.AppendElement(folder), NS_ERROR_OUT_OF_MEMORY); 1.713 + else 1.714 + NS_WARNING("folders value in query is invalid, ignoring"); 1.715 + } 1.716 + 1.717 + // uri 1.718 + } else if (kvp.key.EqualsLiteral(QUERYKEY_URI)) { 1.719 + nsAutoCString unescapedUri(kvp.value); 1.720 + NS_UnescapeURL(unescapedUri); // modifies input 1.721 + nsCOMPtr<nsIURI> uri; 1.722 + nsresult rv = NS_NewURI(getter_AddRefs(uri), unescapedUri); 1.723 + if (NS_FAILED(rv)) { 1.724 + NS_WARNING("Unable to parse URI"); 1.725 + } 1.726 + rv = query->SetUri(uri); 1.727 + NS_ENSURE_SUCCESS(rv, rv); 1.728 + 1.729 + // URI is prefix 1.730 + } else if (kvp.key.EqualsLiteral(QUERYKEY_URIISPREFIX)) { 1.731 + SetQueryKeyBool(kvp.value, query, &nsINavHistoryQuery::SetUriIsPrefix); 1.732 + 1.733 + // not annotation 1.734 + } else if (kvp.key.EqualsLiteral(QUERYKEY_NOTANNOTATION)) { 1.735 + nsAutoCString unescaped(kvp.value); 1.736 + NS_UnescapeURL(unescaped); // modifies input 1.737 + query->SetAnnotationIsNot(true); 1.738 + query->SetAnnotation(unescaped); 1.739 + 1.740 + // annotation 1.741 + } else if (kvp.key.EqualsLiteral(QUERYKEY_ANNOTATION)) { 1.742 + nsAutoCString unescaped(kvp.value); 1.743 + NS_UnescapeURL(unescaped); // modifies input 1.744 + query->SetAnnotationIsNot(false); 1.745 + query->SetAnnotation(unescaped); 1.746 + 1.747 + // tag 1.748 + } else if (kvp.key.EqualsLiteral(QUERYKEY_TAG)) { 1.749 + nsAutoCString unescaped(kvp.value); 1.750 + NS_UnescapeURL(unescaped); // modifies input 1.751 + NS_ConvertUTF8toUTF16 tag(unescaped); 1.752 + if (!tags.Contains(tag)) { 1.753 + NS_ENSURE_TRUE(tags.AppendElement(tag), NS_ERROR_OUT_OF_MEMORY); 1.754 + } 1.755 + 1.756 + // not tags 1.757 + } else if (kvp.key.EqualsLiteral(QUERYKEY_NOTTAGS)) { 1.758 + SetQueryKeyBool(kvp.value, query, &nsINavHistoryQuery::SetTagsAreNot); 1.759 + 1.760 + // transition 1.761 + } else if (kvp.key.EqualsLiteral(QUERYKEY_TRANSITION)) { 1.762 + uint32_t transition = kvp.value.ToInteger(&rv); 1.763 + if (NS_SUCCEEDED(rv)) { 1.764 + if (!transitions.Contains(transition)) 1.765 + NS_ENSURE_TRUE(transitions.AppendElement(transition), 1.766 + NS_ERROR_OUT_OF_MEMORY); 1.767 + } 1.768 + else { 1.769 + NS_WARNING("Invalid Int32 transition value."); 1.770 + } 1.771 + 1.772 + // new query component 1.773 + } else if (kvp.key.EqualsLiteral(QUERYKEY_SEPARATOR)) { 1.774 + 1.775 + if (folders.Length() != 0) { 1.776 + query->SetFolders(folders.Elements(), folders.Length()); 1.777 + folders.Clear(); 1.778 + } 1.779 + 1.780 + if (tags.Length() > 0) { 1.781 + rv = query->SetTags(tags); 1.782 + NS_ENSURE_SUCCESS(rv, rv); 1.783 + tags.Clear(); 1.784 + } 1.785 + 1.786 + if (transitions.Length() > 0) { 1.787 + rv = query->SetTransitions(transitions); 1.788 + NS_ENSURE_SUCCESS(rv, rv); 1.789 + transitions.Clear(); 1.790 + } 1.791 + 1.792 + query = new nsNavHistoryQuery(); 1.793 + if (! query) 1.794 + return NS_ERROR_OUT_OF_MEMORY; 1.795 + if (! aQueries->AppendObject(query)) 1.796 + return NS_ERROR_OUT_OF_MEMORY; 1.797 + 1.798 + // sorting mode 1.799 + } else if (kvp.key.EqualsLiteral(QUERYKEY_SORT)) { 1.800 + SetOptionsKeyUint16(kvp.value, aOptions, 1.801 + &nsINavHistoryQueryOptions::SetSortingMode); 1.802 + // sorting annotation 1.803 + } else if (kvp.key.EqualsLiteral(QUERYKEY_SORTING_ANNOTATION)) { 1.804 + nsCString sortingAnnotation = kvp.value; 1.805 + NS_UnescapeURL(sortingAnnotation); 1.806 + rv = aOptions->SetSortingAnnotation(sortingAnnotation); 1.807 + NS_ENSURE_SUCCESS(rv, rv); 1.808 + // result type 1.809 + } else if (kvp.key.EqualsLiteral(QUERYKEY_RESULT_TYPE)) { 1.810 + SetOptionsKeyUint16(kvp.value, aOptions, 1.811 + &nsINavHistoryQueryOptions::SetResultType); 1.812 + 1.813 + // exclude items 1.814 + } else if (kvp.key.EqualsLiteral(QUERYKEY_EXCLUDE_ITEMS)) { 1.815 + SetOptionsKeyBool(kvp.value, aOptions, 1.816 + &nsINavHistoryQueryOptions::SetExcludeItems); 1.817 + 1.818 + // exclude queries 1.819 + } else if (kvp.key.EqualsLiteral(QUERYKEY_EXCLUDE_QUERIES)) { 1.820 + SetOptionsKeyBool(kvp.value, aOptions, 1.821 + &nsINavHistoryQueryOptions::SetExcludeQueries); 1.822 + 1.823 + // exclude read only folders 1.824 + } else if (kvp.key.EqualsLiteral(QUERYKEY_EXCLUDE_READ_ONLY_FOLDERS)) { 1.825 + SetOptionsKeyBool(kvp.value, aOptions, 1.826 + &nsINavHistoryQueryOptions::SetExcludeReadOnlyFolders); 1.827 + 1.828 + // expand queries 1.829 + } else if (kvp.key.EqualsLiteral(QUERYKEY_EXPAND_QUERIES)) { 1.830 + SetOptionsKeyBool(kvp.value, aOptions, 1.831 + &nsINavHistoryQueryOptions::SetExpandQueries); 1.832 + // include hidden 1.833 + } else if (kvp.key.EqualsLiteral(QUERYKEY_INCLUDE_HIDDEN)) { 1.834 + SetOptionsKeyBool(kvp.value, aOptions, 1.835 + &nsINavHistoryQueryOptions::SetIncludeHidden); 1.836 + // max results 1.837 + } else if (kvp.key.EqualsLiteral(QUERYKEY_MAX_RESULTS)) { 1.838 + SetOptionsKeyUint32(kvp.value, aOptions, 1.839 + &nsINavHistoryQueryOptions::SetMaxResults); 1.840 + // query type 1.841 + } else if (kvp.key.EqualsLiteral(QUERYKEY_QUERY_TYPE)) { 1.842 + SetOptionsKeyUint16(kvp.value, aOptions, 1.843 + &nsINavHistoryQueryOptions::SetQueryType); 1.844 + // async enabled 1.845 + } else if (kvp.key.EqualsLiteral(QUERYKEY_ASYNC_ENABLED)) { 1.846 + SetOptionsKeyBool(kvp.value, aOptions, 1.847 + &nsINavHistoryQueryOptions::SetAsyncEnabled); 1.848 + // unknown key 1.849 + } else { 1.850 + NS_WARNING("TokensToQueries(), ignoring unknown key: "); 1.851 + NS_WARNING(kvp.key.get()); 1.852 + } 1.853 + } 1.854 + 1.855 + if (folders.Length() != 0) 1.856 + query->SetFolders(folders.Elements(), folders.Length()); 1.857 + 1.858 + if (tags.Length() > 0) { 1.859 + rv = query->SetTags(tags); 1.860 + NS_ENSURE_SUCCESS(rv, rv); 1.861 + } 1.862 + 1.863 + if (transitions.Length() > 0) { 1.864 + rv = query->SetTransitions(transitions); 1.865 + NS_ENSURE_SUCCESS(rv, rv); 1.866 + } 1.867 + 1.868 + return NS_OK; 1.869 +} 1.870 + 1.871 + 1.872 +// ParseQueryBooleanString 1.873 +// 1.874 +// Converts a 0/1 or true/false string into a bool 1.875 + 1.876 +nsresult 1.877 +ParseQueryBooleanString(const nsCString& aString, bool* aValue) 1.878 +{ 1.879 + if (aString.EqualsLiteral("1") || aString.EqualsLiteral("true")) { 1.880 + *aValue = true; 1.881 + return NS_OK; 1.882 + } else if (aString.EqualsLiteral("0") || aString.EqualsLiteral("false")) { 1.883 + *aValue = false; 1.884 + return NS_OK; 1.885 + } 1.886 + return NS_ERROR_INVALID_ARG; 1.887 +} 1.888 + 1.889 + 1.890 +// nsINavHistoryQuery ********************************************************** 1.891 + 1.892 +NS_IMPL_ISUPPORTS(nsNavHistoryQuery, nsNavHistoryQuery, nsINavHistoryQuery) 1.893 + 1.894 +// nsINavHistoryQuery::nsNavHistoryQuery 1.895 +// 1.896 +// This must initialize the object such that the default values will cause 1.897 +// all history to be returned if this query is used. Then the caller can 1.898 +// just set the things it's interested in. 1.899 + 1.900 +nsNavHistoryQuery::nsNavHistoryQuery() 1.901 + : mMinVisits(-1), mMaxVisits(-1), mBeginTime(0), 1.902 + mBeginTimeReference(TIME_RELATIVE_EPOCH), 1.903 + mEndTime(0), mEndTimeReference(TIME_RELATIVE_EPOCH), 1.904 + mOnlyBookmarked(false), 1.905 + mDomainIsHost(false), mUriIsPrefix(false), 1.906 + mAnnotationIsNot(false), 1.907 + mTagsAreNot(false) 1.908 +{ 1.909 + // differentiate not set (IsVoid) from empty string (local files) 1.910 + mDomain.SetIsVoid(true); 1.911 +} 1.912 + 1.913 +/* attribute PRTime beginTime; */ 1.914 +NS_IMETHODIMP nsNavHistoryQuery::GetBeginTime(PRTime *aBeginTime) 1.915 +{ 1.916 + *aBeginTime = mBeginTime; 1.917 + return NS_OK; 1.918 +} 1.919 +NS_IMETHODIMP nsNavHistoryQuery::SetBeginTime(PRTime aBeginTime) 1.920 +{ 1.921 + mBeginTime = aBeginTime; 1.922 + return NS_OK; 1.923 +} 1.924 + 1.925 +/* attribute long beginTimeReference; */ 1.926 +NS_IMETHODIMP nsNavHistoryQuery::GetBeginTimeReference(uint32_t* _retval) 1.927 +{ 1.928 + *_retval = mBeginTimeReference; 1.929 + return NS_OK; 1.930 +} 1.931 +NS_IMETHODIMP nsNavHistoryQuery::SetBeginTimeReference(uint32_t aReference) 1.932 +{ 1.933 + if (aReference > TIME_RELATIVE_NOW) 1.934 + return NS_ERROR_INVALID_ARG; 1.935 + mBeginTimeReference = aReference; 1.936 + return NS_OK; 1.937 +} 1.938 + 1.939 +/* readonly attribute boolean hasBeginTime; */ 1.940 +NS_IMETHODIMP nsNavHistoryQuery::GetHasBeginTime(bool* _retval) 1.941 +{ 1.942 + *_retval = ! (mBeginTimeReference == TIME_RELATIVE_EPOCH && mBeginTime == 0); 1.943 + return NS_OK; 1.944 +} 1.945 + 1.946 +/* readonly attribute PRTime absoluteBeginTime; */ 1.947 +NS_IMETHODIMP nsNavHistoryQuery::GetAbsoluteBeginTime(PRTime* _retval) 1.948 +{ 1.949 + *_retval = nsNavHistory::NormalizeTime(mBeginTimeReference, mBeginTime); 1.950 + return NS_OK; 1.951 +} 1.952 + 1.953 +/* attribute PRTime endTime; */ 1.954 +NS_IMETHODIMP nsNavHistoryQuery::GetEndTime(PRTime *aEndTime) 1.955 +{ 1.956 + *aEndTime = mEndTime; 1.957 + return NS_OK; 1.958 +} 1.959 +NS_IMETHODIMP nsNavHistoryQuery::SetEndTime(PRTime aEndTime) 1.960 +{ 1.961 + mEndTime = aEndTime; 1.962 + return NS_OK; 1.963 +} 1.964 + 1.965 +/* attribute long endTimeReference; */ 1.966 +NS_IMETHODIMP nsNavHistoryQuery::GetEndTimeReference(uint32_t* _retval) 1.967 +{ 1.968 + *_retval = mEndTimeReference; 1.969 + return NS_OK; 1.970 +} 1.971 +NS_IMETHODIMP nsNavHistoryQuery::SetEndTimeReference(uint32_t aReference) 1.972 +{ 1.973 + if (aReference > TIME_RELATIVE_NOW) 1.974 + return NS_ERROR_INVALID_ARG; 1.975 + mEndTimeReference = aReference; 1.976 + return NS_OK; 1.977 +} 1.978 + 1.979 +/* readonly attribute boolean hasEndTime; */ 1.980 +NS_IMETHODIMP nsNavHistoryQuery::GetHasEndTime(bool* _retval) 1.981 +{ 1.982 + *_retval = ! (mEndTimeReference == TIME_RELATIVE_EPOCH && mEndTime == 0); 1.983 + return NS_OK; 1.984 +} 1.985 + 1.986 +/* readonly attribute PRTime absoluteEndTime; */ 1.987 +NS_IMETHODIMP nsNavHistoryQuery::GetAbsoluteEndTime(PRTime* _retval) 1.988 +{ 1.989 + *_retval = nsNavHistory::NormalizeTime(mEndTimeReference, mEndTime); 1.990 + return NS_OK; 1.991 +} 1.992 + 1.993 +/* attribute string searchTerms; */ 1.994 +NS_IMETHODIMP nsNavHistoryQuery::GetSearchTerms(nsAString& aSearchTerms) 1.995 +{ 1.996 + aSearchTerms = mSearchTerms; 1.997 + return NS_OK; 1.998 +} 1.999 +NS_IMETHODIMP nsNavHistoryQuery::SetSearchTerms(const nsAString& aSearchTerms) 1.1000 +{ 1.1001 + mSearchTerms = aSearchTerms; 1.1002 + return NS_OK; 1.1003 +} 1.1004 +NS_IMETHODIMP nsNavHistoryQuery::GetHasSearchTerms(bool* _retval) 1.1005 +{ 1.1006 + *_retval = (! mSearchTerms.IsEmpty()); 1.1007 + return NS_OK; 1.1008 +} 1.1009 + 1.1010 +/* attribute int32_t minVisits; */ 1.1011 +NS_IMETHODIMP nsNavHistoryQuery::GetMinVisits(int32_t* _retval) 1.1012 +{ 1.1013 + NS_ENSURE_ARG_POINTER(_retval); 1.1014 + *_retval = mMinVisits; 1.1015 + return NS_OK; 1.1016 +} 1.1017 +NS_IMETHODIMP nsNavHistoryQuery::SetMinVisits(int32_t aVisits) 1.1018 +{ 1.1019 + mMinVisits = aVisits; 1.1020 + return NS_OK; 1.1021 +} 1.1022 + 1.1023 +/* attribute PRint32 maxVisits; */ 1.1024 +NS_IMETHODIMP nsNavHistoryQuery::GetMaxVisits(int32_t* _retval) 1.1025 +{ 1.1026 + NS_ENSURE_ARG_POINTER(_retval); 1.1027 + *_retval = mMaxVisits; 1.1028 + return NS_OK; 1.1029 +} 1.1030 +NS_IMETHODIMP nsNavHistoryQuery::SetMaxVisits(int32_t aVisits) 1.1031 +{ 1.1032 + mMaxVisits = aVisits; 1.1033 + return NS_OK; 1.1034 +} 1.1035 + 1.1036 +/* attribute boolean onlyBookmarked; */ 1.1037 +NS_IMETHODIMP nsNavHistoryQuery::GetOnlyBookmarked(bool *aOnlyBookmarked) 1.1038 +{ 1.1039 + *aOnlyBookmarked = mOnlyBookmarked; 1.1040 + return NS_OK; 1.1041 +} 1.1042 +NS_IMETHODIMP nsNavHistoryQuery::SetOnlyBookmarked(bool aOnlyBookmarked) 1.1043 +{ 1.1044 + mOnlyBookmarked = aOnlyBookmarked; 1.1045 + return NS_OK; 1.1046 +} 1.1047 + 1.1048 +/* attribute boolean domainIsHost; */ 1.1049 +NS_IMETHODIMP nsNavHistoryQuery::GetDomainIsHost(bool *aDomainIsHost) 1.1050 +{ 1.1051 + *aDomainIsHost = mDomainIsHost; 1.1052 + return NS_OK; 1.1053 +} 1.1054 +NS_IMETHODIMP nsNavHistoryQuery::SetDomainIsHost(bool aDomainIsHost) 1.1055 +{ 1.1056 + mDomainIsHost = aDomainIsHost; 1.1057 + return NS_OK; 1.1058 +} 1.1059 + 1.1060 +/* attribute AUTF8String domain; */ 1.1061 +NS_IMETHODIMP nsNavHistoryQuery::GetDomain(nsACString& aDomain) 1.1062 +{ 1.1063 + aDomain = mDomain; 1.1064 + return NS_OK; 1.1065 +} 1.1066 +NS_IMETHODIMP nsNavHistoryQuery::SetDomain(const nsACString& aDomain) 1.1067 +{ 1.1068 + mDomain = aDomain; 1.1069 + return NS_OK; 1.1070 +} 1.1071 +NS_IMETHODIMP nsNavHistoryQuery::GetHasDomain(bool* _retval) 1.1072 +{ 1.1073 + // note that empty but not void is still a valid query (local files) 1.1074 + *_retval = (! mDomain.IsVoid()); 1.1075 + return NS_OK; 1.1076 +} 1.1077 + 1.1078 +/* attribute boolean uriIsPrefix; */ 1.1079 +NS_IMETHODIMP nsNavHistoryQuery::GetUriIsPrefix(bool* aIsPrefix) 1.1080 +{ 1.1081 + *aIsPrefix = mUriIsPrefix; 1.1082 + return NS_OK; 1.1083 +} 1.1084 +NS_IMETHODIMP nsNavHistoryQuery::SetUriIsPrefix(bool aIsPrefix) 1.1085 +{ 1.1086 + mUriIsPrefix = aIsPrefix; 1.1087 + return NS_OK; 1.1088 +} 1.1089 + 1.1090 +/* attribute nsIURI uri; */ 1.1091 +NS_IMETHODIMP nsNavHistoryQuery::GetUri(nsIURI** aUri) 1.1092 +{ 1.1093 + NS_IF_ADDREF(*aUri = mUri); 1.1094 + return NS_OK; 1.1095 +} 1.1096 +NS_IMETHODIMP nsNavHistoryQuery::SetUri(nsIURI* aUri) 1.1097 +{ 1.1098 + mUri = aUri; 1.1099 + return NS_OK; 1.1100 +} 1.1101 +NS_IMETHODIMP nsNavHistoryQuery::GetHasUri(bool* aHasUri) 1.1102 +{ 1.1103 + *aHasUri = (mUri != nullptr); 1.1104 + return NS_OK; 1.1105 +} 1.1106 + 1.1107 +/* attribute boolean annotationIsNot; */ 1.1108 +NS_IMETHODIMP nsNavHistoryQuery::GetAnnotationIsNot(bool* aIsNot) 1.1109 +{ 1.1110 + *aIsNot = mAnnotationIsNot; 1.1111 + return NS_OK; 1.1112 +} 1.1113 +NS_IMETHODIMP nsNavHistoryQuery::SetAnnotationIsNot(bool aIsNot) 1.1114 +{ 1.1115 + mAnnotationIsNot = aIsNot; 1.1116 + return NS_OK; 1.1117 +} 1.1118 + 1.1119 +/* attribute AUTF8String annotation; */ 1.1120 +NS_IMETHODIMP nsNavHistoryQuery::GetAnnotation(nsACString& aAnnotation) 1.1121 +{ 1.1122 + aAnnotation = mAnnotation; 1.1123 + return NS_OK; 1.1124 +} 1.1125 +NS_IMETHODIMP nsNavHistoryQuery::SetAnnotation(const nsACString& aAnnotation) 1.1126 +{ 1.1127 + mAnnotation = aAnnotation; 1.1128 + return NS_OK; 1.1129 +} 1.1130 +NS_IMETHODIMP nsNavHistoryQuery::GetHasAnnotation(bool* aHasIt) 1.1131 +{ 1.1132 + *aHasIt = ! mAnnotation.IsEmpty(); 1.1133 + return NS_OK; 1.1134 +} 1.1135 + 1.1136 +/* attribute nsIVariant tags; */ 1.1137 +NS_IMETHODIMP nsNavHistoryQuery::GetTags(nsIVariant **aTags) 1.1138 +{ 1.1139 + NS_ENSURE_ARG_POINTER(aTags); 1.1140 + 1.1141 + nsresult rv; 1.1142 + nsCOMPtr<nsIWritableVariant> out = do_CreateInstance(NS_VARIANT_CONTRACTID, 1.1143 + &rv); 1.1144 + NS_ENSURE_SUCCESS(rv, rv); 1.1145 + 1.1146 + uint32_t arrayLen = mTags.Length(); 1.1147 + 1.1148 + if (arrayLen == 0) 1.1149 + rv = out->SetAsEmptyArray(); 1.1150 + else { 1.1151 + // Note: The resulting nsIVariant dupes both the array and its elements. 1.1152 + const char16_t **array = reinterpret_cast<const char16_t **> 1.1153 + (NS_Alloc(arrayLen * sizeof(char16_t *))); 1.1154 + NS_ENSURE_TRUE(array, NS_ERROR_OUT_OF_MEMORY); 1.1155 + 1.1156 + for (uint32_t i = 0; i < arrayLen; ++i) { 1.1157 + array[i] = mTags[i].get(); 1.1158 + } 1.1159 + 1.1160 + rv = out->SetAsArray(nsIDataType::VTYPE_WCHAR_STR, 1.1161 + nullptr, 1.1162 + arrayLen, 1.1163 + reinterpret_cast<void *>(array)); 1.1164 + NS_Free(array); 1.1165 + } 1.1166 + NS_ENSURE_SUCCESS(rv, rv); 1.1167 + 1.1168 + NS_ADDREF(*aTags = out); 1.1169 + return NS_OK; 1.1170 +} 1.1171 + 1.1172 +NS_IMETHODIMP nsNavHistoryQuery::SetTags(nsIVariant *aTags) 1.1173 +{ 1.1174 + NS_ENSURE_ARG(aTags); 1.1175 + 1.1176 + uint16_t dataType; 1.1177 + aTags->GetDataType(&dataType); 1.1178 + 1.1179 + // Caller passed in empty array. Easy -- clear our mTags array and return. 1.1180 + if (dataType == nsIDataType::VTYPE_EMPTY_ARRAY) { 1.1181 + mTags.Clear(); 1.1182 + return NS_OK; 1.1183 + } 1.1184 + 1.1185 + // Before we go any further, make sure caller passed in an array. 1.1186 + NS_ENSURE_TRUE(dataType == nsIDataType::VTYPE_ARRAY, NS_ERROR_ILLEGAL_VALUE); 1.1187 + 1.1188 + uint16_t eltType; 1.1189 + nsIID eltIID; 1.1190 + uint32_t arrayLen; 1.1191 + void *array; 1.1192 + 1.1193 + // Convert the nsIVariant to an array. We own the resulting buffer and its 1.1194 + // elements. 1.1195 + nsresult rv = aTags->GetAsArray(&eltType, &eltIID, &arrayLen, &array); 1.1196 + NS_ENSURE_SUCCESS(rv, rv); 1.1197 + 1.1198 + // If element type is not wstring, thanks a lot. Your memory die now. 1.1199 + if (eltType != nsIDataType::VTYPE_WCHAR_STR) { 1.1200 + switch (eltType) { 1.1201 + case nsIDataType::VTYPE_ID: 1.1202 + case nsIDataType::VTYPE_CHAR_STR: 1.1203 + { 1.1204 + char **charArray = reinterpret_cast<char **>(array); 1.1205 + for (uint32_t i = 0; i < arrayLen; ++i) { 1.1206 + if (charArray[i]) 1.1207 + NS_Free(charArray[i]); 1.1208 + } 1.1209 + } 1.1210 + break; 1.1211 + case nsIDataType::VTYPE_INTERFACE: 1.1212 + case nsIDataType::VTYPE_INTERFACE_IS: 1.1213 + { 1.1214 + nsISupports **supportsArray = reinterpret_cast<nsISupports **>(array); 1.1215 + for (uint32_t i = 0; i < arrayLen; ++i) { 1.1216 + NS_IF_RELEASE(supportsArray[i]); 1.1217 + } 1.1218 + } 1.1219 + break; 1.1220 + // The other types are primitives that do not need to be freed. 1.1221 + } 1.1222 + NS_Free(array); 1.1223 + return NS_ERROR_ILLEGAL_VALUE; 1.1224 + } 1.1225 + 1.1226 + char16_t **tags = reinterpret_cast<char16_t **>(array); 1.1227 + mTags.Clear(); 1.1228 + 1.1229 + // Finally, add each passed-in tag to our mTags array and then sort it. 1.1230 + for (uint32_t i = 0; i < arrayLen; ++i) { 1.1231 + 1.1232 + // Don't allow nulls. 1.1233 + if (!tags[i]) { 1.1234 + NS_Free(tags); 1.1235 + return NS_ERROR_ILLEGAL_VALUE; 1.1236 + } 1.1237 + 1.1238 + nsDependentString tag(tags[i]); 1.1239 + 1.1240 + // Don't store duplicate tags. This isn't just to save memory or to be 1.1241 + // fancy; the SQL that's built from the tags relies on no dupes. 1.1242 + if (!mTags.Contains(tag)) { 1.1243 + if (!mTags.AppendElement(tag)) { 1.1244 + NS_Free(tags[i]); 1.1245 + NS_Free(tags); 1.1246 + return NS_ERROR_OUT_OF_MEMORY; 1.1247 + } 1.1248 + } 1.1249 + NS_Free(tags[i]); 1.1250 + } 1.1251 + NS_Free(tags); 1.1252 + 1.1253 + mTags.Sort(); 1.1254 + 1.1255 + return NS_OK; 1.1256 +} 1.1257 + 1.1258 +/* attribute boolean tagsAreNot; */ 1.1259 +NS_IMETHODIMP nsNavHistoryQuery::GetTagsAreNot(bool *aTagsAreNot) 1.1260 +{ 1.1261 + NS_ENSURE_ARG_POINTER(aTagsAreNot); 1.1262 + *aTagsAreNot = mTagsAreNot; 1.1263 + return NS_OK; 1.1264 +} 1.1265 + 1.1266 +NS_IMETHODIMP nsNavHistoryQuery::SetTagsAreNot(bool aTagsAreNot) 1.1267 +{ 1.1268 + mTagsAreNot = aTagsAreNot; 1.1269 + return NS_OK; 1.1270 +} 1.1271 + 1.1272 +NS_IMETHODIMP nsNavHistoryQuery::GetFolders(uint32_t *aCount, 1.1273 + int64_t **aFolders) 1.1274 +{ 1.1275 + uint32_t count = mFolders.Length(); 1.1276 + int64_t *folders = nullptr; 1.1277 + if (count > 0) { 1.1278 + folders = static_cast<int64_t*> 1.1279 + (nsMemory::Alloc(count * sizeof(int64_t))); 1.1280 + NS_ENSURE_TRUE(folders, NS_ERROR_OUT_OF_MEMORY); 1.1281 + 1.1282 + for (uint32_t i = 0; i < count; ++i) { 1.1283 + folders[i] = mFolders[i]; 1.1284 + } 1.1285 + } 1.1286 + *aCount = count; 1.1287 + *aFolders = folders; 1.1288 + return NS_OK; 1.1289 +} 1.1290 + 1.1291 +NS_IMETHODIMP nsNavHistoryQuery::GetFolderCount(uint32_t *aCount) 1.1292 +{ 1.1293 + *aCount = mFolders.Length(); 1.1294 + return NS_OK; 1.1295 +} 1.1296 + 1.1297 +NS_IMETHODIMP nsNavHistoryQuery::SetFolders(const int64_t *aFolders, 1.1298 + uint32_t aFolderCount) 1.1299 +{ 1.1300 + if (!mFolders.ReplaceElementsAt(0, mFolders.Length(), 1.1301 + aFolders, aFolderCount)) { 1.1302 + return NS_ERROR_OUT_OF_MEMORY; 1.1303 + } 1.1304 + 1.1305 + return NS_OK; 1.1306 +} 1.1307 + 1.1308 +NS_IMETHODIMP nsNavHistoryQuery::GetTransitions(uint32_t* aCount, 1.1309 + uint32_t** aTransitions) 1.1310 +{ 1.1311 + uint32_t count = mTransitions.Length(); 1.1312 + uint32_t* transitions = nullptr; 1.1313 + if (count > 0) { 1.1314 + transitions = reinterpret_cast<uint32_t*> 1.1315 + (NS_Alloc(count * sizeof(uint32_t))); 1.1316 + NS_ENSURE_TRUE(transitions, NS_ERROR_OUT_OF_MEMORY); 1.1317 + for (uint32_t i = 0; i < count; ++i) { 1.1318 + transitions[i] = mTransitions[i]; 1.1319 + } 1.1320 + } 1.1321 + *aCount = count; 1.1322 + *aTransitions = transitions; 1.1323 + return NS_OK; 1.1324 +} 1.1325 + 1.1326 +NS_IMETHODIMP nsNavHistoryQuery::GetTransitionCount(uint32_t* aCount) 1.1327 +{ 1.1328 + *aCount = mTransitions.Length(); 1.1329 + return NS_OK; 1.1330 +} 1.1331 + 1.1332 +NS_IMETHODIMP nsNavHistoryQuery::SetTransitions(const uint32_t* aTransitions, 1.1333 + uint32_t aCount) 1.1334 +{ 1.1335 + if (!mTransitions.ReplaceElementsAt(0, mTransitions.Length(), aTransitions, 1.1336 + aCount)) 1.1337 + return NS_ERROR_OUT_OF_MEMORY; 1.1338 + 1.1339 + return NS_OK; 1.1340 +} 1.1341 + 1.1342 +NS_IMETHODIMP nsNavHistoryQuery::Clone(nsINavHistoryQuery** _retval) 1.1343 +{ 1.1344 + *_retval = nullptr; 1.1345 + 1.1346 + nsNavHistoryQuery *clone = new nsNavHistoryQuery(*this); 1.1347 + NS_ENSURE_TRUE(clone, NS_ERROR_OUT_OF_MEMORY); 1.1348 + 1.1349 + clone->mRefCnt = 0; // the clone doesn't inherit our refcount 1.1350 + NS_ADDREF(*_retval = clone); 1.1351 + return NS_OK; 1.1352 +} 1.1353 + 1.1354 + 1.1355 +// nsNavHistoryQueryOptions 1.1356 +NS_IMPL_ISUPPORTS(nsNavHistoryQueryOptions, nsNavHistoryQueryOptions, nsINavHistoryQueryOptions) 1.1357 + 1.1358 +// sortingMode 1.1359 +NS_IMETHODIMP 1.1360 +nsNavHistoryQueryOptions::GetSortingMode(uint16_t* aMode) 1.1361 +{ 1.1362 + *aMode = mSort; 1.1363 + return NS_OK; 1.1364 +} 1.1365 +NS_IMETHODIMP 1.1366 +nsNavHistoryQueryOptions::SetSortingMode(uint16_t aMode) 1.1367 +{ 1.1368 + if (aMode > SORT_BY_FRECENCY_DESCENDING) 1.1369 + return NS_ERROR_INVALID_ARG; 1.1370 + mSort = aMode; 1.1371 + return NS_OK; 1.1372 +} 1.1373 + 1.1374 +// sortingAnnotation 1.1375 +NS_IMETHODIMP 1.1376 +nsNavHistoryQueryOptions::GetSortingAnnotation(nsACString& _result) { 1.1377 + _result.Assign(mSortingAnnotation); 1.1378 + return NS_OK; 1.1379 +} 1.1380 + 1.1381 +NS_IMETHODIMP 1.1382 +nsNavHistoryQueryOptions::SetSortingAnnotation(const nsACString& aSortingAnnotation) { 1.1383 + mSortingAnnotation.Assign(aSortingAnnotation); 1.1384 + return NS_OK; 1.1385 +} 1.1386 + 1.1387 +// resultType 1.1388 +NS_IMETHODIMP 1.1389 +nsNavHistoryQueryOptions::GetResultType(uint16_t* aType) 1.1390 +{ 1.1391 + *aType = mResultType; 1.1392 + return NS_OK; 1.1393 +} 1.1394 +NS_IMETHODIMP 1.1395 +nsNavHistoryQueryOptions::SetResultType(uint16_t aType) 1.1396 +{ 1.1397 + if (aType > RESULTS_AS_TAG_CONTENTS) 1.1398 + return NS_ERROR_INVALID_ARG; 1.1399 + // Tag queries and containers are bookmarks related, so we set the QueryType 1.1400 + // accordingly. 1.1401 + if (aType == RESULTS_AS_TAG_QUERY || aType == RESULTS_AS_TAG_CONTENTS) 1.1402 + mQueryType = QUERY_TYPE_BOOKMARKS; 1.1403 + mResultType = aType; 1.1404 + return NS_OK; 1.1405 +} 1.1406 + 1.1407 +// excludeItems 1.1408 +NS_IMETHODIMP 1.1409 +nsNavHistoryQueryOptions::GetExcludeItems(bool* aExclude) 1.1410 +{ 1.1411 + *aExclude = mExcludeItems; 1.1412 + return NS_OK; 1.1413 +} 1.1414 +NS_IMETHODIMP 1.1415 +nsNavHistoryQueryOptions::SetExcludeItems(bool aExclude) 1.1416 +{ 1.1417 + mExcludeItems = aExclude; 1.1418 + return NS_OK; 1.1419 +} 1.1420 + 1.1421 +// excludeQueries 1.1422 +NS_IMETHODIMP 1.1423 +nsNavHistoryQueryOptions::GetExcludeQueries(bool* aExclude) 1.1424 +{ 1.1425 + *aExclude = mExcludeQueries; 1.1426 + return NS_OK; 1.1427 +} 1.1428 +NS_IMETHODIMP 1.1429 +nsNavHistoryQueryOptions::SetExcludeQueries(bool aExclude) 1.1430 +{ 1.1431 + mExcludeQueries = aExclude; 1.1432 + return NS_OK; 1.1433 +} 1.1434 + 1.1435 +// excludeReadOnlyFolders 1.1436 +NS_IMETHODIMP 1.1437 +nsNavHistoryQueryOptions::GetExcludeReadOnlyFolders(bool* aExclude) 1.1438 +{ 1.1439 + *aExclude = mExcludeReadOnlyFolders; 1.1440 + return NS_OK; 1.1441 +} 1.1442 +NS_IMETHODIMP 1.1443 +nsNavHistoryQueryOptions::SetExcludeReadOnlyFolders(bool aExclude) 1.1444 +{ 1.1445 + mExcludeReadOnlyFolders = aExclude; 1.1446 + return NS_OK; 1.1447 +} 1.1448 + 1.1449 +// expandQueries 1.1450 +NS_IMETHODIMP 1.1451 +nsNavHistoryQueryOptions::GetExpandQueries(bool* aExpand) 1.1452 +{ 1.1453 + *aExpand = mExpandQueries; 1.1454 + return NS_OK; 1.1455 +} 1.1456 +NS_IMETHODIMP 1.1457 +nsNavHistoryQueryOptions::SetExpandQueries(bool aExpand) 1.1458 +{ 1.1459 + mExpandQueries = aExpand; 1.1460 + return NS_OK; 1.1461 +} 1.1462 + 1.1463 +// includeHidden 1.1464 +NS_IMETHODIMP 1.1465 +nsNavHistoryQueryOptions::GetIncludeHidden(bool* aIncludeHidden) 1.1466 +{ 1.1467 + *aIncludeHidden = mIncludeHidden; 1.1468 + return NS_OK; 1.1469 +} 1.1470 +NS_IMETHODIMP 1.1471 +nsNavHistoryQueryOptions::SetIncludeHidden(bool aIncludeHidden) 1.1472 +{ 1.1473 + mIncludeHidden = aIncludeHidden; 1.1474 + return NS_OK; 1.1475 +} 1.1476 + 1.1477 +// maxResults 1.1478 +NS_IMETHODIMP 1.1479 +nsNavHistoryQueryOptions::GetMaxResults(uint32_t* aMaxResults) 1.1480 +{ 1.1481 + *aMaxResults = mMaxResults; 1.1482 + return NS_OK; 1.1483 +} 1.1484 +NS_IMETHODIMP 1.1485 +nsNavHistoryQueryOptions::SetMaxResults(uint32_t aMaxResults) 1.1486 +{ 1.1487 + mMaxResults = aMaxResults; 1.1488 + return NS_OK; 1.1489 +} 1.1490 + 1.1491 +// queryType 1.1492 +NS_IMETHODIMP 1.1493 +nsNavHistoryQueryOptions::GetQueryType(uint16_t* _retval) 1.1494 +{ 1.1495 + *_retval = mQueryType; 1.1496 + return NS_OK; 1.1497 +} 1.1498 +NS_IMETHODIMP 1.1499 +nsNavHistoryQueryOptions::SetQueryType(uint16_t aQueryType) 1.1500 +{ 1.1501 + // Tag query and containers are forced to QUERY_TYPE_BOOKMARKS when the 1.1502 + // resultType is set. 1.1503 + if (mResultType == RESULTS_AS_TAG_CONTENTS || 1.1504 + mResultType == RESULTS_AS_TAG_QUERY) 1.1505 + return NS_OK; 1.1506 + mQueryType = aQueryType; 1.1507 + return NS_OK; 1.1508 +} 1.1509 + 1.1510 +// asyncEnabled 1.1511 +NS_IMETHODIMP 1.1512 +nsNavHistoryQueryOptions::GetAsyncEnabled(bool* _asyncEnabled) 1.1513 +{ 1.1514 + *_asyncEnabled = mAsyncEnabled; 1.1515 + return NS_OK; 1.1516 +} 1.1517 +NS_IMETHODIMP 1.1518 +nsNavHistoryQueryOptions::SetAsyncEnabled(bool aAsyncEnabled) 1.1519 +{ 1.1520 + mAsyncEnabled = aAsyncEnabled; 1.1521 + return NS_OK; 1.1522 +} 1.1523 + 1.1524 + 1.1525 +NS_IMETHODIMP 1.1526 +nsNavHistoryQueryOptions::Clone(nsINavHistoryQueryOptions** aResult) 1.1527 +{ 1.1528 + nsNavHistoryQueryOptions *clone = nullptr; 1.1529 + nsresult rv = Clone(&clone); 1.1530 + *aResult = clone; 1.1531 + return rv; 1.1532 +} 1.1533 + 1.1534 +nsresult 1.1535 +nsNavHistoryQueryOptions::Clone(nsNavHistoryQueryOptions **aResult) 1.1536 +{ 1.1537 + *aResult = nullptr; 1.1538 + nsNavHistoryQueryOptions *result = new nsNavHistoryQueryOptions(); 1.1539 + if (! result) 1.1540 + return NS_ERROR_OUT_OF_MEMORY; 1.1541 + 1.1542 + nsRefPtr<nsNavHistoryQueryOptions> resultHolder(result); 1.1543 + result->mSort = mSort; 1.1544 + result->mResultType = mResultType; 1.1545 + result->mExcludeItems = mExcludeItems; 1.1546 + result->mExcludeQueries = mExcludeQueries; 1.1547 + result->mExpandQueries = mExpandQueries; 1.1548 + result->mMaxResults = mMaxResults; 1.1549 + result->mQueryType = mQueryType; 1.1550 + result->mParentAnnotationToExclude = mParentAnnotationToExclude; 1.1551 + result->mAsyncEnabled = mAsyncEnabled; 1.1552 + 1.1553 + resultHolder.swap(*aResult); 1.1554 + return NS_OK; 1.1555 +} 1.1556 + 1.1557 + 1.1558 +// AppendBoolKeyValueIfTrue 1.1559 + 1.1560 +void // static 1.1561 +AppendBoolKeyValueIfTrue(nsACString& aString, const nsCString& aName, 1.1562 + nsINavHistoryQuery* aQuery, 1.1563 + BoolQueryGetter getter) 1.1564 +{ 1.1565 + bool value; 1.1566 + DebugOnly<nsresult> rv = (aQuery->*getter)(&value); 1.1567 + NS_ASSERTION(NS_SUCCEEDED(rv), "Failure getting boolean value"); 1.1568 + if (value) { 1.1569 + AppendAmpersandIfNonempty(aString); 1.1570 + aString += aName; 1.1571 + aString.AppendLiteral("=1"); 1.1572 + } 1.1573 +} 1.1574 + 1.1575 + 1.1576 +// AppendUint32KeyValueIfNonzero 1.1577 + 1.1578 +void // static 1.1579 +AppendUint32KeyValueIfNonzero(nsACString& aString, 1.1580 + const nsCString& aName, 1.1581 + nsINavHistoryQuery* aQuery, 1.1582 + Uint32QueryGetter getter) 1.1583 +{ 1.1584 + uint32_t value; 1.1585 + DebugOnly<nsresult> rv = (aQuery->*getter)(&value); 1.1586 + NS_ASSERTION(NS_SUCCEEDED(rv), "Failure getting value"); 1.1587 + if (value) { 1.1588 + AppendAmpersandIfNonempty(aString); 1.1589 + aString += aName; 1.1590 + 1.1591 + // AppendInt requires a concrete string 1.1592 + nsAutoCString appendMe("="); 1.1593 + appendMe.AppendInt(value); 1.1594 + aString.Append(appendMe); 1.1595 + } 1.1596 +} 1.1597 + 1.1598 + 1.1599 +// AppendInt64KeyValueIfNonzero 1.1600 + 1.1601 +void // static 1.1602 +AppendInt64KeyValueIfNonzero(nsACString& aString, 1.1603 + const nsCString& aName, 1.1604 + nsINavHistoryQuery* aQuery, 1.1605 + Int64QueryGetter getter) 1.1606 +{ 1.1607 + PRTime value; 1.1608 + DebugOnly<nsresult> rv = (aQuery->*getter)(&value); 1.1609 + NS_ASSERTION(NS_SUCCEEDED(rv), "Failure getting value"); 1.1610 + if (value) { 1.1611 + AppendAmpersandIfNonempty(aString); 1.1612 + aString += aName; 1.1613 + nsAutoCString appendMe("="); 1.1614 + appendMe.AppendInt(static_cast<int64_t>(value)); 1.1615 + aString.Append(appendMe); 1.1616 + } 1.1617 +} 1.1618 + 1.1619 + 1.1620 +// SetQuery/OptionsKeyBool 1.1621 + 1.1622 +void // static 1.1623 +SetQueryKeyBool(const nsCString& aValue, nsINavHistoryQuery* aQuery, 1.1624 + BoolQuerySetter setter) 1.1625 +{ 1.1626 + bool value; 1.1627 + nsresult rv = ParseQueryBooleanString(aValue, &value); 1.1628 + if (NS_SUCCEEDED(rv)) { 1.1629 + rv = (aQuery->*setter)(value); 1.1630 + if (NS_FAILED(rv)) { 1.1631 + NS_WARNING("Error setting boolean key value"); 1.1632 + } 1.1633 + } else { 1.1634 + NS_WARNING("Invalid boolean key value in query string."); 1.1635 + } 1.1636 +} 1.1637 +void // static 1.1638 +SetOptionsKeyBool(const nsCString& aValue, nsINavHistoryQueryOptions* aOptions, 1.1639 + BoolOptionsSetter setter) 1.1640 +{ 1.1641 + bool value; 1.1642 + nsresult rv = ParseQueryBooleanString(aValue, &value); 1.1643 + if (NS_SUCCEEDED(rv)) { 1.1644 + rv = (aOptions->*setter)(value); 1.1645 + if (NS_FAILED(rv)) { 1.1646 + NS_WARNING("Error setting boolean key value"); 1.1647 + } 1.1648 + } else { 1.1649 + NS_WARNING("Invalid boolean key value in query string."); 1.1650 + } 1.1651 +} 1.1652 + 1.1653 + 1.1654 +// SetQuery/OptionsKeyUint32 1.1655 + 1.1656 +void // static 1.1657 +SetQueryKeyUint32(const nsCString& aValue, nsINavHistoryQuery* aQuery, 1.1658 + Uint32QuerySetter setter) 1.1659 +{ 1.1660 + nsresult rv; 1.1661 + uint32_t value = aValue.ToInteger(&rv); 1.1662 + if (NS_SUCCEEDED(rv)) { 1.1663 + rv = (aQuery->*setter)(value); 1.1664 + if (NS_FAILED(rv)) { 1.1665 + NS_WARNING("Error setting Int32 key value"); 1.1666 + } 1.1667 + } else { 1.1668 + NS_WARNING("Invalid Int32 key value in query string."); 1.1669 + } 1.1670 +} 1.1671 +void // static 1.1672 +SetOptionsKeyUint32(const nsCString& aValue, nsINavHistoryQueryOptions* aOptions, 1.1673 + Uint32OptionsSetter setter) 1.1674 +{ 1.1675 + nsresult rv; 1.1676 + uint32_t value = aValue.ToInteger(&rv); 1.1677 + if (NS_SUCCEEDED(rv)) { 1.1678 + rv = (aOptions->*setter)(value); 1.1679 + if (NS_FAILED(rv)) { 1.1680 + NS_WARNING("Error setting Int32 key value"); 1.1681 + } 1.1682 + } else { 1.1683 + NS_WARNING("Invalid Int32 key value in query string."); 1.1684 + } 1.1685 +} 1.1686 + 1.1687 +void // static 1.1688 +SetOptionsKeyUint16(const nsCString& aValue, nsINavHistoryQueryOptions* aOptions, 1.1689 + Uint16OptionsSetter setter) 1.1690 +{ 1.1691 + nsresult rv; 1.1692 + uint16_t value = static_cast<uint16_t>(aValue.ToInteger(&rv)); 1.1693 + if (NS_SUCCEEDED(rv)) { 1.1694 + rv = (aOptions->*setter)(value); 1.1695 + if (NS_FAILED(rv)) { 1.1696 + NS_WARNING("Error setting Int16 key value"); 1.1697 + } 1.1698 + } else { 1.1699 + NS_WARNING("Invalid Int16 key value in query string."); 1.1700 + } 1.1701 +} 1.1702 + 1.1703 + 1.1704 +// SetQueryKeyInt64 1.1705 + 1.1706 +void SetQueryKeyInt64(const nsCString& aValue, nsINavHistoryQuery* aQuery, 1.1707 + Int64QuerySetter setter) 1.1708 +{ 1.1709 + nsresult rv; 1.1710 + int64_t value; 1.1711 + if (PR_sscanf(aValue.get(), "%lld", &value) == 1) { 1.1712 + rv = (aQuery->*setter)(value); 1.1713 + if (NS_FAILED(rv)) { 1.1714 + NS_WARNING("Error setting Int64 key value"); 1.1715 + } 1.1716 + } else { 1.1717 + NS_WARNING("Invalid Int64 value in query string."); 1.1718 + } 1.1719 +}