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