Source code

Revision control

Other Tools

1
//* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* This Source Code Form is subject to the terms of the Mozilla Public
3
* License, v. 2.0. If a copy of the MPL was not distributed with this
4
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6
/**
7
* This file contains the definitions of nsNavHistoryQuery,
8
* nsNavHistoryQueryOptions, and those functions in nsINavHistory that directly
9
* support queries (specifically QueryStringToQuery and QueryToQueryString).
10
*/
11
12
#include "mozilla/DebugOnly.h"
13
14
#include "nsNavHistory.h"
15
#include "nsNavBookmarks.h"
16
#include "nsEscape.h"
17
#include "nsCOMArray.h"
18
#include "nsNetUtil.h"
19
#include "nsTArray.h"
20
#include "prprf.h"
21
#include "nsVariant.h"
22
23
using namespace mozilla;
24
using namespace mozilla::places;
25
26
static nsresult ParseQueryBooleanString(const nsCString& aString, bool* aValue);
27
28
// query getters
29
typedef decltype(&nsINavHistoryQuery::GetOnlyBookmarked) BoolQueryGetter;
30
typedef decltype(&nsINavHistoryQuery::GetBeginTimeReference) Uint32QueryGetter;
31
typedef decltype(&nsINavHistoryQuery::GetBeginTime) Int64QueryGetter;
32
static void AppendBoolKeyValueIfTrue(nsACString& aString,
33
const nsCString& aName,
34
nsINavHistoryQuery* aQuery,
35
BoolQueryGetter getter);
36
static void AppendUint32KeyValueIfNonzero(nsACString& aString,
37
const nsCString& aName,
38
nsINavHistoryQuery* aQuery,
39
Uint32QueryGetter getter);
40
static void AppendInt64KeyValueIfNonzero(nsACString& aString,
41
const nsCString& aName,
42
nsINavHistoryQuery* aQuery,
43
Int64QueryGetter getter);
44
45
// query setters
46
typedef decltype(&nsINavHistoryQuery::SetOnlyBookmarked) BoolQuerySetter;
47
typedef decltype(&nsINavHistoryQuery::SetBeginTimeReference) Uint32QuerySetter;
48
typedef decltype(&nsINavHistoryQuery::SetBeginTime) Int64QuerySetter;
49
static void SetQueryKeyBool(const nsCString& aValue, nsINavHistoryQuery* aQuery,
50
BoolQuerySetter setter);
51
static void SetQueryKeyUint32(const nsCString& aValue,
52
nsINavHistoryQuery* aQuery,
53
Uint32QuerySetter setter);
54
static void SetQueryKeyInt64(const nsCString& aValue,
55
nsINavHistoryQuery* aQuery,
56
Int64QuerySetter setter);
57
58
// options setters
59
typedef decltype(
60
&nsINavHistoryQueryOptions::SetExpandQueries) BoolOptionsSetter;
61
typedef decltype(&nsINavHistoryQueryOptions::SetMaxResults) Uint32OptionsSetter;
62
typedef decltype(&nsINavHistoryQueryOptions::SetResultType) Uint16OptionsSetter;
63
static void SetOptionsKeyBool(const nsCString& aValue,
64
nsINavHistoryQueryOptions* aOptions,
65
BoolOptionsSetter setter);
66
static void SetOptionsKeyUint16(const nsCString& aValue,
67
nsINavHistoryQueryOptions* aOptions,
68
Uint16OptionsSetter setter);
69
static void SetOptionsKeyUint32(const nsCString& aValue,
70
nsINavHistoryQueryOptions* aOptions,
71
Uint32OptionsSetter setter);
72
73
// Components of a query string.
74
// Note that query strings are also generated in nsNavBookmarks::GetFolderURI
75
// for performance reasons, so if you change these values, change that, too.
76
#define QUERYKEY_BEGIN_TIME "beginTime"
77
#define QUERYKEY_BEGIN_TIME_REFERENCE "beginTimeRef"
78
#define QUERYKEY_END_TIME "endTime"
79
#define QUERYKEY_END_TIME_REFERENCE "endTimeRef"
80
#define QUERYKEY_SEARCH_TERMS "terms"
81
#define QUERYKEY_MIN_VISITS "minVisits"
82
#define QUERYKEY_MAX_VISITS "maxVisits"
83
#define QUERYKEY_ONLY_BOOKMARKED "onlyBookmarked"
84
#define QUERYKEY_DOMAIN_IS_HOST "domainIsHost"
85
#define QUERYKEY_DOMAIN "domain"
86
#define QUERYKEY_PARENT "parent"
87
#define QUERYKEY_NOTANNOTATION "!annotation"
88
#define QUERYKEY_ANNOTATION "annotation"
89
#define QUERYKEY_URI "uri"
90
#define QUERYKEY_GROUP "group"
91
#define QUERYKEY_SORT "sort"
92
#define QUERYKEY_RESULT_TYPE "type"
93
#define QUERYKEY_EXCLUDE_ITEMS "excludeItems"
94
#define QUERYKEY_EXCLUDE_QUERIES "excludeQueries"
95
#define QUERYKEY_EXPAND_QUERIES "expandQueries"
96
#define QUERYKEY_FORCE_ORIGINAL_TITLE "originalTitle"
97
#define QUERYKEY_INCLUDE_HIDDEN "includeHidden"
98
#define QUERYKEY_MAX_RESULTS "maxResults"
99
#define QUERYKEY_QUERY_TYPE "queryType"
100
#define QUERYKEY_TAG "tag"
101
#define QUERYKEY_NOTTAGS "!tags"
102
#define QUERYKEY_ASYNC_ENABLED "asyncEnabled"
103
#define QUERYKEY_TRANSITION "transition"
104
105
inline void AppendAmpersandIfNonempty(nsACString& aString) {
106
if (!aString.IsEmpty()) aString.Append('&');
107
}
108
inline void AppendInt16(nsACString& str, int16_t i) {
109
nsAutoCString tmp;
110
tmp.AppendInt(i);
111
str.Append(tmp);
112
}
113
inline void AppendInt32(nsACString& str, int32_t i) {
114
nsAutoCString tmp;
115
tmp.AppendInt(i);
116
str.Append(tmp);
117
}
118
inline void AppendInt64(nsACString& str, int64_t i) {
119
nsCString tmp;
120
tmp.AppendInt(i);
121
str.Append(tmp);
122
}
123
124
NS_IMETHODIMP
125
nsNavHistory::QueryStringToQuery(const nsACString& aQueryString,
126
nsINavHistoryQuery** _query,
127
nsINavHistoryQueryOptions** _options) {
128
NS_ENSURE_ARG_POINTER(_query);
129
NS_ENSURE_ARG_POINTER(_options);
130
131
nsTArray<QueryKeyValuePair> tokens;
132
nsresult rv = TokenizeQueryString(aQueryString, &tokens);
133
NS_ENSURE_SUCCESS(rv, rv);
134
135
RefPtr<nsNavHistoryQueryOptions> options = new nsNavHistoryQueryOptions();
136
RefPtr<nsNavHistoryQuery> query = new nsNavHistoryQuery();
137
rv = TokensToQuery(tokens, query, options);
138
MOZ_ASSERT(NS_SUCCEEDED(rv), "The query string should be valid");
139
if (NS_FAILED(rv)) {
140
NS_WARNING("Unable to parse the query string: ");
141
NS_WARNING(PromiseFlatCString(aQueryString).get());
142
}
143
144
options.forget(_options);
145
query.forget(_query);
146
return NS_OK;
147
}
148
149
NS_IMETHODIMP
150
nsNavHistory::QueryToQueryString(nsINavHistoryQuery* aQuery,
151
nsINavHistoryQueryOptions* aOptions,
152
nsACString& aQueryString) {
153
NS_ENSURE_ARG(aQuery);
154
NS_ENSURE_ARG(aOptions);
155
156
RefPtr<nsNavHistoryQuery> query = do_QueryObject(aQuery);
157
NS_ENSURE_STATE(query);
158
RefPtr<nsNavHistoryQueryOptions> options = do_QueryObject(aOptions);
159
NS_ENSURE_STATE(options);
160
161
nsAutoCString queryString;
162
bool hasIt;
163
164
// begin time
165
query->GetHasBeginTime(&hasIt);
166
if (hasIt) {
167
AppendInt64KeyValueIfNonzero(queryString,
168
NS_LITERAL_CSTRING(QUERYKEY_BEGIN_TIME), query,
169
&nsINavHistoryQuery::GetBeginTime);
170
AppendUint32KeyValueIfNonzero(
171
queryString, NS_LITERAL_CSTRING(QUERYKEY_BEGIN_TIME_REFERENCE), query,
172
&nsINavHistoryQuery::GetBeginTimeReference);
173
}
174
175
// end time
176
query->GetHasEndTime(&hasIt);
177
if (hasIt) {
178
AppendInt64KeyValueIfNonzero(queryString,
179
NS_LITERAL_CSTRING(QUERYKEY_END_TIME), query,
180
&nsINavHistoryQuery::GetEndTime);
181
AppendUint32KeyValueIfNonzero(
182
queryString, NS_LITERAL_CSTRING(QUERYKEY_END_TIME_REFERENCE), query,
183
&nsINavHistoryQuery::GetEndTimeReference);
184
}
185
186
// search terms
187
if (!query->SearchTerms().IsEmpty()) {
188
const nsString& searchTerms = query->SearchTerms();
189
nsCString escapedTerms;
190
if (!NS_Escape(NS_ConvertUTF16toUTF8(searchTerms), escapedTerms,
191
url_XAlphas))
192
return NS_ERROR_OUT_OF_MEMORY;
193
194
AppendAmpersandIfNonempty(queryString);
195
queryString += NS_LITERAL_CSTRING(QUERYKEY_SEARCH_TERMS "=");
196
queryString += escapedTerms;
197
}
198
199
// min and max visits
200
int32_t minVisits;
201
if (NS_SUCCEEDED(query->GetMinVisits(&minVisits)) && minVisits >= 0) {
202
AppendAmpersandIfNonempty(queryString);
203
queryString.AppendLiteral(QUERYKEY_MIN_VISITS "=");
204
AppendInt32(queryString, minVisits);
205
}
206
207
int32_t maxVisits;
208
if (NS_SUCCEEDED(query->GetMaxVisits(&maxVisits)) && maxVisits >= 0) {
209
AppendAmpersandIfNonempty(queryString);
210
queryString.AppendLiteral(QUERYKEY_MAX_VISITS "=");
211
AppendInt32(queryString, maxVisits);
212
}
213
214
// only bookmarked
215
AppendBoolKeyValueIfTrue(queryString,
216
NS_LITERAL_CSTRING(QUERYKEY_ONLY_BOOKMARKED), query,
217
&nsINavHistoryQuery::GetOnlyBookmarked);
218
219
// domain (+ is host), only call if hasDomain, which means non-IsVoid
220
// this means we may get an empty string for the domain in the result,
221
// which is valid
222
if (!query->Domain().IsVoid()) {
223
AppendBoolKeyValueIfTrue(queryString,
224
NS_LITERAL_CSTRING(QUERYKEY_DOMAIN_IS_HOST), query,
225
&nsINavHistoryQuery::GetDomainIsHost);
226
const nsCString& domain = query->Domain();
227
nsCString escapedDomain;
228
bool success = NS_Escape(domain, escapedDomain, url_XAlphas);
229
NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);
230
231
AppendAmpersandIfNonempty(queryString);
232
queryString.AppendLiteral(QUERYKEY_DOMAIN "=");
233
queryString.Append(escapedDomain);
234
}
235
236
// uri
237
if (query->Uri()) {
238
nsCOMPtr<nsIURI> uri = query->Uri();
239
nsAutoCString uriSpec;
240
nsresult rv = uri->GetSpec(uriSpec);
241
NS_ENSURE_SUCCESS(rv, rv);
242
nsAutoCString escaped;
243
bool success = NS_Escape(uriSpec, escaped, url_XAlphas);
244
NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);
245
246
AppendAmpersandIfNonempty(queryString);
247
queryString.AppendLiteral(QUERYKEY_URI "=");
248
queryString.Append(escaped);
249
}
250
251
// annotation
252
if (!query->Annotation().IsEmpty()) {
253
AppendAmpersandIfNonempty(queryString);
254
if (query->AnnotationIsNot()) {
255
queryString.AppendLiteral(QUERYKEY_NOTANNOTATION "=");
256
} else {
257
queryString.AppendLiteral(QUERYKEY_ANNOTATION "=");
258
}
259
const nsCString& annot = query->Annotation();
260
nsAutoCString escaped;
261
bool success = NS_Escape(annot, escaped, url_XAlphas);
262
NS_ENSURE_TRUE(success, NS_ERROR_OUT_OF_MEMORY);
263
queryString.Append(escaped);
264
}
265
266
// parents
267
const nsTArray<nsCString>& parents = query->Parents();
268
for (uint32_t i = 0; i < parents.Length(); ++i) {
269
AppendAmpersandIfNonempty(queryString);
270
queryString += NS_LITERAL_CSTRING(QUERYKEY_PARENT "=");
271
queryString += parents[i];
272
}
273
274
// tags
275
const nsTArray<nsString>& tags = query->Tags();
276
for (uint32_t i = 0; i < tags.Length(); ++i) {
277
nsAutoCString escapedTag;
278
if (!NS_Escape(NS_ConvertUTF16toUTF8(tags[i]), escapedTag, url_XAlphas))
279
return NS_ERROR_OUT_OF_MEMORY;
280
281
AppendAmpersandIfNonempty(queryString);
282
queryString += NS_LITERAL_CSTRING(QUERYKEY_TAG "=");
283
queryString += escapedTag;
284
}
285
AppendBoolKeyValueIfTrue(queryString, NS_LITERAL_CSTRING(QUERYKEY_NOTTAGS),
286
query, &nsINavHistoryQuery::GetTagsAreNot);
287
288
// transitions
289
const nsTArray<uint32_t>& transitions = query->Transitions();
290
for (uint32_t i = 0; i < transitions.Length(); ++i) {
291
AppendAmpersandIfNonempty(queryString);
292
queryString += NS_LITERAL_CSTRING(QUERYKEY_TRANSITION "=");
293
AppendInt64(queryString, transitions[i]);
294
}
295
296
// sorting
297
if (options->SortingMode() != nsINavHistoryQueryOptions::SORT_BY_NONE) {
298
AppendAmpersandIfNonempty(queryString);
299
queryString += NS_LITERAL_CSTRING(QUERYKEY_SORT "=");
300
AppendInt16(queryString, options->SortingMode());
301
}
302
303
// result type
304
if (options->ResultType() != nsINavHistoryQueryOptions::RESULTS_AS_URI) {
305
AppendAmpersandIfNonempty(queryString);
306
queryString += NS_LITERAL_CSTRING(QUERYKEY_RESULT_TYPE "=");
307
AppendInt16(queryString, options->ResultType());
308
}
309
310
// exclude items
311
if (options->ExcludeItems()) {
312
AppendAmpersandIfNonempty(queryString);
313
queryString += NS_LITERAL_CSTRING(QUERYKEY_EXCLUDE_ITEMS "=1");
314
}
315
316
// exclude queries
317
if (options->ExcludeQueries()) {
318
AppendAmpersandIfNonempty(queryString);
319
queryString += NS_LITERAL_CSTRING(QUERYKEY_EXCLUDE_QUERIES "=1");
320
}
321
322
// expand queries
323
if (!options->ExpandQueries()) {
324
AppendAmpersandIfNonempty(queryString);
325
queryString += NS_LITERAL_CSTRING(QUERYKEY_EXPAND_QUERIES "=0");
326
}
327
328
// include hidden
329
if (options->IncludeHidden()) {
330
AppendAmpersandIfNonempty(queryString);
331
queryString += NS_LITERAL_CSTRING(QUERYKEY_INCLUDE_HIDDEN "=1");
332
}
333
334
// max results
335
if (options->MaxResults()) {
336
AppendAmpersandIfNonempty(queryString);
337
queryString += NS_LITERAL_CSTRING(QUERYKEY_MAX_RESULTS "=");
338
AppendInt32(queryString, options->MaxResults());
339
}
340
341
// queryType
342
if (options->QueryType() != nsINavHistoryQueryOptions::QUERY_TYPE_HISTORY) {
343
AppendAmpersandIfNonempty(queryString);
344
queryString += NS_LITERAL_CSTRING(QUERYKEY_QUERY_TYPE "=");
345
AppendInt16(queryString, options->QueryType());
346
}
347
348
// async enabled
349
if (options->AsyncEnabled()) {
350
AppendAmpersandIfNonempty(queryString);
351
queryString += NS_LITERAL_CSTRING(QUERYKEY_ASYNC_ENABLED "=1");
352
}
353
354
aQueryString.AssignLiteral("place:");
355
aQueryString.Append(queryString);
356
return NS_OK;
357
}
358
359
nsresult nsNavHistory::TokensToQuery(const nsTArray<QueryKeyValuePair>& aTokens,
360
nsNavHistoryQuery* aQuery,
361
nsNavHistoryQueryOptions* aOptions) {
362
nsresult rv;
363
364
if (aTokens.Length() == 0) return NS_OK;
365
366
nsTArray<nsCString> parents;
367
nsTArray<nsString> tags;
368
nsTArray<uint32_t> transitions;
369
for (uint32_t i = 0; i < aTokens.Length(); i++) {
370
const QueryKeyValuePair& kvp = aTokens[i];
371
372
// begin time
373
if (kvp.key.EqualsLiteral(QUERYKEY_BEGIN_TIME)) {
374
SetQueryKeyInt64(kvp.value, aQuery, &nsINavHistoryQuery::SetBeginTime);
375
376
// begin time reference
377
} else if (kvp.key.EqualsLiteral(QUERYKEY_BEGIN_TIME_REFERENCE)) {
378
SetQueryKeyUint32(kvp.value, aQuery,
379
&nsINavHistoryQuery::SetBeginTimeReference);
380
381
// end time
382
} else if (kvp.key.EqualsLiteral(QUERYKEY_END_TIME)) {
383
SetQueryKeyInt64(kvp.value, aQuery, &nsINavHistoryQuery::SetEndTime);
384
385
// end time reference
386
} else if (kvp.key.EqualsLiteral(QUERYKEY_END_TIME_REFERENCE)) {
387
SetQueryKeyUint32(kvp.value, aQuery,
388
&nsINavHistoryQuery::SetEndTimeReference);
389
390
// search terms
391
} else if (kvp.key.EqualsLiteral(QUERYKEY_SEARCH_TERMS)) {
392
nsCString unescapedTerms = kvp.value;
393
NS_UnescapeURL(unescapedTerms); // modifies input
394
rv = aQuery->SetSearchTerms(NS_ConvertUTF8toUTF16(unescapedTerms));
395
NS_ENSURE_SUCCESS(rv, rv);
396
397
// min visits
398
} else if (kvp.key.EqualsLiteral(QUERYKEY_MIN_VISITS)) {
399
int32_t visits = kvp.value.ToInteger(&rv);
400
if (NS_SUCCEEDED(rv))
401
aQuery->SetMinVisits(visits);
402
else
403
NS_WARNING("Bad number for minVisits in query");
404
405
// max visits
406
} else if (kvp.key.EqualsLiteral(QUERYKEY_MAX_VISITS)) {
407
int32_t visits = kvp.value.ToInteger(&rv);
408
if (NS_SUCCEEDED(rv))
409
aQuery->SetMaxVisits(visits);
410
else
411
NS_WARNING("Bad number for maxVisits in query");
412
413
// onlyBookmarked flag
414
} else if (kvp.key.EqualsLiteral(QUERYKEY_ONLY_BOOKMARKED)) {
415
SetQueryKeyBool(kvp.value, aQuery,
416
&nsINavHistoryQuery::SetOnlyBookmarked);
417
418
// domainIsHost flag
419
} else if (kvp.key.EqualsLiteral(QUERYKEY_DOMAIN_IS_HOST)) {
420
SetQueryKeyBool(kvp.value, aQuery, &nsINavHistoryQuery::SetDomainIsHost);
421
422
// domain string
423
} else if (kvp.key.EqualsLiteral(QUERYKEY_DOMAIN)) {
424
nsAutoCString unescapedDomain(kvp.value);
425
NS_UnescapeURL(unescapedDomain); // modifies input
426
rv = aQuery->SetDomain(unescapedDomain);
427
NS_ENSURE_SUCCESS(rv, rv);
428
429
// parent folders (guids)
430
} else if (kvp.key.EqualsLiteral(QUERYKEY_PARENT)) {
431
NS_ENSURE_TRUE(parents.AppendElement(kvp.value), NS_ERROR_OUT_OF_MEMORY);
432
433
// uri
434
} else if (kvp.key.EqualsLiteral(QUERYKEY_URI)) {
435
nsAutoCString unescapedUri(kvp.value);
436
NS_UnescapeURL(unescapedUri); // modifies input
437
nsCOMPtr<nsIURI> uri;
438
nsresult rv = NS_NewURI(getter_AddRefs(uri), unescapedUri);
439
if (NS_FAILED(rv)) {
440
NS_WARNING("Unable to parse URI");
441
}
442
rv = aQuery->SetUri(uri);
443
NS_ENSURE_SUCCESS(rv, rv);
444
445
// not annotation
446
} else if (kvp.key.EqualsLiteral(QUERYKEY_NOTANNOTATION)) {
447
nsAutoCString unescaped(kvp.value);
448
NS_UnescapeURL(unescaped); // modifies input
449
aQuery->SetAnnotationIsNot(true);
450
aQuery->SetAnnotation(unescaped);
451
452
// annotation
453
} else if (kvp.key.EqualsLiteral(QUERYKEY_ANNOTATION)) {
454
nsAutoCString unescaped(kvp.value);
455
NS_UnescapeURL(unescaped); // modifies input
456
aQuery->SetAnnotationIsNot(false);
457
aQuery->SetAnnotation(unescaped);
458
459
// tag
460
} else if (kvp.key.EqualsLiteral(QUERYKEY_TAG)) {
461
nsAutoCString unescaped(kvp.value);
462
NS_UnescapeURL(unescaped); // modifies input
463
NS_ConvertUTF8toUTF16 tag(unescaped);
464
if (!tags.Contains(tag)) {
465
NS_ENSURE_TRUE(tags.AppendElement(tag), NS_ERROR_OUT_OF_MEMORY);
466
}
467
468
// not tags
469
} else if (kvp.key.EqualsLiteral(QUERYKEY_NOTTAGS)) {
470
SetQueryKeyBool(kvp.value, aQuery, &nsINavHistoryQuery::SetTagsAreNot);
471
472
// transition
473
} else if (kvp.key.EqualsLiteral(QUERYKEY_TRANSITION)) {
474
uint32_t transition = kvp.value.ToInteger(&rv);
475
if (NS_SUCCEEDED(rv)) {
476
if (!transitions.Contains(transition))
477
NS_ENSURE_TRUE(transitions.AppendElement(transition),
478
NS_ERROR_OUT_OF_MEMORY);
479
} else {
480
NS_WARNING("Invalid Int32 transition value.");
481
}
482
483
// sorting mode
484
} else if (kvp.key.EqualsLiteral(QUERYKEY_SORT)) {
485
SetOptionsKeyUint16(kvp.value, aOptions,
486
&nsINavHistoryQueryOptions::SetSortingMode);
487
// result type
488
} else if (kvp.key.EqualsLiteral(QUERYKEY_RESULT_TYPE)) {
489
SetOptionsKeyUint16(kvp.value, aOptions,
490
&nsINavHistoryQueryOptions::SetResultType);
491
492
// exclude items
493
} else if (kvp.key.EqualsLiteral(QUERYKEY_EXCLUDE_ITEMS)) {
494
SetOptionsKeyBool(kvp.value, aOptions,
495
&nsINavHistoryQueryOptions::SetExcludeItems);
496
497
// exclude queries
498
} else if (kvp.key.EqualsLiteral(QUERYKEY_EXCLUDE_QUERIES)) {
499
SetOptionsKeyBool(kvp.value, aOptions,
500
&nsINavHistoryQueryOptions::SetExcludeQueries);
501
502
// expand queries
503
} else if (kvp.key.EqualsLiteral(QUERYKEY_EXPAND_QUERIES)) {
504
SetOptionsKeyBool(kvp.value, aOptions,
505
&nsINavHistoryQueryOptions::SetExpandQueries);
506
// include hidden
507
} else if (kvp.key.EqualsLiteral(QUERYKEY_INCLUDE_HIDDEN)) {
508
SetOptionsKeyBool(kvp.value, aOptions,
509
&nsINavHistoryQueryOptions::SetIncludeHidden);
510
// max results
511
} else if (kvp.key.EqualsLiteral(QUERYKEY_MAX_RESULTS)) {
512
SetOptionsKeyUint32(kvp.value, aOptions,
513
&nsINavHistoryQueryOptions::SetMaxResults);
514
// query type
515
} else if (kvp.key.EqualsLiteral(QUERYKEY_QUERY_TYPE)) {
516
SetOptionsKeyUint16(kvp.value, aOptions,
517
&nsINavHistoryQueryOptions::SetQueryType);
518
// async enabled
519
} else if (kvp.key.EqualsLiteral(QUERYKEY_ASYNC_ENABLED)) {
520
SetOptionsKeyBool(kvp.value, aOptions,
521
&nsINavHistoryQueryOptions::SetAsyncEnabled);
522
// unknown key
523
} else {
524
NS_WARNING("TokensToQueries(), ignoring unknown key: ");
525
NS_WARNING(kvp.key.get());
526
}
527
}
528
529
if (parents.Length() != 0) {
530
rv = aQuery->SetParents(parents);
531
NS_ENSURE_SUCCESS(rv, rv);
532
}
533
534
if (tags.Length() > 0) {
535
rv = aQuery->SetTags(tags);
536
NS_ENSURE_SUCCESS(rv, rv);
537
}
538
539
if (transitions.Length() > 0) {
540
rv = aQuery->SetTransitions(transitions);
541
NS_ENSURE_SUCCESS(rv, rv);
542
}
543
544
return NS_OK;
545
}
546
547
// ParseQueryBooleanString
548
//
549
// Converts a 0/1 or true/false string into a bool
550
551
nsresult ParseQueryBooleanString(const nsCString& aString, bool* aValue) {
552
if (aString.EqualsLiteral("1") || aString.EqualsLiteral("true")) {
553
*aValue = true;
554
return NS_OK;
555
} else if (aString.EqualsLiteral("0") || aString.EqualsLiteral("false")) {
556
*aValue = false;
557
return NS_OK;
558
}
559
return NS_ERROR_INVALID_ARG;
560
}
561
562
// nsINavHistoryQuery **********************************************************
563
564
NS_IMPL_ISUPPORTS(nsNavHistoryQuery, nsNavHistoryQuery, nsINavHistoryQuery)
565
566
// nsINavHistoryQuery::nsNavHistoryQuery
567
//
568
// This must initialize the object such that the default values will cause
569
// all history to be returned if this query is used. Then the caller can
570
// just set the things it's interested in.
571
572
nsNavHistoryQuery::nsNavHistoryQuery()
573
: mMinVisits(-1),
574
mMaxVisits(-1),
575
mBeginTime(0),
576
mBeginTimeReference(TIME_RELATIVE_EPOCH),
577
mEndTime(0),
578
mEndTimeReference(TIME_RELATIVE_EPOCH),
579
mOnlyBookmarked(false),
580
mDomainIsHost(false),
581
mAnnotationIsNot(false),
582
mTagsAreNot(false) {
583
// differentiate not set (IsVoid) from empty string (local files)
584
mDomain.SetIsVoid(true);
585
}
586
587
nsNavHistoryQuery::nsNavHistoryQuery(const nsNavHistoryQuery& aOther)
588
: mMinVisits(aOther.mMinVisits),
589
mMaxVisits(aOther.mMaxVisits),
590
mBeginTime(aOther.mBeginTime),
591
mBeginTimeReference(aOther.mBeginTimeReference),
592
mEndTime(aOther.mEndTime),
593
mEndTimeReference(aOther.mEndTimeReference),
594
mSearchTerms(aOther.mSearchTerms),
595
mOnlyBookmarked(aOther.mOnlyBookmarked),
596
mDomainIsHost(aOther.mDomainIsHost),
597
mDomain(aOther.mDomain),
598
mUri(aOther.mUri),
599
mAnnotationIsNot(aOther.mAnnotationIsNot),
600
mAnnotation(aOther.mAnnotation),
601
mParents(aOther.mParents),
602
mTags(aOther.mTags),
603
mTagsAreNot(aOther.mTagsAreNot),
604
mTransitions(aOther.mTransitions) {}
605
606
NS_IMETHODIMP nsNavHistoryQuery::GetBeginTime(PRTime* aBeginTime) {
607
*aBeginTime = mBeginTime;
608
return NS_OK;
609
}
610
NS_IMETHODIMP nsNavHistoryQuery::SetBeginTime(PRTime aBeginTime) {
611
mBeginTime = aBeginTime;
612
return NS_OK;
613
}
614
615
NS_IMETHODIMP nsNavHistoryQuery::GetBeginTimeReference(uint32_t* _retval) {
616
*_retval = mBeginTimeReference;
617
return NS_OK;
618
}
619
NS_IMETHODIMP nsNavHistoryQuery::SetBeginTimeReference(uint32_t aReference) {
620
if (aReference > TIME_RELATIVE_NOW) return NS_ERROR_INVALID_ARG;
621
mBeginTimeReference = aReference;
622
return NS_OK;
623
}
624
625
NS_IMETHODIMP nsNavHistoryQuery::GetHasBeginTime(bool* _retval) {
626
*_retval = !(mBeginTimeReference == TIME_RELATIVE_EPOCH && mBeginTime == 0);
627
return NS_OK;
628
}
629
630
NS_IMETHODIMP nsNavHistoryQuery::GetAbsoluteBeginTime(PRTime* _retval) {
631
*_retval = nsNavHistory::NormalizeTime(mBeginTimeReference, mBeginTime);
632
return NS_OK;
633
}
634
635
NS_IMETHODIMP nsNavHistoryQuery::GetEndTime(PRTime* aEndTime) {
636
*aEndTime = mEndTime;
637
return NS_OK;
638
}
639
NS_IMETHODIMP nsNavHistoryQuery::SetEndTime(PRTime aEndTime) {
640
mEndTime = aEndTime;
641
return NS_OK;
642
}
643
644
NS_IMETHODIMP nsNavHistoryQuery::GetEndTimeReference(uint32_t* _retval) {
645
*_retval = mEndTimeReference;
646
return NS_OK;
647
}
648
NS_IMETHODIMP nsNavHistoryQuery::SetEndTimeReference(uint32_t aReference) {
649
if (aReference > TIME_RELATIVE_NOW) return NS_ERROR_INVALID_ARG;
650
mEndTimeReference = aReference;
651
return NS_OK;
652
}
653
654
NS_IMETHODIMP nsNavHistoryQuery::GetHasEndTime(bool* _retval) {
655
*_retval = !(mEndTimeReference == TIME_RELATIVE_EPOCH && mEndTime == 0);
656
return NS_OK;
657
}
658
659
NS_IMETHODIMP nsNavHistoryQuery::GetAbsoluteEndTime(PRTime* _retval) {
660
*_retval = nsNavHistory::NormalizeTime(mEndTimeReference, mEndTime);
661
return NS_OK;
662
}
663
664
NS_IMETHODIMP nsNavHistoryQuery::GetSearchTerms(nsAString& aSearchTerms) {
665
aSearchTerms = mSearchTerms;
666
return NS_OK;
667
}
668
NS_IMETHODIMP nsNavHistoryQuery::SetSearchTerms(const nsAString& aSearchTerms) {
669
mSearchTerms = aSearchTerms;
670
return NS_OK;
671
}
672
NS_IMETHODIMP nsNavHistoryQuery::GetHasSearchTerms(bool* _retval) {
673
*_retval = (!mSearchTerms.IsEmpty());
674
return NS_OK;
675
}
676
677
NS_IMETHODIMP nsNavHistoryQuery::GetMinVisits(int32_t* _retval) {
678
NS_ENSURE_ARG_POINTER(_retval);
679
*_retval = mMinVisits;
680
return NS_OK;
681
}
682
NS_IMETHODIMP nsNavHistoryQuery::SetMinVisits(int32_t aVisits) {
683
mMinVisits = aVisits;
684
return NS_OK;
685
}
686
687
NS_IMETHODIMP nsNavHistoryQuery::GetMaxVisits(int32_t* _retval) {
688
NS_ENSURE_ARG_POINTER(_retval);
689
*_retval = mMaxVisits;
690
return NS_OK;
691
}
692
NS_IMETHODIMP nsNavHistoryQuery::SetMaxVisits(int32_t aVisits) {
693
mMaxVisits = aVisits;
694
return NS_OK;
695
}
696
697
NS_IMETHODIMP nsNavHistoryQuery::GetOnlyBookmarked(bool* aOnlyBookmarked) {
698
*aOnlyBookmarked = mOnlyBookmarked;
699
return NS_OK;
700
}
701
NS_IMETHODIMP nsNavHistoryQuery::SetOnlyBookmarked(bool aOnlyBookmarked) {
702
mOnlyBookmarked = aOnlyBookmarked;
703
return NS_OK;
704
}
705
706
NS_IMETHODIMP nsNavHistoryQuery::GetDomainIsHost(bool* aDomainIsHost) {
707
*aDomainIsHost = mDomainIsHost;
708
return NS_OK;
709
}
710
NS_IMETHODIMP nsNavHistoryQuery::SetDomainIsHost(bool aDomainIsHost) {
711
mDomainIsHost = aDomainIsHost;
712
return NS_OK;
713
}
714
715
NS_IMETHODIMP nsNavHistoryQuery::GetDomain(nsACString& aDomain) {
716
aDomain = mDomain;
717
return NS_OK;
718
}
719
NS_IMETHODIMP nsNavHistoryQuery::SetDomain(const nsACString& aDomain) {
720
mDomain = aDomain;
721
return NS_OK;
722
}
723
NS_IMETHODIMP nsNavHistoryQuery::GetHasDomain(bool* _retval) {
724
// note that empty but not void is still a valid query (local files)
725
*_retval = (!mDomain.IsVoid());
726
return NS_OK;
727
}
728
729
NS_IMETHODIMP nsNavHistoryQuery::GetUri(nsIURI** aUri) {
730
NS_IF_ADDREF(*aUri = mUri);
731
return NS_OK;
732
}
733
NS_IMETHODIMP nsNavHistoryQuery::SetUri(nsIURI* aUri) {
734
mUri = aUri;
735
return NS_OK;
736
}
737
NS_IMETHODIMP nsNavHistoryQuery::GetHasUri(bool* aHasUri) {
738
*aHasUri = (mUri != nullptr);
739
return NS_OK;
740
}
741
742
NS_IMETHODIMP nsNavHistoryQuery::GetAnnotationIsNot(bool* aIsNot) {
743
*aIsNot = mAnnotationIsNot;
744
return NS_OK;
745
}
746
NS_IMETHODIMP nsNavHistoryQuery::SetAnnotationIsNot(bool aIsNot) {
747
mAnnotationIsNot = aIsNot;
748
return NS_OK;
749
}
750
751
NS_IMETHODIMP nsNavHistoryQuery::GetAnnotation(nsACString& aAnnotation) {
752
aAnnotation = mAnnotation;
753
return NS_OK;
754
}
755
NS_IMETHODIMP nsNavHistoryQuery::SetAnnotation(const nsACString& aAnnotation) {
756
mAnnotation = aAnnotation;
757
return NS_OK;
758
}
759
NS_IMETHODIMP nsNavHistoryQuery::GetHasAnnotation(bool* aHasIt) {
760
*aHasIt = !mAnnotation.IsEmpty();
761
return NS_OK;
762
}
763
764
NS_IMETHODIMP nsNavHistoryQuery::GetTags(nsIVariant** aTags) {
765
NS_ENSURE_ARG_POINTER(aTags);
766
767
RefPtr<nsVariant> out = new nsVariant();
768
769
uint32_t arrayLen = mTags.Length();
770
771
nsresult rv;
772
if (arrayLen == 0)
773
rv = out->SetAsEmptyArray();
774
else {
775
// Note: The resulting nsIVariant dupes both the array and its elements.
776
const char16_t** array = reinterpret_cast<const char16_t**>(
777
moz_xmalloc(arrayLen * sizeof(char16_t*)));
778
for (uint32_t i = 0; i < arrayLen; ++i) {
779
array[i] = mTags[i].get();
780
}
781
782
rv = out->SetAsArray(nsIDataType::VTYPE_WCHAR_STR, nullptr, arrayLen,
783
reinterpret_cast<void*>(array));
784
free(array);
785
}
786
NS_ENSURE_SUCCESS(rv, rv);
787
788
out.forget(aTags);
789
return NS_OK;
790
}
791
792
NS_IMETHODIMP nsNavHistoryQuery::SetTags(nsIVariant* aTags) {
793
NS_ENSURE_ARG(aTags);
794
795
uint16_t dataType = aTags->GetDataType();
796
797
// Caller passed in empty array. Easy -- clear our mTags array and return.
798
if (dataType == nsIDataType::VTYPE_EMPTY_ARRAY) {
799
mTags.Clear();
800
return NS_OK;
801
}
802
803
// Before we go any further, make sure caller passed in an array.
804
NS_ENSURE_TRUE(dataType == nsIDataType::VTYPE_ARRAY, NS_ERROR_ILLEGAL_VALUE);
805
806
uint16_t eltType;
807
nsIID eltIID;
808
uint32_t arrayLen;
809
void* array;
810
811
// Convert the nsIVariant to an array. We own the resulting buffer and its
812
// elements.
813
nsresult rv = aTags->GetAsArray(&eltType, &eltIID, &arrayLen, &array);
814
NS_ENSURE_SUCCESS(rv, rv);
815
816
// If element type is not wstring, thanks a lot. Your memory die now.
817
if (eltType != nsIDataType::VTYPE_WCHAR_STR) {
818
switch (eltType) {
819
case nsIDataType::VTYPE_ID:
820
case nsIDataType::VTYPE_CHAR_STR: {
821
char** charArray = reinterpret_cast<char**>(array);
822
for (uint32_t i = 0; i < arrayLen; ++i) {
823
if (charArray[i]) free(charArray[i]);
824
}
825
} break;
826
case nsIDataType::VTYPE_INTERFACE:
827
case nsIDataType::VTYPE_INTERFACE_IS: {
828
nsISupports** supportsArray = reinterpret_cast<nsISupports**>(array);
829
for (uint32_t i = 0; i < arrayLen; ++i) {
830
NS_IF_RELEASE(supportsArray[i]);
831
}
832
} break;
833
// The other types are primitives that do not need to be freed.
834
}
835
free(array);
836
return NS_ERROR_ILLEGAL_VALUE;
837
}
838
839
char16_t** tags = reinterpret_cast<char16_t**>(array);
840
mTags.Clear();
841
842
// Finally, add each passed-in tag to our mTags array and then sort it.
843
for (uint32_t i = 0; i < arrayLen; ++i) {
844
// Don't allow nulls.
845
if (!tags[i]) {
846
free(tags);
847
return NS_ERROR_ILLEGAL_VALUE;
848
}
849
850
nsDependentString tag(tags[i]);
851
852
// Don't store duplicate tags. This isn't just to save memory or to be
853
// fancy; the SQL that's built from the tags relies on no dupes.
854
if (!mTags.Contains(tag)) {
855
if (!mTags.AppendElement(tag)) {
856
free(tags[i]);
857
free(tags);
858
return NS_ERROR_OUT_OF_MEMORY;
859
}
860
}
861
free(tags[i]);
862
}
863
free(tags);
864
865
mTags.Sort();
866
867
return NS_OK;
868
}
869
870
NS_IMETHODIMP nsNavHistoryQuery::GetTagsAreNot(bool* aTagsAreNot) {
871
NS_ENSURE_ARG_POINTER(aTagsAreNot);
872
*aTagsAreNot = mTagsAreNot;
873
return NS_OK;
874
}
875
876
NS_IMETHODIMP nsNavHistoryQuery::SetTagsAreNot(bool aTagsAreNot) {
877
mTagsAreNot = aTagsAreNot;
878
return NS_OK;
879
}
880
881
NS_IMETHODIMP nsNavHistoryQuery::GetParents(nsTArray<nsCString>& aGuids) {
882
aGuids = mParents;
883
return NS_OK;
884
}
885
886
NS_IMETHODIMP nsNavHistoryQuery::GetParentCount(uint32_t* aGuidCount) {
887
*aGuidCount = mParents.Length();
888
return NS_OK;
889
}
890
891
NS_IMETHODIMP nsNavHistoryQuery::SetParents(const nsTArray<nsCString>& aGuids) {
892
mParents.Clear();
893
if (!mParents.Assign(aGuids, fallible)) {
894
return NS_ERROR_OUT_OF_MEMORY;
895
}
896
897
return NS_OK;
898
}
899
900
NS_IMETHODIMP nsNavHistoryQuery::GetTransitions(
901
nsTArray<uint32_t>& aTransitions) {
902
aTransitions = mTransitions;
903
return NS_OK;
904
}
905
906
NS_IMETHODIMP nsNavHistoryQuery::GetTransitionCount(uint32_t* aCount) {
907
*aCount = mTransitions.Length();
908
return NS_OK;
909
}
910
911
NS_IMETHODIMP nsNavHistoryQuery::SetTransitions(
912
const nsTArray<uint32_t>& aTransitions) {
913
if (!mTransitions.Assign(aTransitions, fallible)) {
914
return NS_ERROR_OUT_OF_MEMORY;
915
}
916
return NS_OK;
917
}
918
919
NS_IMETHODIMP
920
nsNavHistoryQuery::Clone(nsINavHistoryQuery** _clone) {
921
nsNavHistoryQuery* clone = nullptr;
922
Unused << Clone(&clone);
923
*_clone = clone;
924
return NS_OK;
925
}
926
927
nsresult nsNavHistoryQuery::Clone(nsNavHistoryQuery** _clone) {
928
*_clone = nullptr;
929
RefPtr<nsNavHistoryQuery> clone = new nsNavHistoryQuery(*this);
930
clone.forget(_clone);
931
return NS_OK;
932
}
933
934
// nsNavHistoryQueryOptions
935
NS_IMPL_ISUPPORTS(nsNavHistoryQueryOptions, nsNavHistoryQueryOptions,
936
nsINavHistoryQueryOptions)
937
938
nsNavHistoryQueryOptions::nsNavHistoryQueryOptions()
939
: mSort(0),
940
mResultType(0),
941
mExcludeItems(false),
942
mExcludeQueries(false),
943
mExpandQueries(true),
944
mIncludeHidden(false),
945
mMaxResults(0),
946
mQueryType(nsINavHistoryQueryOptions::QUERY_TYPE_HISTORY),
947
mAsyncEnabled(false) {}
948
949
nsNavHistoryQueryOptions::nsNavHistoryQueryOptions(
950
const nsNavHistoryQueryOptions& other)
951
: mSort(other.mSort),
952
mResultType(other.mResultType),
953
mExcludeItems(other.mExcludeItems),
954
mExcludeQueries(other.mExcludeQueries),
955
mExpandQueries(other.mExpandQueries),
956
mIncludeHidden(other.mIncludeHidden),
957
mMaxResults(other.mMaxResults),
958
mQueryType(other.mQueryType),
959
mAsyncEnabled(other.mAsyncEnabled) {}
960
961
// sortingMode
962
NS_IMETHODIMP
963
nsNavHistoryQueryOptions::GetSortingMode(uint16_t* aMode) {
964
*aMode = mSort;
965
return NS_OK;
966
}
967
NS_IMETHODIMP
968
nsNavHistoryQueryOptions::SetSortingMode(uint16_t aMode) {
969
if (aMode > SORT_BY_FRECENCY_DESCENDING) return NS_ERROR_INVALID_ARG;
970
mSort = aMode;
971
return NS_OK;
972
}
973
974
// resultType
975
NS_IMETHODIMP
976
nsNavHistoryQueryOptions::GetResultType(uint16_t* aType) {
977
*aType = mResultType;
978
return NS_OK;
979
}
980
NS_IMETHODIMP
981
nsNavHistoryQueryOptions::SetResultType(uint16_t aType) {
982
if (aType > RESULTS_AS_LEFT_PANE_QUERY) return NS_ERROR_INVALID_ARG;
983
// Tag queries, containers and the roots query are bookmarks related, so we
984
// set the QueryType accordingly.
985
if (aType == RESULTS_AS_TAGS_ROOT || aType == RESULTS_AS_ROOTS_QUERY ||
986
aType == RESULTS_AS_LEFT_PANE_QUERY) {
987
mQueryType = QUERY_TYPE_BOOKMARKS;
988
}
989
mResultType = aType;
990
return NS_OK;
991
}
992
993
// excludeItems
994
NS_IMETHODIMP
995
nsNavHistoryQueryOptions::GetExcludeItems(bool* aExclude) {
996
*aExclude = mExcludeItems;
997
return NS_OK;
998
}
999
NS_IMETHODIMP
1000
nsNavHistoryQueryOptions::SetExcludeItems(bool aExclude) {
1001
mExcludeItems = aExclude;
1002
return NS_OK;
1003
}
1004
1005
// excludeQueries
1006
NS_IMETHODIMP
1007
nsNavHistoryQueryOptions::GetExcludeQueries(bool* aExclude) {
1008
*aExclude = mExcludeQueries;
1009
return NS_OK;
1010
}
1011
NS_IMETHODIMP
1012
nsNavHistoryQueryOptions::SetExcludeQueries(bool aExclude) {
1013
mExcludeQueries = aExclude;
1014
return NS_OK;
1015
}
1016
// expandQueries
1017
NS_IMETHODIMP
1018
nsNavHistoryQueryOptions::GetExpandQueries(bool* aExpand) {
1019
*aExpand = mExpandQueries;
1020
return NS_OK;
1021
}
1022
NS_IMETHODIMP
1023
nsNavHistoryQueryOptions::SetExpandQueries(bool aExpand) {
1024
mExpandQueries = aExpand;
1025
return NS_OK;
1026
}
1027
1028
// includeHidden
1029
NS_IMETHODIMP
1030
nsNavHistoryQueryOptions::GetIncludeHidden(bool* aIncludeHidden) {
1031
*aIncludeHidden = mIncludeHidden;
1032
return NS_OK;
1033
}
1034
NS_IMETHODIMP
1035
nsNavHistoryQueryOptions::SetIncludeHidden(bool aIncludeHidden) {
1036
mIncludeHidden = aIncludeHidden;
1037
return NS_OK;
1038
}
1039
1040
// maxResults
1041
NS_IMETHODIMP
1042
nsNavHistoryQueryOptions::GetMaxResults(uint32_t* aMaxResults) {
1043
*aMaxResults = mMaxResults;
1044
return NS_OK;
1045
}
1046
NS_IMETHODIMP
1047
nsNavHistoryQueryOptions::SetMaxResults(uint32_t aMaxResults) {
1048
mMaxResults = aMaxResults;
1049
return NS_OK;
1050
}
1051
1052
// queryType
1053
NS_IMETHODIMP
1054
nsNavHistoryQueryOptions::GetQueryType(uint16_t* _retval) {
1055
*_retval = mQueryType;
1056
return NS_OK;
1057
}
1058
NS_IMETHODIMP
1059
nsNavHistoryQueryOptions::SetQueryType(uint16_t aQueryType) {
1060
// Tag query and containers are forced to QUERY_TYPE_BOOKMARKS when the
1061
// resultType is set.
1062
if (mResultType == RESULTS_AS_TAGS_ROOT ||
1063
mResultType == RESULTS_AS_LEFT_PANE_QUERY ||
1064
mResultType == RESULTS_AS_ROOTS_QUERY)
1065
return NS_OK;
1066
mQueryType = aQueryType;
1067
return NS_OK;
1068
}
1069
1070
// asyncEnabled
1071
NS_IMETHODIMP
1072
nsNavHistoryQueryOptions::GetAsyncEnabled(bool* _asyncEnabled) {
1073
*_asyncEnabled = mAsyncEnabled;
1074
return NS_OK;
1075
}
1076
NS_IMETHODIMP
1077
nsNavHistoryQueryOptions::SetAsyncEnabled(bool aAsyncEnabled) {
1078
mAsyncEnabled = aAsyncEnabled;
1079
return NS_OK;
1080
}
1081
1082
NS_IMETHODIMP
1083
nsNavHistoryQueryOptions::Clone(nsINavHistoryQueryOptions** _clone) {
1084
nsNavHistoryQueryOptions* clone = nullptr;
1085
Unused << Clone(&clone);
1086
*_clone = clone;
1087
return NS_OK;
1088
}
1089
1090
nsresult nsNavHistoryQueryOptions::Clone(nsNavHistoryQueryOptions** _clone) {
1091
*_clone = nullptr;
1092
RefPtr<nsNavHistoryQueryOptions> clone = new nsNavHistoryQueryOptions(*this);
1093
clone.forget(_clone);
1094
return NS_OK;
1095
}
1096
1097
// AppendBoolKeyValueIfTrue
1098
1099
void // static
1100
AppendBoolKeyValueIfTrue(nsACString& aString, const nsCString& aName,
1101
nsINavHistoryQuery* aQuery, BoolQueryGetter getter) {
1102
bool value;
1103
DebugOnly<nsresult> rv = (aQuery->*getter)(&value);
1104
NS_ASSERTION(NS_SUCCEEDED(rv), "Failure getting boolean value");
1105
if (value) {
1106
AppendAmpersandIfNonempty(aString);
1107
aString += aName;
1108
aString.AppendLiteral("=1");
1109
}
1110
}
1111
1112
// AppendUint32KeyValueIfNonzero
1113
1114
void // static
1115
AppendUint32KeyValueIfNonzero(nsACString& aString, const nsCString& aName,
1116
nsINavHistoryQuery* aQuery,
1117
Uint32QueryGetter getter) {
1118
uint32_t value;
1119
DebugOnly<nsresult> rv = (aQuery->*getter)(&value);
1120
NS_ASSERTION(NS_SUCCEEDED(rv), "Failure getting value");
1121
if (value) {
1122
AppendAmpersandIfNonempty(aString);
1123
aString += aName;
1124
1125
// AppendInt requires a concrete string
1126
nsAutoCString appendMe("=");
1127
appendMe.AppendInt(value);
1128
aString.Append(appendMe);
1129
}
1130
}
1131
1132
// AppendInt64KeyValueIfNonzero
1133
1134
void // static
1135
AppendInt64KeyValueIfNonzero(nsACString& aString, const nsCString& aName,
1136
nsINavHistoryQuery* aQuery,
1137
Int64QueryGetter getter) {
1138
PRTime value;
1139
DebugOnly<nsresult> rv = (aQuery->*getter)(&value);
1140
NS_ASSERTION(NS_SUCCEEDED(rv), "Failure getting value");
1141
if (value) {
1142
AppendAmpersandIfNonempty(aString);
1143
aString += aName;
1144
nsAutoCString appendMe("=");
1145
appendMe.AppendInt(static_cast<int64_t>(value));
1146
aString.Append(appendMe);
1147
}
1148
}
1149
1150
// SetQuery/OptionsKeyBool
1151
1152
void // static
1153
SetQueryKeyBool(const nsCString& aValue, nsINavHistoryQuery* aQuery,
1154
BoolQuerySetter setter) {
1155
bool value;
1156
nsresult rv = ParseQueryBooleanString(aValue, &value);
1157
if (NS_SUCCEEDED(rv)) {
1158
rv = (aQuery->*setter)(value);
1159
if (NS_FAILED(rv)) {
1160
NS_WARNING("Error setting boolean key value");
1161
}
1162
} else {
1163
NS_WARNING("Invalid boolean key value in query string.");
1164
}
1165
}
1166
void // static
1167
SetOptionsKeyBool(const nsCString& aValue, nsINavHistoryQueryOptions* aOptions,
1168
BoolOptionsSetter setter) {
1169
bool value = false;
1170
nsresult rv = ParseQueryBooleanString(aValue, &value);
1171
if (NS_SUCCEEDED(rv)) {
1172
rv = (aOptions->*setter)(value);
1173
if (NS_FAILED(rv)) {
1174
NS_WARNING("Error setting boolean key value");
1175
}
1176
} else {
1177
NS_WARNING("Invalid boolean key value in query string.");
1178
}
1179
}
1180
1181
// SetQuery/OptionsKeyUint32
1182
1183
void // static
1184
SetQueryKeyUint32(const nsCString& aValue, nsINavHistoryQuery* aQuery,
1185
Uint32QuerySetter setter) {
1186
nsresult rv;
1187
uint32_t value = aValue.ToInteger(&rv);
1188
if (NS_SUCCEEDED(rv)) {
1189
rv = (aQuery->*setter)(value);
1190
if (NS_FAILED(rv)) {
1191
NS_WARNING("Error setting Int32 key value");
1192
}
1193
} else {
1194
NS_WARNING("Invalid Int32 key value in query string.");
1195
}
1196
}
1197
void // static
1198
SetOptionsKeyUint32(const nsCString& aValue,
1199
nsINavHistoryQueryOptions* aOptions,
1200
Uint32OptionsSetter setter) {
1201
nsresult rv;
1202
uint32_t value = aValue.ToInteger(&rv);
1203
if (NS_SUCCEEDED(rv)) {
1204
rv = (aOptions->*setter)(value);
1205
if (NS_FAILED(rv)) {
1206
NS_WARNING("Error setting Int32 key value");
1207
}
1208
} else {
1209
NS_WARNING("Invalid Int32 key value in query string.");
1210
}
1211
}
1212
1213
void // static
1214
SetOptionsKeyUint16(const nsCString& aValue,
1215
nsINavHistoryQueryOptions* aOptions,
1216
Uint16OptionsSetter setter) {
1217
nsresult rv;
1218
uint16_t value = static_cast<uint16_t>(aValue.ToInteger(&rv));
1219
if (NS_SUCCEEDED(rv)) {
1220
rv = (aOptions->*setter)(value);
1221
if (NS_FAILED(rv)) {
1222
NS_WARNING("Error setting Int16 key value");
1223
}
1224
} else {
1225
NS_WARNING("Invalid Int16 key value in query string.");
1226
}
1227
}
1228
1229
// SetQueryKeyInt64
1230
1231
void SetQueryKeyInt64(const nsCString& aValue, nsINavHistoryQuery* aQuery,
1232
Int64QuerySetter setter) {
1233
nsresult rv;
1234
int64_t value;
1235
if (PR_sscanf(aValue.get(), "%lld", &value) == 1) {
1236
rv = (aQuery->*setter)(value);
1237
if (NS_FAILED(rv)) {
1238
NS_WARNING("Error setting Int64 key value");
1239
}
1240
} else {
1241
NS_WARNING("Invalid Int64 value in query string.");
1242
}
1243
}