LCOV - code coverage report
Current view: top level - toolkit/components/places - nsNavHistoryQuery.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 843 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 101 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13