1 : //* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is Places code
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Google Inc.
19 : * Portions created by the Initial Developer are Copyright (C) 2005
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Brett Wilson <brettw@gmail.com> (original author)
24 : * Shawn Wilsher <me@shawnwilsher.com>
25 : * Drew Willcoxon <adw@mozilla.com>
26 : *
27 : * Alternatively, the contents of this file may be used under the terms of
28 : * either the GNU General Public License Version 2 or later (the "GPL"), or
29 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 : * in which case the provisions of the GPL or the LGPL are applicable instead
31 : * of those above. If you wish to allow use of your version of this file only
32 : * under the terms of either the GPL or the LGPL, and not to allow others to
33 : * use your version of this file under the terms of the MPL, indicate your
34 : * decision by deleting the provisions above and replace them with the notice
35 : * and other provisions required by the GPL or the LGPL. If you do not delete
36 : * the provisions above, a recipient may use your version of this file under
37 : * the terms of any one of the MPL, the GPL or the LGPL.
38 : *
39 : * ***** END LICENSE BLOCK ***** */
40 :
41 : /**
42 : * This file contains the definitions of nsNavHistoryQuery,
43 : * nsNavHistoryQueryOptions, and those functions in nsINavHistory that directly
44 : * support queries (specifically QueryStringToQueries and QueriesToQueryString).
45 : */
46 :
47 : #include "nsNavHistory.h"
48 : #include "nsNavBookmarks.h"
49 : #include "nsEscape.h"
50 : #include "nsCOMArray.h"
51 : #include "nsNetUtil.h"
52 : #include "nsTArray.h"
53 : #include "prprf.h"
54 : #include "mozilla/Util.h"
55 :
56 : using namespace mozilla;
57 :
58 : class QueryKeyValuePair
59 44112 : {
60 : public:
61 :
62 : // QueryKeyValuePair
63 : //
64 : // 01234567890
65 : // input : qwerty&key=value&qwerty
66 : // ^ ^ ^
67 : // aKeyBegin | aPastEnd (may point to NULL terminator)
68 : // aEquals
69 : //
70 : // Special case: if aKeyBegin == aEquals, then there is only one string
71 : // and no equal sign, so we treat the entire thing as a key with no value
72 :
73 14704 : QueryKeyValuePair(const nsCSubstring& aSource, PRInt32 aKeyBegin,
74 : PRInt32 aEquals, PRInt32 aPastEnd)
75 14704 : {
76 14704 : if (aEquals == aKeyBegin)
77 1674 : aEquals = aPastEnd;
78 14704 : key = Substring(aSource, aKeyBegin, aEquals - aKeyBegin);
79 14704 : if (aPastEnd - aEquals > 0)
80 13030 : value = Substring(aSource, aEquals + 1, aPastEnd - aEquals - 1);
81 14704 : }
82 : nsCString key;
83 : nsCString value;
84 : };
85 :
86 : static nsresult TokenizeQueryString(const nsACString& aQuery,
87 : nsTArray<QueryKeyValuePair>* aTokens);
88 : static nsresult ParseQueryBooleanString(const nsCString& aString,
89 : bool* aValue);
90 :
91 : // query getters
92 : typedef NS_STDCALL_FUNCPROTO(nsresult, BoolQueryGetter, nsINavHistoryQuery,
93 : GetOnlyBookmarked, (bool*));
94 : typedef NS_STDCALL_FUNCPROTO(nsresult, Uint32QueryGetter, nsINavHistoryQuery,
95 : GetBeginTimeReference, (PRUint32*));
96 : typedef NS_STDCALL_FUNCPROTO(nsresult, Int64QueryGetter, nsINavHistoryQuery,
97 : GetBeginTime, (PRInt64*));
98 : static void AppendBoolKeyValueIfTrue(nsACString& aString,
99 : const nsCString& aName,
100 : nsINavHistoryQuery* aQuery,
101 : BoolQueryGetter getter);
102 : static void AppendUint32KeyValueIfNonzero(nsACString& aString,
103 : const nsCString& aName,
104 : nsINavHistoryQuery* aQuery,
105 : Uint32QueryGetter getter);
106 : static void AppendInt64KeyValueIfNonzero(nsACString& aString,
107 : const nsCString& aName,
108 : nsINavHistoryQuery* aQuery,
109 : Int64QueryGetter getter);
110 :
111 : // query setters
112 : typedef NS_STDCALL_FUNCPROTO(nsresult, BoolQuerySetter, nsINavHistoryQuery,
113 : SetOnlyBookmarked, (bool));
114 : typedef NS_STDCALL_FUNCPROTO(nsresult, Uint32QuerySetter, nsINavHistoryQuery,
115 : SetBeginTimeReference, (PRUint32));
116 : typedef NS_STDCALL_FUNCPROTO(nsresult, Int64QuerySetter, nsINavHistoryQuery,
117 : SetBeginTime, (PRInt64));
118 : static void SetQueryKeyBool(const nsCString& aValue, nsINavHistoryQuery* aQuery,
119 : BoolQuerySetter setter);
120 : static void SetQueryKeyUint32(const nsCString& aValue, nsINavHistoryQuery* aQuery,
121 : Uint32QuerySetter setter);
122 : static void SetQueryKeyInt64(const nsCString& aValue, nsINavHistoryQuery* aQuery,
123 : Int64QuerySetter setter);
124 :
125 : // options setters
126 : typedef NS_STDCALL_FUNCPROTO(nsresult, BoolOptionsSetter,
127 : nsINavHistoryQueryOptions,
128 : SetExpandQueries, (bool));
129 : typedef NS_STDCALL_FUNCPROTO(nsresult, Uint32OptionsSetter,
130 : nsINavHistoryQueryOptions,
131 : SetMaxResults, (PRUint32));
132 : typedef NS_STDCALL_FUNCPROTO(nsresult, Uint16OptionsSetter,
133 : nsINavHistoryQueryOptions,
134 : SetResultType, (PRUint16));
135 : static void SetOptionsKeyBool(const nsCString& aValue,
136 : nsINavHistoryQueryOptions* aOptions,
137 : BoolOptionsSetter setter);
138 : static void SetOptionsKeyUint16(const nsCString& aValue,
139 : nsINavHistoryQueryOptions* aOptions,
140 : Uint16OptionsSetter setter);
141 : static void SetOptionsKeyUint32(const nsCString& aValue,
142 : nsINavHistoryQueryOptions* aOptions,
143 : Uint32OptionsSetter setter);
144 :
145 : // Components of a query string.
146 : // Note that query strings are also generated in nsNavBookmarks::GetFolderURI
147 : // for performance reasons, so if you change these values, change that, too.
148 : #define QUERYKEY_BEGIN_TIME "beginTime"
149 : #define QUERYKEY_BEGIN_TIME_REFERENCE "beginTimeRef"
150 : #define QUERYKEY_END_TIME "endTime"
151 : #define QUERYKEY_END_TIME_REFERENCE "endTimeRef"
152 : #define QUERYKEY_SEARCH_TERMS "terms"
153 : #define QUERYKEY_MIN_VISITS "minVisits"
154 : #define QUERYKEY_MAX_VISITS "maxVisits"
155 : #define QUERYKEY_ONLY_BOOKMARKED "onlyBookmarked"
156 : #define QUERYKEY_DOMAIN_IS_HOST "domainIsHost"
157 : #define QUERYKEY_DOMAIN "domain"
158 : #define QUERYKEY_FOLDER "folder"
159 : #define QUERYKEY_NOTANNOTATION "!annotation"
160 : #define QUERYKEY_ANNOTATION "annotation"
161 : #define QUERYKEY_URI "uri"
162 : #define QUERYKEY_URIISPREFIX "uriIsPrefix"
163 : #define QUERYKEY_SEPARATOR "OR"
164 : #define QUERYKEY_GROUP "group"
165 : #define QUERYKEY_SORT "sort"
166 : #define QUERYKEY_SORTING_ANNOTATION "sortingAnnotation"
167 : #define QUERYKEY_RESULT_TYPE "type"
168 : #define QUERYKEY_EXCLUDE_ITEMS "excludeItems"
169 : #define QUERYKEY_EXCLUDE_QUERIES "excludeQueries"
170 : #define QUERYKEY_EXCLUDE_READ_ONLY_FOLDERS "excludeReadOnlyFolders"
171 : #define QUERYKEY_EXPAND_QUERIES "expandQueries"
172 : #define QUERYKEY_FORCE_ORIGINAL_TITLE "originalTitle"
173 : #define QUERYKEY_INCLUDE_HIDDEN "includeHidden"
174 : #define QUERYKEY_REDIRECTS_MODE "redirectsMode"
175 : #define QUERYKEY_MAX_RESULTS "maxResults"
176 : #define QUERYKEY_QUERY_TYPE "queryType"
177 : #define QUERYKEY_TAG "tag"
178 : #define QUERYKEY_NOTTAGS "!tags"
179 : #define QUERYKEY_ASYNC_ENABLED "asyncEnabled"
180 : #define QUERYKEY_TRANSITION "transition"
181 :
182 12177 : inline void AppendAmpersandIfNonempty(nsACString& aString)
183 : {
184 12177 : if (! aString.IsEmpty())
185 9421 : aString.Append('&');
186 12177 : }
187 853 : inline void AppendInt16(nsACString& str, PRInt16 i)
188 : {
189 1706 : nsCAutoString tmp;
190 853 : tmp.AppendInt(i);
191 853 : str.Append(tmp);
192 853 : }
193 553 : inline void AppendInt32(nsACString& str, PRInt32 i)
194 : {
195 1106 : nsCAutoString tmp;
196 553 : tmp.AppendInt(i);
197 553 : str.Append(tmp);
198 553 : }
199 595 : inline void AppendInt64(nsACString& str, PRInt64 i)
200 : {
201 1190 : nsCString tmp;
202 595 : tmp.AppendInt(i);
203 595 : str.Append(tmp);
204 595 : }
205 :
206 : namespace PlacesFolderConversion {
207 : #define PLACES_ROOT_FOLDER "PLACES_ROOT"
208 : #define BOOKMARKS_MENU_FOLDER "BOOKMARKS_MENU"
209 : #define TAGS_FOLDER "TAGS"
210 : #define UNFILED_BOOKMARKS_FOLDER "UNFILED_BOOKMARKS"
211 : #define TOOLBAR_FOLDER "TOOLBAR"
212 :
213 : /**
214 : * Converts a folder name to a folder id.
215 : *
216 : * @param aName
217 : * The name of the folder to convert to a folder id.
218 : * @returns the folder id if aName is a recognizable name, -1 otherwise.
219 : */
220 689 : inline PRInt64 DecodeFolder(const nsCString &aName)
221 : {
222 689 : nsNavBookmarks *bs = nsNavBookmarks::GetBookmarksService();
223 689 : NS_ENSURE_TRUE(bs, false);
224 689 : PRInt64 folderID = -1;
225 :
226 689 : if (aName.EqualsLiteral(PLACES_ROOT_FOLDER))
227 392 : (void)bs->GetPlacesRoot(&folderID);
228 297 : else if (aName.EqualsLiteral(BOOKMARKS_MENU_FOLDER))
229 43 : (void)bs->GetBookmarksMenuFolder(&folderID);
230 254 : else if (aName.EqualsLiteral(TAGS_FOLDER))
231 196 : (void)bs->GetTagsFolder(&folderID);
232 58 : else if (aName.EqualsLiteral(UNFILED_BOOKMARKS_FOLDER))
233 29 : (void)bs->GetUnfiledBookmarksFolder(&folderID);
234 29 : else if (aName.EqualsLiteral(TOOLBAR_FOLDER))
235 29 : (void)bs->GetToolbarFolder(&folderID);
236 :
237 689 : return folderID;
238 : }
239 :
240 : /**
241 : * Converts a folder id to a named constant, or a string representation of the
242 : * folder id if there is no named constant for the folder, and appends it to
243 : * aQuery.
244 : *
245 : * @param aQuery
246 : * The string to append the folder string to. This is generally a
247 : * query string, but could really be anything.
248 : * @param aFolderID
249 : * The folder ID to convert to the proper named constant.
250 : */
251 664 : inline void AppendFolder(nsCString &aQuery, PRInt64 aFolderID)
252 : {
253 664 : nsNavBookmarks *bs = nsNavBookmarks::GetBookmarksService();
254 : PRInt64 folderID;
255 :
256 664 : (void)bs->GetPlacesRoot(&folderID);
257 664 : if (aFolderID == folderID) {
258 393 : aQuery.AppendLiteral(PLACES_ROOT_FOLDER);
259 393 : return;
260 : }
261 :
262 271 : (void)bs->GetBookmarksMenuFolder(&folderID);
263 271 : if (aFolderID == folderID) {
264 26 : aQuery.AppendLiteral(BOOKMARKS_MENU_FOLDER);
265 26 : return;
266 : }
267 :
268 245 : (void)bs->GetTagsFolder(&folderID);
269 245 : if (aFolderID == folderID) {
270 196 : aQuery.AppendLiteral(TAGS_FOLDER);
271 196 : return;
272 : }
273 :
274 49 : (void)bs->GetUnfiledBookmarksFolder(&folderID);
275 49 : if (aFolderID == folderID) {
276 16 : aQuery.AppendLiteral(UNFILED_BOOKMARKS_FOLDER);
277 16 : return;
278 : }
279 :
280 33 : (void)bs->GetToolbarFolder(&folderID);
281 33 : if (aFolderID == folderID) {
282 16 : aQuery.AppendLiteral(TOOLBAR_FOLDER);
283 16 : return;
284 : }
285 :
286 : // It wasn't one of our named constants, so just convert it to a string
287 17 : aQuery.AppendInt(aFolderID);
288 : }
289 : }
290 :
291 : // nsNavHistory::QueryStringToQueries
292 : //
293 : // From C++ places code, you should use QueryStringToQueryArray, this is
294 : // the harder-to-use XPCOM version.
295 :
296 : NS_IMETHODIMP
297 2529 : nsNavHistory::QueryStringToQueries(const nsACString& aQueryString,
298 : nsINavHistoryQuery*** aQueries,
299 : PRUint32* aResultCount,
300 : nsINavHistoryQueryOptions** aOptions)
301 : {
302 2529 : NS_ENSURE_ARG_POINTER(aQueries);
303 2529 : NS_ENSURE_ARG_POINTER(aResultCount);
304 2529 : NS_ENSURE_ARG_POINTER(aOptions);
305 :
306 2529 : *aQueries = nsnull;
307 2529 : *aResultCount = 0;
308 5058 : nsCOMPtr<nsNavHistoryQueryOptions> options;
309 5058 : nsCOMArray<nsNavHistoryQuery> queries;
310 : nsresult rv = QueryStringToQueryArray(aQueryString, &queries,
311 2529 : getter_AddRefs(options));
312 2529 : NS_ENSURE_SUCCESS(rv, rv);
313 :
314 2529 : *aResultCount = queries.Count();
315 2529 : if (queries.Count() > 0) {
316 : // convert COM array to raw
317 : *aQueries = static_cast<nsINavHistoryQuery**>
318 2529 : (nsMemory::Alloc(sizeof(nsINavHistoryQuery*) * queries.Count()));
319 2529 : NS_ENSURE_TRUE(*aQueries, NS_ERROR_OUT_OF_MEMORY);
320 6726 : for (PRInt32 i = 0; i < queries.Count(); i ++) {
321 4197 : (*aQueries)[i] = queries[i];
322 4197 : NS_ADDREF((*aQueries)[i]);
323 : }
324 : }
325 2529 : NS_ADDREF(*aOptions = options);
326 2529 : return NS_OK;
327 : }
328 :
329 :
330 : // nsNavHistory::QueryStringToQueryArray
331 : //
332 : // An internal version of QueryStringToQueries that fills a COM array for
333 : // ease-of-use.
334 :
335 : nsresult
336 3346 : nsNavHistory::QueryStringToQueryArray(const nsACString& aQueryString,
337 : nsCOMArray<nsNavHistoryQuery>* aQueries,
338 : nsNavHistoryQueryOptions** aOptions)
339 : {
340 : nsresult rv;
341 3346 : aQueries->Clear();
342 3346 : *aOptions = nsnull;
343 :
344 6692 : nsRefPtr<nsNavHistoryQueryOptions> options(new nsNavHistoryQueryOptions());
345 3346 : if (! options)
346 0 : return NS_ERROR_OUT_OF_MEMORY;
347 :
348 6692 : nsTArray<QueryKeyValuePair> tokens;
349 3346 : rv = TokenizeQueryString(aQueryString, &tokens);
350 3346 : NS_ENSURE_SUCCESS(rv, rv);
351 :
352 3346 : rv = TokensToQueries(tokens, aQueries, options);
353 3346 : if (NS_FAILED(rv)) {
354 0 : NS_WARNING("Unable to parse the query string: ");
355 0 : NS_WARNING(PromiseFlatCString(aQueryString).get());
356 0 : return rv;
357 : }
358 :
359 3346 : NS_ADDREF(*aOptions = options);
360 3346 : return NS_OK;
361 : }
362 :
363 :
364 : // nsNavHistory::QueriesToQueryString
365 :
366 : NS_IMETHODIMP
367 2622 : nsNavHistory::QueriesToQueryString(nsINavHistoryQuery **aQueries,
368 : PRUint32 aQueryCount,
369 : nsINavHistoryQueryOptions* aOptions,
370 : nsACString& aQueryString)
371 : {
372 2622 : NS_ENSURE_ARG(aQueries);
373 2621 : NS_ENSURE_ARG(aOptions);
374 :
375 5242 : nsCOMPtr<nsNavHistoryQueryOptions> options = do_QueryInterface(aOptions);
376 2621 : NS_ENSURE_TRUE(options, NS_ERROR_INVALID_ARG);
377 :
378 5242 : nsCAutoString queryString;
379 6914 : for (PRUint32 queryIndex = 0; queryIndex < aQueryCount; queryIndex ++) {
380 8586 : nsCOMPtr<nsNavHistoryQuery> query = do_QueryInterface(aQueries[queryIndex]);
381 4293 : if (queryIndex > 0) {
382 1672 : AppendAmpersandIfNonempty(queryString);
383 1672 : queryString += NS_LITERAL_CSTRING(QUERYKEY_SEPARATOR);
384 : }
385 :
386 : bool hasIt;
387 :
388 : // begin time
389 4293 : query->GetHasBeginTime(&hasIt);
390 4293 : if (hasIt) {
391 : AppendInt64KeyValueIfNonzero(queryString,
392 398 : NS_LITERAL_CSTRING(QUERYKEY_BEGIN_TIME),
393 398 : query, &nsINavHistoryQuery::GetBeginTime);
394 : AppendUint32KeyValueIfNonzero(queryString,
395 398 : NS_LITERAL_CSTRING(QUERYKEY_BEGIN_TIME_REFERENCE),
396 398 : query, &nsINavHistoryQuery::GetBeginTimeReference);
397 : }
398 :
399 : // end time
400 4293 : query->GetHasEndTime(&hasIt);
401 4293 : if (hasIt) {
402 : AppendInt64KeyValueIfNonzero(queryString,
403 400 : NS_LITERAL_CSTRING(QUERYKEY_END_TIME),
404 400 : query, &nsINavHistoryQuery::GetEndTime);
405 : AppendUint32KeyValueIfNonzero(queryString,
406 400 : NS_LITERAL_CSTRING(QUERYKEY_END_TIME_REFERENCE),
407 400 : query, &nsINavHistoryQuery::GetEndTimeReference);
408 : }
409 :
410 : // search terms
411 4293 : query->GetHasSearchTerms(&hasIt);
412 4293 : if (hasIt) {
413 404 : nsAutoString searchTerms;
414 202 : query->GetSearchTerms(searchTerms);
415 404 : nsCString escapedTerms;
416 202 : if (! NS_Escape(NS_ConvertUTF16toUTF8(searchTerms), escapedTerms,
417 202 : url_XAlphas))
418 0 : return NS_ERROR_OUT_OF_MEMORY;
419 :
420 202 : AppendAmpersandIfNonempty(queryString);
421 202 : queryString += NS_LITERAL_CSTRING(QUERYKEY_SEARCH_TERMS "=");
422 404 : queryString += escapedTerms;
423 : }
424 :
425 : // min and max visits
426 : PRInt32 minVisits;
427 4293 : if (NS_SUCCEEDED(query->GetMinVisits(&minVisits)) && minVisits >= 0) {
428 205 : AppendAmpersandIfNonempty(queryString);
429 205 : queryString.Append(NS_LITERAL_CSTRING(QUERYKEY_MIN_VISITS "="));
430 205 : AppendInt32(queryString, minVisits);
431 : }
432 :
433 : PRInt32 maxVisits;
434 4293 : if (NS_SUCCEEDED(query->GetMaxVisits(&maxVisits)) && maxVisits >= 0) {
435 205 : AppendAmpersandIfNonempty(queryString);
436 205 : queryString.Append(NS_LITERAL_CSTRING(QUERYKEY_MAX_VISITS "="));
437 205 : AppendInt32(queryString, maxVisits);
438 : }
439 :
440 : // only bookmarked
441 : AppendBoolKeyValueIfTrue(queryString,
442 4293 : NS_LITERAL_CSTRING(QUERYKEY_ONLY_BOOKMARKED),
443 4293 : query, &nsINavHistoryQuery::GetOnlyBookmarked);
444 :
445 : // domain (+ is host), only call if hasDomain, which means non-IsVoid
446 : // this means we may get an empty string for the domain in the result,
447 : // which is valid
448 4293 : query->GetHasDomain(&hasIt);
449 4293 : if (hasIt) {
450 : AppendBoolKeyValueIfTrue(queryString,
451 585 : NS_LITERAL_CSTRING(QUERYKEY_DOMAIN_IS_HOST),
452 585 : query, &nsINavHistoryQuery::GetDomainIsHost);
453 1170 : nsCAutoString domain;
454 585 : nsresult rv = query->GetDomain(domain);
455 585 : NS_ENSURE_SUCCESS(rv, rv);
456 1170 : nsCString escapedDomain;
457 585 : bool success = NS_Escape(domain, escapedDomain, url_XAlphas);
458 585 : NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);
459 :
460 585 : AppendAmpersandIfNonempty(queryString);
461 585 : queryString.Append(NS_LITERAL_CSTRING(QUERYKEY_DOMAIN "="));
462 1170 : queryString.Append(escapedDomain);
463 : }
464 :
465 : // uri
466 4293 : query->GetHasUri(&hasIt);
467 4293 : if (hasIt) {
468 : AppendBoolKeyValueIfTrue(aQueryString,
469 401 : NS_LITERAL_CSTRING(QUERYKEY_URIISPREFIX),
470 401 : query, &nsINavHistoryQuery::GetUriIsPrefix);
471 802 : nsCOMPtr<nsIURI> uri;
472 401 : query->GetUri(getter_AddRefs(uri));
473 401 : NS_ENSURE_TRUE(uri, NS_ERROR_FAILURE); // hasURI should tell is if invalid
474 802 : nsCAutoString uriSpec;
475 401 : nsresult rv = uri->GetSpec(uriSpec);
476 401 : NS_ENSURE_SUCCESS(rv, rv);
477 802 : nsCAutoString escaped;
478 401 : bool success = NS_Escape(uriSpec, escaped, url_XAlphas);
479 401 : NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);
480 :
481 401 : AppendAmpersandIfNonempty(queryString);
482 401 : queryString.Append(NS_LITERAL_CSTRING(QUERYKEY_URI "="));
483 802 : queryString.Append(escaped);
484 : }
485 :
486 : // annotation
487 4293 : query->GetHasAnnotation(&hasIt);
488 4293 : if (hasIt) {
489 400 : AppendAmpersandIfNonempty(queryString);
490 : bool annotationIsNot;
491 400 : query->GetAnnotationIsNot(&annotationIsNot);
492 400 : if (annotationIsNot)
493 200 : queryString.AppendLiteral(QUERYKEY_NOTANNOTATION "=");
494 : else
495 200 : queryString.AppendLiteral(QUERYKEY_ANNOTATION "=");
496 800 : nsCAutoString annot;
497 400 : query->GetAnnotation(annot);
498 800 : nsCAutoString escaped;
499 400 : bool success = NS_Escape(annot, escaped, url_XAlphas);
500 400 : NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);
501 800 : queryString.Append(escaped);
502 : }
503 :
504 : // folders
505 4293 : PRInt64 *folders = nsnull;
506 4293 : PRUint32 folderCount = 0;
507 4293 : query->GetFolders(&folderCount, &folders);
508 4957 : for (PRUint32 i = 0; i < folderCount; ++i) {
509 664 : AppendAmpersandIfNonempty(queryString);
510 664 : queryString += NS_LITERAL_CSTRING(QUERYKEY_FOLDER "=");
511 664 : PlacesFolderConversion::AppendFolder(queryString, folders[i]);
512 : }
513 4293 : nsMemory::Free(folders);
514 :
515 : // tags
516 4293 : const nsTArray<nsString> &tags = query->Tags();
517 7921 : for (PRUint32 i = 0; i < tags.Length(); ++i) {
518 7256 : nsCAutoString escapedTag;
519 3628 : if (!NS_Escape(NS_ConvertUTF16toUTF8(tags[i]), escapedTag, url_XAlphas))
520 0 : return NS_ERROR_OUT_OF_MEMORY;
521 :
522 3628 : AppendAmpersandIfNonempty(queryString);
523 3628 : queryString += NS_LITERAL_CSTRING(QUERYKEY_TAG "=");
524 7256 : queryString += escapedTag;
525 : }
526 : AppendBoolKeyValueIfTrue(queryString,
527 4293 : NS_LITERAL_CSTRING(QUERYKEY_NOTTAGS),
528 : query,
529 4293 : &nsINavHistoryQuery::GetTagsAreNot);
530 :
531 : // transitions
532 4293 : const nsTArray<PRUint32>& transitions = query->Transitions();
533 4888 : for (PRUint32 i = 0; i < transitions.Length(); ++i) {
534 595 : AppendAmpersandIfNonempty(queryString);
535 595 : queryString += NS_LITERAL_CSTRING(QUERYKEY_TRANSITION "=");
536 595 : AppendInt64(queryString, transitions[i]);
537 : }
538 : }
539 :
540 : // sorting
541 2621 : if (options->SortingMode() != nsINavHistoryQueryOptions::SORT_BY_NONE) {
542 291 : AppendAmpersandIfNonempty(queryString);
543 291 : queryString += NS_LITERAL_CSTRING(QUERYKEY_SORT "=");
544 291 : AppendInt16(queryString, options->SortingMode());
545 581 : if (options->SortingMode() == nsINavHistoryQueryOptions::SORT_BY_ANNOTATION_DESCENDING ||
546 290 : options->SortingMode() == nsINavHistoryQueryOptions::SORT_BY_ANNOTATION_ASCENDING) {
547 : // sortingAnnotation
548 242 : nsCAutoString sortingAnnotation;
549 121 : if (NS_SUCCEEDED(options->GetSortingAnnotation(sortingAnnotation))) {
550 242 : nsCString escaped;
551 121 : if (!NS_Escape(sortingAnnotation, escaped, url_XAlphas))
552 0 : return NS_ERROR_OUT_OF_MEMORY;
553 121 : AppendAmpersandIfNonempty(queryString);
554 121 : queryString += NS_LITERAL_CSTRING(QUERYKEY_SORTING_ANNOTATION "=");
555 242 : queryString.Append(escaped);
556 : }
557 : }
558 : }
559 :
560 : // result type
561 2621 : if (options->ResultType() != nsINavHistoryQueryOptions::RESULTS_AS_URI) {
562 147 : AppendAmpersandIfNonempty(queryString);
563 147 : queryString += NS_LITERAL_CSTRING(QUERYKEY_RESULT_TYPE "=");
564 147 : AppendInt16(queryString, options->ResultType());
565 : }
566 :
567 : // exclude items
568 2621 : if (options->ExcludeItems()) {
569 131 : AppendAmpersandIfNonempty(queryString);
570 131 : queryString += NS_LITERAL_CSTRING(QUERYKEY_EXCLUDE_ITEMS "=1");
571 : }
572 :
573 : // exclude queries
574 2621 : if (options->ExcludeQueries()) {
575 129 : AppendAmpersandIfNonempty(queryString);
576 129 : queryString += NS_LITERAL_CSTRING(QUERYKEY_EXCLUDE_QUERIES "=1");
577 : }
578 :
579 : // exclude read only folders
580 2621 : if (options->ExcludeReadOnlyFolders()) {
581 124 : AppendAmpersandIfNonempty(queryString);
582 124 : queryString += NS_LITERAL_CSTRING(QUERYKEY_EXCLUDE_READ_ONLY_FOLDERS "=1");
583 : }
584 :
585 : // expand queries
586 2621 : if (!options->ExpandQueries()) {
587 5 : AppendAmpersandIfNonempty(queryString);
588 5 : queryString += NS_LITERAL_CSTRING(QUERYKEY_EXPAND_QUERIES "=0");
589 : }
590 :
591 : // include hidden
592 2621 : if (options->IncludeHidden()) {
593 123 : AppendAmpersandIfNonempty(queryString);
594 123 : queryString += NS_LITERAL_CSTRING(QUERYKEY_INCLUDE_HIDDEN "=1");
595 : }
596 :
597 : // redirects mode
598 2621 : if (options->RedirectsMode() != nsINavHistoryQueryOptions::REDIRECTS_MODE_ALL) {
599 242 : AppendAmpersandIfNonempty(queryString);
600 242 : queryString += NS_LITERAL_CSTRING(QUERYKEY_REDIRECTS_MODE "=");
601 242 : AppendInt16(queryString, options->RedirectsMode());
602 : }
603 :
604 : // max results
605 2621 : if (options->MaxResults()) {
606 143 : AppendAmpersandIfNonempty(queryString);
607 143 : queryString += NS_LITERAL_CSTRING(QUERYKEY_MAX_RESULTS "=");
608 143 : AppendInt32(queryString, options->MaxResults());
609 : }
610 :
611 : // queryType
612 2621 : if (options->QueryType() != nsINavHistoryQueryOptions::QUERY_TYPE_HISTORY) {
613 173 : AppendAmpersandIfNonempty(queryString);
614 173 : queryString += NS_LITERAL_CSTRING(QUERYKEY_QUERY_TYPE "=");
615 173 : AppendInt16(queryString, options->QueryType());
616 : }
617 :
618 : // async enabled
619 2621 : if (options->AsyncEnabled()) {
620 0 : AppendAmpersandIfNonempty(queryString);
621 0 : queryString += NS_LITERAL_CSTRING(QUERYKEY_ASYNC_ENABLED "=1");
622 : }
623 :
624 2621 : aQueryString.Assign(NS_LITERAL_CSTRING("place:") + queryString);
625 2621 : return NS_OK;
626 : }
627 :
628 :
629 : // TokenizeQueryString
630 :
631 : nsresult
632 3346 : TokenizeQueryString(const nsACString& aQuery,
633 : nsTArray<QueryKeyValuePair>* aTokens)
634 : {
635 : // Strip off the "place:" prefix
636 3346 : const PRUint32 prefixlen = 6; // = strlen("place:");
637 6692 : nsCString query;
638 13382 : if (aQuery.Length() >= prefixlen &&
639 10036 : Substring(aQuery, 0, prefixlen).EqualsLiteral("place:"))
640 3345 : query = Substring(aQuery, prefixlen);
641 : else
642 1 : query = aQuery;
643 :
644 3346 : PRInt32 keyFirstIndex = 0;
645 3346 : PRInt32 equalsIndex = 0;
646 358803 : for (PRUint32 i = 0; i < query.Length(); i ++) {
647 355457 : if (query[i] == '&') {
648 : // new clause, save last one
649 11398 : if (i - keyFirstIndex > 1) {
650 22796 : if (! aTokens->AppendElement(QueryKeyValuePair(query, keyFirstIndex,
651 22796 : equalsIndex, i)))
652 0 : return NS_ERROR_OUT_OF_MEMORY;
653 : }
654 11398 : keyFirstIndex = equalsIndex = i + 1;
655 344059 : } else if (query[i] == '=') {
656 13030 : equalsIndex = i;
657 : }
658 : }
659 :
660 : // handle last pair, if any
661 3346 : if (query.Length() - keyFirstIndex > 1) {
662 6612 : if (! aTokens->AppendElement(QueryKeyValuePair(query, keyFirstIndex,
663 6612 : equalsIndex, query.Length())))
664 0 : return NS_ERROR_OUT_OF_MEMORY;
665 : }
666 3346 : return NS_OK;
667 : }
668 :
669 : // nsNavHistory::TokensToQueries
670 :
671 : nsresult
672 3346 : nsNavHistory::TokensToQueries(const nsTArray<QueryKeyValuePair>& aTokens,
673 : nsCOMArray<nsNavHistoryQuery>* aQueries,
674 : nsNavHistoryQueryOptions* aOptions)
675 : {
676 : nsresult rv;
677 :
678 6692 : nsCOMPtr<nsNavHistoryQuery> query(new nsNavHistoryQuery());
679 3346 : if (! query)
680 0 : return NS_ERROR_OUT_OF_MEMORY;
681 3346 : if (! aQueries->AppendObject(query))
682 0 : return NS_ERROR_OUT_OF_MEMORY;
683 :
684 3346 : if (aTokens.Length() == 0)
685 40 : return NS_OK; // nothing to do
686 :
687 6612 : nsTArray<PRInt64> folders;
688 6612 : nsTArray<nsString> tags;
689 6612 : nsTArray<PRUint32> transitions;
690 18010 : for (PRUint32 i = 0; i < aTokens.Length(); i ++) {
691 14704 : const QueryKeyValuePair& kvp = aTokens[i];
692 :
693 : // begin time
694 14704 : if (kvp.key.EqualsLiteral(QUERYKEY_BEGIN_TIME)) {
695 803 : SetQueryKeyInt64(kvp.value, query, &nsINavHistoryQuery::SetBeginTime);
696 :
697 : // begin time reference
698 13901 : } else if (kvp.key.EqualsLiteral(QUERYKEY_BEGIN_TIME_REFERENCE)) {
699 200 : SetQueryKeyUint32(kvp.value, query, &nsINavHistoryQuery::SetBeginTimeReference);
700 :
701 : // end time
702 13701 : } else if (kvp.key.EqualsLiteral(QUERYKEY_END_TIME)) {
703 805 : SetQueryKeyInt64(kvp.value, query, &nsINavHistoryQuery::SetEndTime);
704 :
705 : // end time reference
706 12896 : } else if (kvp.key.EqualsLiteral(QUERYKEY_END_TIME_REFERENCE)) {
707 200 : SetQueryKeyUint32(kvp.value, query, &nsINavHistoryQuery::SetEndTimeReference);
708 :
709 : // search terms
710 12696 : } else if (kvp.key.EqualsLiteral(QUERYKEY_SEARCH_TERMS)) {
711 412 : nsCString unescapedTerms = kvp.value;
712 206 : NS_UnescapeURL(unescapedTerms); // modifies input
713 206 : rv = query->SetSearchTerms(NS_ConvertUTF8toUTF16(unescapedTerms));
714 206 : NS_ENSURE_SUCCESS(rv, rv);
715 :
716 : // min visits
717 12490 : } else if (kvp.key.EqualsLiteral(QUERYKEY_MIN_VISITS)) {
718 205 : PRInt32 visits = kvp.value.ToInteger(&rv);
719 205 : if (NS_SUCCEEDED(rv))
720 205 : query->SetMinVisits(visits);
721 : else
722 0 : NS_WARNING("Bad number for minVisits in query");
723 :
724 : // max visits
725 12285 : } else if (kvp.key.EqualsLiteral(QUERYKEY_MAX_VISITS)) {
726 205 : PRInt32 visits = kvp.value.ToInteger(&rv);
727 205 : if (NS_SUCCEEDED(rv))
728 205 : query->SetMaxVisits(visits);
729 : else
730 0 : NS_WARNING("Bad number for maxVisits in query");
731 :
732 : // onlyBookmarked flag
733 12080 : } else if (kvp.key.EqualsLiteral(QUERYKEY_ONLY_BOOKMARKED)) {
734 205 : SetQueryKeyBool(kvp.value, query, &nsINavHistoryQuery::SetOnlyBookmarked);
735 :
736 : // domainIsHost flag
737 11875 : } else if (kvp.key.EqualsLiteral(QUERYKEY_DOMAIN_IS_HOST)) {
738 352 : SetQueryKeyBool(kvp.value, query, &nsINavHistoryQuery::SetDomainIsHost);
739 :
740 : // domain string
741 11523 : } else if (kvp.key.EqualsLiteral(QUERYKEY_DOMAIN)) {
742 1494 : nsCAutoString unescapedDomain(kvp.value);
743 747 : NS_UnescapeURL(unescapedDomain); // modifies input
744 747 : rv = query->SetDomain(unescapedDomain);
745 747 : NS_ENSURE_SUCCESS(rv, rv);
746 :
747 : // folders
748 10776 : } else if (kvp.key.EqualsLiteral(QUERYKEY_FOLDER)) {
749 : PRInt64 folder;
750 858 : if (PR_sscanf(kvp.value.get(), "%lld", &folder) == 1) {
751 169 : NS_ENSURE_TRUE(folders.AppendElement(folder), NS_ERROR_OUT_OF_MEMORY);
752 : } else {
753 689 : folder = PlacesFolderConversion::DecodeFolder(kvp.value);
754 689 : if (folder != -1)
755 689 : NS_ENSURE_TRUE(folders.AppendElement(folder), NS_ERROR_OUT_OF_MEMORY);
756 : else
757 0 : NS_WARNING("folders value in query is invalid, ignoring");
758 : }
759 :
760 : // uri
761 9918 : } else if (kvp.key.EqualsLiteral(QUERYKEY_URI)) {
762 802 : nsCAutoString unescapedUri(kvp.value);
763 401 : NS_UnescapeURL(unescapedUri); // modifies input
764 802 : nsCOMPtr<nsIURI> uri;
765 401 : nsresult rv = NS_NewURI(getter_AddRefs(uri), unescapedUri);
766 401 : if (NS_FAILED(rv)) {
767 0 : NS_WARNING("Unable to parse URI");
768 : }
769 401 : rv = query->SetUri(uri);
770 401 : NS_ENSURE_SUCCESS(rv, rv);
771 :
772 : // URI is prefix
773 9517 : } else if (kvp.key.EqualsLiteral(QUERYKEY_URIISPREFIX)) {
774 0 : SetQueryKeyBool(kvp.value, query, &nsINavHistoryQuery::SetUriIsPrefix);
775 :
776 : // not annotation
777 9517 : } else if (kvp.key.EqualsLiteral(QUERYKEY_NOTANNOTATION)) {
778 400 : nsCAutoString unescaped(kvp.value);
779 200 : NS_UnescapeURL(unescaped); // modifies input
780 200 : query->SetAnnotationIsNot(true);
781 200 : query->SetAnnotation(unescaped);
782 :
783 : // annotation
784 9317 : } else if (kvp.key.EqualsLiteral(QUERYKEY_ANNOTATION)) {
785 400 : nsCAutoString unescaped(kvp.value);
786 200 : NS_UnescapeURL(unescaped); // modifies input
787 200 : query->SetAnnotationIsNot(false);
788 200 : query->SetAnnotation(unescaped);
789 :
790 : // tag
791 9117 : } else if (kvp.key.EqualsLiteral(QUERYKEY_TAG)) {
792 7220 : nsCAutoString unescaped(kvp.value);
793 3610 : NS_UnescapeURL(unescaped); // modifies input
794 7220 : nsString tag = NS_ConvertUTF8toUTF16(unescaped);
795 3610 : if (!tags.Contains(tag)) {
796 3610 : NS_ENSURE_TRUE(tags.AppendElement(tag), NS_ERROR_OUT_OF_MEMORY);
797 : }
798 :
799 : // not tags
800 5507 : } else if (kvp.key.EqualsLiteral(QUERYKEY_NOTTAGS)) {
801 190 : SetQueryKeyBool(kvp.value, query, &nsINavHistoryQuery::SetTagsAreNot);
802 :
803 : // transition
804 5317 : } else if (kvp.key.EqualsLiteral(QUERYKEY_TRANSITION)) {
805 601 : PRUint32 transition = kvp.value.ToInteger(&rv);
806 601 : if (NS_SUCCEEDED(rv)) {
807 601 : if (!transitions.Contains(transition))
808 601 : NS_ENSURE_TRUE(transitions.AppendElement(transition),
809 : NS_ERROR_OUT_OF_MEMORY);
810 : }
811 : else {
812 0 : NS_WARNING("Invalid Int32 transition value.");
813 : }
814 :
815 : // new query component
816 4716 : } else if (kvp.key.EqualsLiteral(QUERYKEY_SEPARATOR)) {
817 :
818 1674 : if (folders.Length() != 0) {
819 162 : query->SetFolders(folders.Elements(), folders.Length());
820 162 : folders.Clear();
821 : }
822 :
823 1674 : if (tags.Length() > 0) {
824 228 : rv = query->SetTags(tags);
825 228 : NS_ENSURE_SUCCESS(rv, rv);
826 228 : tags.Clear();
827 : }
828 :
829 1674 : if (transitions.Length() > 0) {
830 156 : rv = query->SetTransitions(transitions);
831 156 : NS_ENSURE_SUCCESS(rv, rv);
832 156 : transitions.Clear();
833 : }
834 :
835 1674 : query = new nsNavHistoryQuery();
836 1674 : if (! query)
837 0 : return NS_ERROR_OUT_OF_MEMORY;
838 1674 : if (! aQueries->AppendObject(query))
839 0 : return NS_ERROR_OUT_OF_MEMORY;
840 :
841 : // sorting mode
842 3042 : } else if (kvp.key.EqualsLiteral(QUERYKEY_SORT)) {
843 : SetOptionsKeyUint16(kvp.value, aOptions,
844 861 : &nsINavHistoryQueryOptions::SetSortingMode);
845 : // sorting annotation
846 2181 : } else if (kvp.key.EqualsLiteral(QUERYKEY_SORTING_ANNOTATION)) {
847 242 : nsCString sortingAnnotation = kvp.value;
848 121 : NS_UnescapeURL(sortingAnnotation);
849 121 : rv = aOptions->SetSortingAnnotation(sortingAnnotation);
850 121 : NS_ENSURE_SUCCESS(rv, rv);
851 : // result type
852 2060 : } else if (kvp.key.EqualsLiteral(QUERYKEY_RESULT_TYPE)) {
853 : SetOptionsKeyUint16(kvp.value, aOptions,
854 807 : &nsINavHistoryQueryOptions::SetResultType);
855 :
856 : // exclude items
857 1253 : } else if (kvp.key.EqualsLiteral(QUERYKEY_EXCLUDE_ITEMS)) {
858 : SetOptionsKeyBool(kvp.value, aOptions,
859 131 : &nsINavHistoryQueryOptions::SetExcludeItems);
860 :
861 : // exclude queries
862 1122 : } else if (kvp.key.EqualsLiteral(QUERYKEY_EXCLUDE_QUERIES)) {
863 : SetOptionsKeyBool(kvp.value, aOptions,
864 145 : &nsINavHistoryQueryOptions::SetExcludeQueries);
865 :
866 : // exclude read only folders
867 977 : } else if (kvp.key.EqualsLiteral(QUERYKEY_EXCLUDE_READ_ONLY_FOLDERS)) {
868 : SetOptionsKeyBool(kvp.value, aOptions,
869 123 : &nsINavHistoryQueryOptions::SetExcludeReadOnlyFolders);
870 :
871 : // expand queries
872 854 : } else if (kvp.key.EqualsLiteral(QUERYKEY_EXPAND_QUERIES)) {
873 : SetOptionsKeyBool(kvp.value, aOptions,
874 9 : &nsINavHistoryQueryOptions::SetExpandQueries);
875 : // include hidden
876 845 : } else if (kvp.key.EqualsLiteral(QUERYKEY_INCLUDE_HIDDEN)) {
877 : SetOptionsKeyBool(kvp.value, aOptions,
878 123 : &nsINavHistoryQueryOptions::SetIncludeHidden);
879 : // query type
880 722 : } else if (kvp.key.EqualsLiteral(QUERYKEY_REDIRECTS_MODE)) {
881 : SetOptionsKeyUint16(kvp.value, aOptions,
882 256 : &nsINavHistoryQueryOptions::SetRedirectsMode);
883 : // max results
884 466 : } else if (kvp.key.EqualsLiteral(QUERYKEY_MAX_RESULTS)) {
885 : SetOptionsKeyUint32(kvp.value, aOptions,
886 183 : &nsINavHistoryQueryOptions::SetMaxResults);
887 : // query type
888 283 : } else if (kvp.key.EqualsLiteral(QUERYKEY_QUERY_TYPE)) {
889 : SetOptionsKeyUint16(kvp.value, aOptions,
890 283 : &nsINavHistoryQueryOptions::SetQueryType);
891 : // async enabled
892 0 : } else if (kvp.key.EqualsLiteral(QUERYKEY_ASYNC_ENABLED)) {
893 : SetOptionsKeyBool(kvp.value, aOptions,
894 0 : &nsINavHistoryQueryOptions::SetAsyncEnabled);
895 : // unknown key
896 : } else {
897 0 : NS_WARNING("TokensToQueries(), ignoring unknown key: ");
898 0 : NS_WARNING(kvp.key.get());
899 : }
900 : }
901 :
902 3306 : if (folders.Length() != 0)
903 459 : query->SetFolders(folders.Elements(), folders.Length());
904 :
905 3306 : if (tags.Length() > 0) {
906 342 : rv = query->SetTags(tags);
907 342 : NS_ENSURE_SUCCESS(rv, rv);
908 : }
909 :
910 3306 : if (transitions.Length() > 0) {
911 249 : rv = query->SetTransitions(transitions);
912 249 : NS_ENSURE_SUCCESS(rv, rv);
913 : }
914 :
915 3306 : return NS_OK;
916 : }
917 :
918 :
919 : // ParseQueryBooleanString
920 : //
921 : // Converts a 0/1 or true/false string into a bool
922 :
923 : nsresult
924 1278 : ParseQueryBooleanString(const nsCString& aString, bool* aValue)
925 : {
926 1278 : if (aString.EqualsLiteral("1") || aString.EqualsLiteral("true")) {
927 1273 : *aValue = true;
928 1273 : return NS_OK;
929 5 : } else if (aString.EqualsLiteral("0") || aString.EqualsLiteral("false")) {
930 5 : *aValue = false;
931 5 : return NS_OK;
932 : }
933 0 : return NS_ERROR_INVALID_ARG;
934 : }
935 :
936 :
937 : // nsINavHistoryQuery **********************************************************
938 :
939 167628 : NS_IMPL_ISUPPORTS2(nsNavHistoryQuery, nsNavHistoryQuery, nsINavHistoryQuery)
940 :
941 : // nsINavHistoryQuery::nsNavHistoryQuery
942 : //
943 : // This must initialize the object such that the default values will cause
944 : // all history to be returned if this query is used. Then the caller can
945 : // just set the things it's interested in.
946 :
947 6745 : nsNavHistoryQuery::nsNavHistoryQuery()
948 : : mMinVisits(-1), mMaxVisits(-1), mBeginTime(0),
949 : mBeginTimeReference(TIME_RELATIVE_EPOCH),
950 : mEndTime(0), mEndTimeReference(TIME_RELATIVE_EPOCH),
951 : mOnlyBookmarked(false),
952 : mDomainIsHost(false), mUriIsPrefix(false),
953 : mAnnotationIsNot(false),
954 6745 : mTagsAreNot(false)
955 : {
956 : // differentiate not set (IsVoid) from empty string (local files)
957 6745 : mDomain.SetIsVoid(true);
958 6745 : }
959 :
960 : /* attribute PRTime beginTime; */
961 398 : NS_IMETHODIMP nsNavHistoryQuery::GetBeginTime(PRTime *aBeginTime)
962 : {
963 398 : *aBeginTime = mBeginTime;
964 398 : return NS_OK;
965 : }
966 886 : NS_IMETHODIMP nsNavHistoryQuery::SetBeginTime(PRTime aBeginTime)
967 : {
968 886 : mBeginTime = aBeginTime;
969 886 : return NS_OK;
970 : }
971 :
972 : /* attribute long beginTimeReference; */
973 398 : NS_IMETHODIMP nsNavHistoryQuery::GetBeginTimeReference(PRUint32* _retval)
974 : {
975 398 : *_retval = mBeginTimeReference;
976 398 : return NS_OK;
977 : }
978 283 : NS_IMETHODIMP nsNavHistoryQuery::SetBeginTimeReference(PRUint32 aReference)
979 : {
980 283 : if (aReference > TIME_RELATIVE_NOW)
981 0 : return NS_ERROR_INVALID_ARG;
982 283 : mBeginTimeReference = aReference;
983 283 : return NS_OK;
984 : }
985 :
986 : /* readonly attribute boolean hasBeginTime; */
987 18754 : NS_IMETHODIMP nsNavHistoryQuery::GetHasBeginTime(bool* _retval)
988 : {
989 18754 : *_retval = ! (mBeginTimeReference == TIME_RELATIVE_EPOCH && mBeginTime == 0);
990 18754 : return NS_OK;
991 : }
992 :
993 : /* readonly attribute PRTime absoluteBeginTime; */
994 0 : NS_IMETHODIMP nsNavHistoryQuery::GetAbsoluteBeginTime(PRTime* _retval)
995 : {
996 0 : *_retval = nsNavHistory::NormalizeTime(mBeginTimeReference, mBeginTime);
997 0 : return NS_OK;
998 : }
999 :
1000 : /* attribute PRTime endTime; */
1001 400 : NS_IMETHODIMP nsNavHistoryQuery::GetEndTime(PRTime *aEndTime)
1002 : {
1003 400 : *aEndTime = mEndTime;
1004 400 : return NS_OK;
1005 : }
1006 888 : NS_IMETHODIMP nsNavHistoryQuery::SetEndTime(PRTime aEndTime)
1007 : {
1008 888 : mEndTime = aEndTime;
1009 888 : return NS_OK;
1010 : }
1011 :
1012 : /* attribute long endTimeReference; */
1013 400 : NS_IMETHODIMP nsNavHistoryQuery::GetEndTimeReference(PRUint32* _retval)
1014 : {
1015 400 : *_retval = mEndTimeReference;
1016 400 : return NS_OK;
1017 : }
1018 283 : NS_IMETHODIMP nsNavHistoryQuery::SetEndTimeReference(PRUint32 aReference)
1019 : {
1020 283 : if (aReference > TIME_RELATIVE_NOW)
1021 0 : return NS_ERROR_INVALID_ARG;
1022 283 : mEndTimeReference = aReference;
1023 283 : return NS_OK;
1024 : }
1025 :
1026 : /* readonly attribute boolean hasEndTime; */
1027 18614 : NS_IMETHODIMP nsNavHistoryQuery::GetHasEndTime(bool* _retval)
1028 : {
1029 18614 : *_retval = ! (mEndTimeReference == TIME_RELATIVE_EPOCH && mEndTime == 0);
1030 18614 : return NS_OK;
1031 : }
1032 :
1033 : /* readonly attribute PRTime absoluteEndTime; */
1034 0 : NS_IMETHODIMP nsNavHistoryQuery::GetAbsoluteEndTime(PRTime* _retval)
1035 : {
1036 0 : *_retval = nsNavHistory::NormalizeTime(mEndTimeReference, mEndTime);
1037 0 : return NS_OK;
1038 : }
1039 :
1040 : /* attribute string searchTerms; */
1041 202 : NS_IMETHODIMP nsNavHistoryQuery::GetSearchTerms(nsAString& aSearchTerms)
1042 : {
1043 202 : aSearchTerms = mSearchTerms;
1044 202 : return NS_OK;
1045 : }
1046 328 : NS_IMETHODIMP nsNavHistoryQuery::SetSearchTerms(const nsAString& aSearchTerms)
1047 : {
1048 328 : mSearchTerms = aSearchTerms;
1049 328 : return NS_OK;
1050 : }
1051 21042 : NS_IMETHODIMP nsNavHistoryQuery::GetHasSearchTerms(bool* _retval)
1052 : {
1053 21042 : *_retval = (! mSearchTerms.IsEmpty());
1054 21042 : return NS_OK;
1055 : }
1056 :
1057 : /* attribute PRInt32 minVisits; */
1058 12635 : NS_IMETHODIMP nsNavHistoryQuery::GetMinVisits(PRInt32* _retval)
1059 : {
1060 12635 : NS_ENSURE_ARG_POINTER(_retval);
1061 12635 : *_retval = mMinVisits;
1062 12635 : return NS_OK;
1063 : }
1064 258 : NS_IMETHODIMP nsNavHistoryQuery::SetMinVisits(PRInt32 aVisits)
1065 : {
1066 258 : mMinVisits = aVisits;
1067 258 : return NS_OK;
1068 : }
1069 :
1070 : /* attribute PRint32 maxVisits; */
1071 12635 : NS_IMETHODIMP nsNavHistoryQuery::GetMaxVisits(PRInt32* _retval)
1072 : {
1073 12635 : NS_ENSURE_ARG_POINTER(_retval);
1074 12635 : *_retval = mMaxVisits;
1075 12635 : return NS_OK;
1076 : }
1077 256 : NS_IMETHODIMP nsNavHistoryQuery::SetMaxVisits(PRInt32 aVisits)
1078 : {
1079 256 : mMaxVisits = aVisits;
1080 256 : return NS_OK;
1081 : }
1082 :
1083 : /* attribute boolean onlyBookmarked; */
1084 12635 : NS_IMETHODIMP nsNavHistoryQuery::GetOnlyBookmarked(bool *aOnlyBookmarked)
1085 : {
1086 12635 : *aOnlyBookmarked = mOnlyBookmarked;
1087 12635 : return NS_OK;
1088 : }
1089 263 : NS_IMETHODIMP nsNavHistoryQuery::SetOnlyBookmarked(bool aOnlyBookmarked)
1090 : {
1091 263 : mOnlyBookmarked = aOnlyBookmarked;
1092 263 : return NS_OK;
1093 : }
1094 :
1095 : /* attribute boolean domainIsHost; */
1096 678 : NS_IMETHODIMP nsNavHistoryQuery::GetDomainIsHost(bool *aDomainIsHost)
1097 : {
1098 678 : *aDomainIsHost = mDomainIsHost;
1099 678 : return NS_OK;
1100 : }
1101 432 : NS_IMETHODIMP nsNavHistoryQuery::SetDomainIsHost(bool aDomainIsHost)
1102 : {
1103 432 : mDomainIsHost = aDomainIsHost;
1104 432 : return NS_OK;
1105 : }
1106 :
1107 : /* attribute AUTF8String domain; */
1108 585 : NS_IMETHODIMP nsNavHistoryQuery::GetDomain(nsACString& aDomain)
1109 : {
1110 585 : aDomain = mDomain;
1111 585 : return NS_OK;
1112 : }
1113 868 : NS_IMETHODIMP nsNavHistoryQuery::SetDomain(const nsACString& aDomain)
1114 : {
1115 868 : mDomain = aDomain;
1116 868 : return NS_OK;
1117 : }
1118 18376 : NS_IMETHODIMP nsNavHistoryQuery::GetHasDomain(bool* _retval)
1119 : {
1120 : // note that empty but not void is still a valid query (local files)
1121 18376 : *_retval = (! mDomain.IsVoid());
1122 18376 : return NS_OK;
1123 : }
1124 :
1125 : /* attribute boolean uriIsPrefix; */
1126 401 : NS_IMETHODIMP nsNavHistoryQuery::GetUriIsPrefix(bool* aIsPrefix)
1127 : {
1128 401 : *aIsPrefix = mUriIsPrefix;
1129 401 : return NS_OK;
1130 : }
1131 82 : NS_IMETHODIMP nsNavHistoryQuery::SetUriIsPrefix(bool aIsPrefix)
1132 : {
1133 82 : mUriIsPrefix = aIsPrefix;
1134 82 : return NS_OK;
1135 : }
1136 :
1137 : /* attribute nsIURI uri; */
1138 402 : NS_IMETHODIMP nsNavHistoryQuery::GetUri(nsIURI** aUri)
1139 : {
1140 402 : NS_IF_ADDREF(*aUri = mUri);
1141 402 : return NS_OK;
1142 : }
1143 560 : NS_IMETHODIMP nsNavHistoryQuery::SetUri(nsIURI* aUri)
1144 : {
1145 560 : mUri = aUri;
1146 560 : return NS_OK;
1147 : }
1148 17886 : NS_IMETHODIMP nsNavHistoryQuery::GetHasUri(bool* aHasUri)
1149 : {
1150 17886 : *aHasUri = (mUri != nsnull);
1151 17886 : return NS_OK;
1152 : }
1153 :
1154 : /* attribute boolean annotationIsNot; */
1155 400 : NS_IMETHODIMP nsNavHistoryQuery::GetAnnotationIsNot(bool* aIsNot)
1156 : {
1157 400 : *aIsNot = mAnnotationIsNot;
1158 400 : return NS_OK;
1159 : }
1160 483 : NS_IMETHODIMP nsNavHistoryQuery::SetAnnotationIsNot(bool aIsNot)
1161 : {
1162 483 : mAnnotationIsNot = aIsNot;
1163 483 : return NS_OK;
1164 : }
1165 :
1166 : /* attribute AUTF8String annotation; */
1167 400 : NS_IMETHODIMP nsNavHistoryQuery::GetAnnotation(nsACString& aAnnotation)
1168 : {
1169 400 : aAnnotation = mAnnotation;
1170 400 : return NS_OK;
1171 : }
1172 484 : NS_IMETHODIMP nsNavHistoryQuery::SetAnnotation(const nsACString& aAnnotation)
1173 : {
1174 484 : mAnnotation = aAnnotation;
1175 484 : return NS_OK;
1176 : }
1177 17306 : NS_IMETHODIMP nsNavHistoryQuery::GetHasAnnotation(bool* aHasIt)
1178 : {
1179 17306 : *aHasIt = ! mAnnotation.IsEmpty();
1180 17306 : return NS_OK;
1181 : }
1182 :
1183 : /* attribute nsIVariant tags; */
1184 8467 : NS_IMETHODIMP nsNavHistoryQuery::GetTags(nsIVariant **aTags)
1185 : {
1186 8467 : NS_ENSURE_ARG_POINTER(aTags);
1187 :
1188 : nsresult rv;
1189 : nsCOMPtr<nsIWritableVariant> out = do_CreateInstance(NS_VARIANT_CONTRACTID,
1190 16934 : &rv);
1191 8467 : NS_ENSURE_SUCCESS(rv, rv);
1192 :
1193 8467 : PRUint32 arrayLen = mTags.Length();
1194 :
1195 8467 : if (arrayLen == 0)
1196 7213 : rv = out->SetAsEmptyArray();
1197 : else {
1198 : // Note: The resulting nsIVariant dupes both the array and its elements.
1199 : const PRUnichar **array = reinterpret_cast<const PRUnichar **>
1200 1254 : (NS_Alloc(arrayLen * sizeof(PRUnichar *)));
1201 1254 : NS_ENSURE_TRUE(array, NS_ERROR_OUT_OF_MEMORY);
1202 :
1203 8920 : for (PRUint32 i = 0; i < arrayLen; ++i) {
1204 7666 : array[i] = mTags[i].get();
1205 : }
1206 :
1207 1254 : rv = out->SetAsArray(nsIDataType::VTYPE_WCHAR_STR,
1208 : nsnull,
1209 : arrayLen,
1210 1254 : reinterpret_cast<void *>(array));
1211 1254 : NS_Free(array);
1212 : }
1213 8467 : NS_ENSURE_SUCCESS(rv, rv);
1214 :
1215 8467 : NS_ADDREF(*aTags = out);
1216 8467 : return NS_OK;
1217 : }
1218 :
1219 221 : NS_IMETHODIMP nsNavHistoryQuery::SetTags(nsIVariant *aTags)
1220 : {
1221 221 : NS_ENSURE_ARG(aTags);
1222 :
1223 : PRUint16 dataType;
1224 221 : aTags->GetDataType(&dataType);
1225 :
1226 : // Caller passed in empty array. Easy -- clear our mTags array and return.
1227 221 : if (dataType == nsIDataType::VTYPE_EMPTY_ARRAY) {
1228 41 : mTags.Clear();
1229 41 : return NS_OK;
1230 : }
1231 :
1232 : // Before we go any further, make sure caller passed in an array.
1233 180 : NS_ENSURE_TRUE(dataType == nsIDataType::VTYPE_ARRAY, NS_ERROR_ILLEGAL_VALUE);
1234 :
1235 : PRUint16 eltType;
1236 : nsIID eltIID;
1237 : PRUint32 arrayLen;
1238 : void *array;
1239 :
1240 : // Convert the nsIVariant to an array. We own the resulting buffer and its
1241 : // elements.
1242 177 : nsresult rv = aTags->GetAsArray(&eltType, &eltIID, &arrayLen, &array);
1243 177 : NS_ENSURE_SUCCESS(rv, rv);
1244 :
1245 : // If element type is not wstring, thanks a lot. Your memory die now.
1246 177 : if (eltType != nsIDataType::VTYPE_WCHAR_STR) {
1247 6 : switch (eltType) {
1248 : case nsIDataType::VTYPE_ID:
1249 : case nsIDataType::VTYPE_CHAR_STR:
1250 : {
1251 0 : char **charArray = reinterpret_cast<char **>(array);
1252 0 : for (PRUint32 i = 0; i < arrayLen; ++i) {
1253 0 : if (charArray[i])
1254 0 : NS_Free(charArray[i]);
1255 : }
1256 : }
1257 0 : break;
1258 : case nsIDataType::VTYPE_INTERFACE:
1259 : case nsIDataType::VTYPE_INTERFACE_IS:
1260 : {
1261 5 : nsISupports **supportsArray = reinterpret_cast<nsISupports **>(array);
1262 15 : for (PRUint32 i = 0; i < arrayLen; ++i) {
1263 10 : NS_IF_RELEASE(supportsArray[i]);
1264 : }
1265 : }
1266 5 : break;
1267 : // The other types are primitives that do not need to be freed.
1268 : }
1269 6 : NS_Free(array);
1270 6 : return NS_ERROR_ILLEGAL_VALUE;
1271 : }
1272 :
1273 171 : PRUnichar **tags = reinterpret_cast<PRUnichar **>(array);
1274 171 : mTags.Clear();
1275 :
1276 : // Finally, add each passed-in tag to our mTags array and then sort it.
1277 1125 : for (PRUint32 i = 0; i < arrayLen; ++i) {
1278 :
1279 : // Don't allow nulls.
1280 955 : if (!tags[i]) {
1281 1 : NS_Free(tags);
1282 1 : return NS_ERROR_ILLEGAL_VALUE;
1283 : }
1284 :
1285 1908 : nsDependentString tag(tags[i]);
1286 :
1287 : // Don't store duplicate tags. This isn't just to save memory or to be
1288 : // fancy; the SQL that's built from the tags relies on no dupes.
1289 954 : if (!mTags.Contains(tag)) {
1290 943 : if (!mTags.AppendElement(tag)) {
1291 0 : NS_Free(tags[i]);
1292 0 : NS_Free(tags);
1293 0 : return NS_ERROR_OUT_OF_MEMORY;
1294 : }
1295 : }
1296 1908 : NS_Free(tags[i]);
1297 : }
1298 170 : NS_Free(tags);
1299 :
1300 170 : mTags.Sort();
1301 :
1302 170 : return NS_OK;
1303 : }
1304 :
1305 : /* attribute boolean tagsAreNot; */
1306 12697 : NS_IMETHODIMP nsNavHistoryQuery::GetTagsAreNot(bool *aTagsAreNot)
1307 : {
1308 12697 : NS_ENSURE_ARG_POINTER(aTagsAreNot);
1309 12697 : *aTagsAreNot = mTagsAreNot;
1310 12697 : return NS_OK;
1311 : }
1312 :
1313 297 : NS_IMETHODIMP nsNavHistoryQuery::SetTagsAreNot(bool aTagsAreNot)
1314 : {
1315 297 : mTagsAreNot = aTagsAreNot;
1316 297 : return NS_OK;
1317 : }
1318 :
1319 12635 : NS_IMETHODIMP nsNavHistoryQuery::GetFolders(PRUint32 *aCount,
1320 : PRInt64 **aFolders)
1321 : {
1322 12635 : PRUint32 count = mFolders.Length();
1323 12635 : PRInt64 *folders = nsnull;
1324 12635 : if (count > 0) {
1325 : folders = static_cast<PRInt64*>
1326 1237 : (nsMemory::Alloc(count * sizeof(PRInt64)));
1327 1237 : NS_ENSURE_TRUE(folders, NS_ERROR_OUT_OF_MEMORY);
1328 :
1329 3071 : for (PRUint32 i = 0; i < count; ++i) {
1330 1834 : folders[i] = mFolders[i];
1331 : }
1332 : }
1333 12635 : *aCount = count;
1334 12635 : *aFolders = folders;
1335 12635 : return NS_OK;
1336 : }
1337 :
1338 0 : NS_IMETHODIMP nsNavHistoryQuery::GetFolderCount(PRUint32 *aCount)
1339 : {
1340 0 : *aCount = mFolders.Length();
1341 0 : return NS_OK;
1342 : }
1343 :
1344 1308 : NS_IMETHODIMP nsNavHistoryQuery::SetFolders(const PRInt64 *aFolders,
1345 : PRUint32 aFolderCount)
1346 : {
1347 1308 : if (!mFolders.ReplaceElementsAt(0, mFolders.Length(),
1348 1308 : aFolders, aFolderCount)) {
1349 0 : return NS_ERROR_OUT_OF_MEMORY;
1350 : }
1351 :
1352 1308 : return NS_OK;
1353 : }
1354 :
1355 8342 : NS_IMETHODIMP nsNavHistoryQuery::GetTransitions(PRUint32* aCount,
1356 : PRUint32** aTransitions)
1357 : {
1358 8342 : PRUint32 count = mTransitions.Length();
1359 8342 : PRUint32* transitions = nsnull;
1360 8342 : if (count > 0) {
1361 : transitions = reinterpret_cast<PRUint32*>
1362 780 : (NS_Alloc(count * sizeof(PRUint32)));
1363 780 : NS_ENSURE_TRUE(transitions, NS_ERROR_OUT_OF_MEMORY);
1364 1950 : for (PRUint32 i = 0; i < count; ++i) {
1365 1170 : transitions[i] = mTransitions[i];
1366 : }
1367 : }
1368 8342 : *aCount = count;
1369 8342 : *aTransitions = transitions;
1370 8342 : return NS_OK;
1371 : }
1372 :
1373 0 : NS_IMETHODIMP nsNavHistoryQuery::GetTransitionCount(PRUint32* aCount)
1374 : {
1375 0 : *aCount = mTransitions.Length();
1376 0 : return NS_OK;
1377 : }
1378 :
1379 117 : NS_IMETHODIMP nsNavHistoryQuery::SetTransitions(const PRUint32* aTransitions,
1380 : PRUint32 aCount)
1381 : {
1382 117 : if (!mTransitions.ReplaceElementsAt(0, mTransitions.Length(), aTransitions,
1383 117 : aCount))
1384 0 : return NS_ERROR_OUT_OF_MEMORY;
1385 :
1386 117 : return NS_OK;
1387 : }
1388 :
1389 899 : NS_IMETHODIMP nsNavHistoryQuery::Clone(nsINavHistoryQuery** _retval)
1390 : {
1391 899 : *_retval = nsnull;
1392 :
1393 899 : nsNavHistoryQuery *clone = new nsNavHistoryQuery(*this);
1394 899 : NS_ENSURE_TRUE(clone, NS_ERROR_OUT_OF_MEMORY);
1395 :
1396 899 : clone->mRefCnt = 0; // the clone doesn't inherit our refcount
1397 899 : NS_ADDREF(*_retval = clone);
1398 899 : return NS_OK;
1399 : }
1400 :
1401 :
1402 : // nsNavHistoryQueryOptions
1403 125530 : NS_IMPL_ISUPPORTS2(nsNavHistoryQueryOptions, nsNavHistoryQueryOptions, nsINavHistoryQueryOptions)
1404 :
1405 : // sortingMode
1406 : NS_IMETHODIMP
1407 7510 : nsNavHistoryQueryOptions::GetSortingMode(PRUint16* aMode)
1408 : {
1409 7510 : *aMode = mSort;
1410 7510 : return NS_OK;
1411 : }
1412 : NS_IMETHODIMP
1413 1104 : nsNavHistoryQueryOptions::SetSortingMode(PRUint16 aMode)
1414 : {
1415 1104 : if (aMode > SORT_BY_FRECENCY_DESCENDING)
1416 0 : return NS_ERROR_INVALID_ARG;
1417 1104 : mSort = aMode;
1418 1104 : return NS_OK;
1419 : }
1420 :
1421 : // sortingAnnotation
1422 : NS_IMETHODIMP
1423 1281 : nsNavHistoryQueryOptions::GetSortingAnnotation(nsACString& _result) {
1424 1281 : _result.Assign(mSortingAnnotation);
1425 1281 : return NS_OK;
1426 : }
1427 :
1428 : NS_IMETHODIMP
1429 170 : nsNavHistoryQueryOptions::SetSortingAnnotation(const nsACString& aSortingAnnotation) {
1430 170 : mSortingAnnotation.Assign(aSortingAnnotation);
1431 170 : return NS_OK;
1432 : }
1433 :
1434 : // resultType
1435 : NS_IMETHODIMP
1436 5059 : nsNavHistoryQueryOptions::GetResultType(PRUint16* aType)
1437 : {
1438 5059 : *aType = mResultType;
1439 5059 : return NS_OK;
1440 : }
1441 : NS_IMETHODIMP
1442 1023 : nsNavHistoryQueryOptions::SetResultType(PRUint16 aType)
1443 : {
1444 1023 : if (aType > RESULTS_AS_TAG_CONTENTS)
1445 0 : return NS_ERROR_INVALID_ARG;
1446 : // Tag queries and containers are bookmarks related, so we set the QueryType
1447 : // accordingly.
1448 1023 : if (aType == RESULTS_AS_TAG_QUERY || aType == RESULTS_AS_TAG_CONTENTS)
1449 175 : mQueryType = QUERY_TYPE_BOOKMARKS;
1450 1023 : mResultType = aType;
1451 1023 : return NS_OK;
1452 : }
1453 :
1454 : // excludeItems
1455 : NS_IMETHODIMP
1456 5040 : nsNavHistoryQueryOptions::GetExcludeItems(bool* aExclude)
1457 : {
1458 5040 : *aExclude = mExcludeItems;
1459 5040 : return NS_OK;
1460 : }
1461 : NS_IMETHODIMP
1462 249 : nsNavHistoryQueryOptions::SetExcludeItems(bool aExclude)
1463 : {
1464 249 : mExcludeItems = aExclude;
1465 249 : return NS_OK;
1466 : }
1467 :
1468 : // excludeQueries
1469 : NS_IMETHODIMP
1470 5006 : nsNavHistoryQueryOptions::GetExcludeQueries(bool* aExclude)
1471 : {
1472 5006 : *aExclude = mExcludeQueries;
1473 5006 : return NS_OK;
1474 : }
1475 : NS_IMETHODIMP
1476 190 : nsNavHistoryQueryOptions::SetExcludeQueries(bool aExclude)
1477 : {
1478 190 : mExcludeQueries = aExclude;
1479 190 : return NS_OK;
1480 : }
1481 :
1482 : // excludeReadOnlyFolders
1483 : NS_IMETHODIMP
1484 5006 : nsNavHistoryQueryOptions::GetExcludeReadOnlyFolders(bool* aExclude)
1485 : {
1486 5006 : *aExclude = mExcludeReadOnlyFolders;
1487 5006 : return NS_OK;
1488 : }
1489 : NS_IMETHODIMP
1490 165 : nsNavHistoryQueryOptions::SetExcludeReadOnlyFolders(bool aExclude)
1491 : {
1492 165 : mExcludeReadOnlyFolders = aExclude;
1493 165 : return NS_OK;
1494 : }
1495 :
1496 : // expandQueries
1497 : NS_IMETHODIMP
1498 5042 : nsNavHistoryQueryOptions::GetExpandQueries(bool* aExpand)
1499 : {
1500 5042 : *aExpand = mExpandQueries;
1501 5042 : return NS_OK;
1502 : }
1503 : NS_IMETHODIMP
1504 200 : nsNavHistoryQueryOptions::SetExpandQueries(bool aExpand)
1505 : {
1506 200 : mExpandQueries = aExpand;
1507 200 : return NS_OK;
1508 : }
1509 :
1510 : // includeHidden
1511 : NS_IMETHODIMP
1512 5006 : nsNavHistoryQueryOptions::GetIncludeHidden(bool* aIncludeHidden)
1513 : {
1514 5006 : *aIncludeHidden = mIncludeHidden;
1515 5006 : return NS_OK;
1516 : }
1517 : NS_IMETHODIMP
1518 252 : nsNavHistoryQueryOptions::SetIncludeHidden(bool aIncludeHidden)
1519 : {
1520 252 : mIncludeHidden = aIncludeHidden;
1521 252 : return NS_OK;
1522 : }
1523 :
1524 : // redirectsMode
1525 : NS_IMETHODIMP
1526 5006 : nsNavHistoryQueryOptions::GetRedirectsMode(PRUint16* _retval)
1527 : {
1528 5006 : *_retval = mRedirectsMode;
1529 5006 : return NS_OK;
1530 : }
1531 : NS_IMETHODIMP
1532 445 : nsNavHistoryQueryOptions::SetRedirectsMode(PRUint16 aRedirectsMode)
1533 : {
1534 445 : mRedirectsMode = aRedirectsMode;
1535 445 : return NS_OK;
1536 : }
1537 :
1538 : // maxResults
1539 : NS_IMETHODIMP
1540 5009 : nsNavHistoryQueryOptions::GetMaxResults(PRUint32* aMaxResults)
1541 : {
1542 5009 : *aMaxResults = mMaxResults;
1543 5009 : return NS_OK;
1544 : }
1545 : NS_IMETHODIMP
1546 337 : nsNavHistoryQueryOptions::SetMaxResults(PRUint32 aMaxResults)
1547 : {
1548 337 : mMaxResults = aMaxResults;
1549 337 : return NS_OK;
1550 : }
1551 :
1552 : // queryType
1553 : NS_IMETHODIMP
1554 5006 : nsNavHistoryQueryOptions::GetQueryType(PRUint16* _retval)
1555 : {
1556 5006 : *_retval = mQueryType;
1557 5006 : return NS_OK;
1558 : }
1559 : NS_IMETHODIMP
1560 577 : nsNavHistoryQueryOptions::SetQueryType(PRUint16 aQueryType)
1561 : {
1562 : // Tag query and containers are forced to QUERY_TYPE_BOOKMARKS when the
1563 : // resultType is set.
1564 577 : if (mResultType == RESULTS_AS_TAG_CONTENTS ||
1565 : mResultType == RESULTS_AS_TAG_QUERY)
1566 1 : return NS_OK;
1567 576 : mQueryType = aQueryType;
1568 576 : return NS_OK;
1569 : }
1570 :
1571 : // asyncEnabled
1572 : NS_IMETHODIMP
1573 0 : nsNavHistoryQueryOptions::GetAsyncEnabled(bool* _asyncEnabled)
1574 : {
1575 0 : *_asyncEnabled = mAsyncEnabled;
1576 0 : return NS_OK;
1577 : }
1578 : NS_IMETHODIMP
1579 3 : nsNavHistoryQueryOptions::SetAsyncEnabled(bool aAsyncEnabled)
1580 : {
1581 3 : mAsyncEnabled = aAsyncEnabled;
1582 3 : return NS_OK;
1583 : }
1584 :
1585 :
1586 : NS_IMETHODIMP
1587 0 : nsNavHistoryQueryOptions::Clone(nsINavHistoryQueryOptions** aResult)
1588 : {
1589 0 : nsNavHistoryQueryOptions *clone = nsnull;
1590 0 : nsresult rv = Clone(&clone);
1591 0 : *aResult = clone;
1592 0 : return rv;
1593 : }
1594 :
1595 : nsresult
1596 873 : nsNavHistoryQueryOptions::Clone(nsNavHistoryQueryOptions **aResult)
1597 : {
1598 873 : *aResult = nsnull;
1599 873 : nsNavHistoryQueryOptions *result = new nsNavHistoryQueryOptions();
1600 873 : if (! result)
1601 0 : return NS_ERROR_OUT_OF_MEMORY;
1602 :
1603 1746 : nsRefPtr<nsNavHistoryQueryOptions> resultHolder(result);
1604 873 : result->mSort = mSort;
1605 873 : result->mResultType = mResultType;
1606 873 : result->mExcludeItems = mExcludeItems;
1607 873 : result->mExcludeQueries = mExcludeQueries;
1608 873 : result->mExpandQueries = mExpandQueries;
1609 873 : result->mMaxResults = mMaxResults;
1610 873 : result->mQueryType = mQueryType;
1611 873 : result->mParentAnnotationToExclude = mParentAnnotationToExclude;
1612 873 : result->mAsyncEnabled = mAsyncEnabled;
1613 :
1614 873 : resultHolder.swap(*aResult);
1615 873 : return NS_OK;
1616 : }
1617 :
1618 :
1619 : // AppendBoolKeyValueIfTrue
1620 :
1621 : void // static
1622 9572 : AppendBoolKeyValueIfTrue(nsACString& aString, const nsCString& aName,
1623 : nsINavHistoryQuery* aQuery,
1624 : BoolQueryGetter getter)
1625 : {
1626 : bool value;
1627 19144 : DebugOnly<nsresult> rv = (aQuery->*getter)(&value);
1628 9572 : NS_ASSERTION(NS_SUCCEEDED(rv), "Failure getting boolean value");
1629 9572 : if (value) {
1630 793 : AppendAmpersandIfNonempty(aString);
1631 793 : aString += aName;
1632 793 : aString.AppendLiteral("=1");
1633 : }
1634 9572 : }
1635 :
1636 :
1637 : // AppendUint32KeyValueIfNonzero
1638 :
1639 : void // static
1640 798 : AppendUint32KeyValueIfNonzero(nsACString& aString,
1641 : const nsCString& aName,
1642 : nsINavHistoryQuery* aQuery,
1643 : Uint32QueryGetter getter)
1644 : {
1645 : PRUint32 value;
1646 1596 : DebugOnly<nsresult> rv = (aQuery->*getter)(&value);
1647 798 : NS_ASSERTION(NS_SUCCEEDED(rv), "Failure getting value");
1648 798 : if (value) {
1649 400 : AppendAmpersandIfNonempty(aString);
1650 400 : aString += aName;
1651 :
1652 : // AppendInt requires a concrete string
1653 800 : nsCAutoString appendMe("=");
1654 400 : appendMe.AppendInt(value);
1655 400 : aString.Append(appendMe);
1656 : }
1657 798 : }
1658 :
1659 :
1660 : // AppendInt64KeyValueIfNonzero
1661 :
1662 : void // static
1663 798 : AppendInt64KeyValueIfNonzero(nsACString& aString,
1664 : const nsCString& aName,
1665 : nsINavHistoryQuery* aQuery,
1666 : Int64QueryGetter getter)
1667 : {
1668 : PRInt64 value;
1669 1596 : DebugOnly<nsresult> rv = (aQuery->*getter)(&value);
1670 798 : NS_ASSERTION(NS_SUCCEEDED(rv), "Failure getting value");
1671 798 : if (value) {
1672 798 : AppendAmpersandIfNonempty(aString);
1673 798 : aString += aName;
1674 1596 : nsCAutoString appendMe("=");
1675 798 : appendMe.AppendInt(value);
1676 798 : aString.Append(appendMe);
1677 : }
1678 798 : }
1679 :
1680 :
1681 : // SetQuery/OptionsKeyBool
1682 :
1683 : void // static
1684 747 : SetQueryKeyBool(const nsCString& aValue, nsINavHistoryQuery* aQuery,
1685 : BoolQuerySetter setter)
1686 : {
1687 : bool value;
1688 747 : nsresult rv = ParseQueryBooleanString(aValue, &value);
1689 747 : if (NS_SUCCEEDED(rv)) {
1690 747 : rv = (aQuery->*setter)(value);
1691 747 : if (NS_FAILED(rv)) {
1692 0 : NS_WARNING("Error setting boolean key value");
1693 : }
1694 : } else {
1695 0 : NS_WARNING("Invalid boolean key value in query string.");
1696 : }
1697 747 : }
1698 : void // static
1699 531 : SetOptionsKeyBool(const nsCString& aValue, nsINavHistoryQueryOptions* aOptions,
1700 : BoolOptionsSetter setter)
1701 : {
1702 : bool value;
1703 531 : nsresult rv = ParseQueryBooleanString(aValue, &value);
1704 531 : if (NS_SUCCEEDED(rv)) {
1705 531 : rv = (aOptions->*setter)(value);
1706 531 : if (NS_FAILED(rv)) {
1707 0 : NS_WARNING("Error setting boolean key value");
1708 : }
1709 : } else {
1710 0 : NS_WARNING("Invalid boolean key value in query string.");
1711 : }
1712 531 : }
1713 :
1714 :
1715 : // SetQuery/OptionsKeyUint32
1716 :
1717 : void // static
1718 400 : SetQueryKeyUint32(const nsCString& aValue, nsINavHistoryQuery* aQuery,
1719 : Uint32QuerySetter setter)
1720 : {
1721 : nsresult rv;
1722 400 : PRUint32 value = aValue.ToInteger(reinterpret_cast<PRInt32*>(&rv));
1723 400 : if (NS_SUCCEEDED(rv)) {
1724 400 : rv = (aQuery->*setter)(value);
1725 400 : if (NS_FAILED(rv)) {
1726 0 : NS_WARNING("Error setting Int32 key value");
1727 : }
1728 : } else {
1729 0 : NS_WARNING("Invalid Int32 key value in query string.");
1730 : }
1731 400 : }
1732 : void // static
1733 183 : SetOptionsKeyUint32(const nsCString& aValue, nsINavHistoryQueryOptions* aOptions,
1734 : Uint32OptionsSetter setter)
1735 : {
1736 : nsresult rv;
1737 183 : PRUint32 value = aValue.ToInteger(reinterpret_cast<PRInt32*>(&rv));
1738 183 : if (NS_SUCCEEDED(rv)) {
1739 183 : rv = (aOptions->*setter)(value);
1740 183 : if (NS_FAILED(rv)) {
1741 0 : NS_WARNING("Error setting Int32 key value");
1742 : }
1743 : } else {
1744 0 : NS_WARNING("Invalid Int32 key value in query string.");
1745 : }
1746 183 : }
1747 :
1748 : void // static
1749 2207 : SetOptionsKeyUint16(const nsCString& aValue, nsINavHistoryQueryOptions* aOptions,
1750 : Uint16OptionsSetter setter)
1751 : {
1752 : nsresult rv;
1753 : PRUint16 value = static_cast<PRUint16>
1754 2207 : (aValue.ToInteger(reinterpret_cast<PRInt32*>(&rv)));
1755 2207 : if (NS_SUCCEEDED(rv)) {
1756 2207 : rv = (aOptions->*setter)(value);
1757 2207 : if (NS_FAILED(rv)) {
1758 0 : NS_WARNING("Error setting Int16 key value");
1759 : }
1760 : } else {
1761 0 : NS_WARNING("Invalid Int16 key value in query string.");
1762 : }
1763 2207 : }
1764 :
1765 :
1766 : // SetQueryKeyInt64
1767 :
1768 1608 : void SetQueryKeyInt64(const nsCString& aValue, nsINavHistoryQuery* aQuery,
1769 : Int64QuerySetter setter)
1770 : {
1771 : nsresult rv;
1772 : PRInt64 value;
1773 1608 : if (PR_sscanf(aValue.get(), "%lld", &value) == 1) {
1774 1608 : rv = (aQuery->*setter)(value);
1775 1608 : if (NS_FAILED(rv)) {
1776 0 : NS_WARNING("Error setting Int64 key value");
1777 : }
1778 : } else {
1779 0 : NS_WARNING("Invalid Int64 value in query string.");
1780 : }
1781 1608 : }
|