Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/toolkit/components/places/Helpers.h
Line
Count
Source (jump to first uncovered line)
1
/* vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
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
#ifndef mozilla_places_Helpers_h_
7
#define mozilla_places_Helpers_h_
8
9
/**
10
 * This file contains helper classes used by various bits of Places code.
11
 */
12
13
#include "mozilla/storage.h"
14
#include "nsIURI.h"
15
#include "nsThreadUtils.h"
16
#include "nsProxyRelease.h"
17
#include "prtime.h"
18
#include "mozilla/Telemetry.h"
19
20
namespace mozilla {
21
namespace places {
22
23
////////////////////////////////////////////////////////////////////////////////
24
//// Asynchronous Statement Callback Helper
25
26
class WeakAsyncStatementCallback : public mozIStorageStatementCallback
27
{
28
public:
29
  NS_DECL_MOZISTORAGESTATEMENTCALLBACK
30
0
  WeakAsyncStatementCallback() {}
31
32
protected:
33
0
  virtual ~WeakAsyncStatementCallback() {}
34
};
35
36
class AsyncStatementCallback : public WeakAsyncStatementCallback
37
{
38
public:
39
  NS_DECL_ISUPPORTS
40
0
  AsyncStatementCallback() {}
41
42
protected:
43
0
  virtual ~AsyncStatementCallback() {}
44
};
45
46
/**
47
 * Macros to use in place of NS_DECL_MOZISTORAGESTATEMENTCALLBACK to declare the
48
 * methods this class assumes silent or notreached.
49
 */
50
#define NS_DECL_ASYNCSTATEMENTCALLBACK \
51
  NS_IMETHOD HandleResult(mozIStorageResultSet *) override; \
52
  NS_IMETHOD HandleCompletion(uint16_t) override;
53
54
/**
55
 * Utils to bind a specified URI (or URL) to a statement or binding params, at
56
 * the specified index or name.
57
 * @note URIs are always bound as UTF8.
58
 */
59
class URIBinder // static
60
{
61
public:
62
  // Bind URI to statement by index.
63
  static nsresult Bind(mozIStorageStatement* statement,
64
                       int32_t index,
65
                       nsIURI* aURI);
66
  // Statement URLCString to statement by index.
67
  static nsresult Bind(mozIStorageStatement* statement,
68
                       int32_t index,
69
                       const nsACString& aURLString);
70
  // Bind URI to statement by name.
71
  static nsresult Bind(mozIStorageStatement* statement,
72
                       const nsACString& aName,
73
                       nsIURI* aURI);
74
  // Bind URLCString to statement by name.
75
  static nsresult Bind(mozIStorageStatement* statement,
76
                       const nsACString& aName,
77
                       const nsACString& aURLString);
78
  // Bind URI to params by index.
79
  static nsresult Bind(mozIStorageBindingParams* aParams,
80
                       int32_t index,
81
                       nsIURI* aURI);
82
  // Bind URLCString to params by index.
83
  static nsresult Bind(mozIStorageBindingParams* aParams,
84
                       int32_t index,
85
                       const nsACString& aURLString);
86
  // Bind URI to params by name.
87
  static nsresult Bind(mozIStorageBindingParams* aParams,
88
                       const nsACString& aName,
89
                       nsIURI* aURI);
90
  // Bind URLCString to params by name.
91
  static nsresult Bind(mozIStorageBindingParams* aParams,
92
                       const nsACString& aName,
93
                       const nsACString& aURLString);
94
};
95
96
/**
97
 * This extracts the hostname from the URI and reverses it in the
98
 * form that we use (always ending with a "."). So
99
 * "http://microsoft.com/" becomes "moc.tfosorcim."
100
 *
101
 * The idea behind this is that we can create an index over the items in
102
 * the reversed host name column, and then query for as much or as little
103
 * of the host name as we feel like.
104
 *
105
 * For example, the query "host >= 'gro.allizom.' AND host < 'gro.allizom/'
106
 * Matches all host names ending in '.mozilla.org', including
107
 * 'developer.mozilla.org' and just 'mozilla.org' (since we define all
108
 * reversed host names to end in a period, even 'mozilla.org' matches).
109
 * The important thing is that this operation uses the index. Any substring
110
 * calls in a select statement (even if it's for the beginning of a string)
111
 * will bypass any indices and will be slow).
112
 *
113
 * @param aURI
114
 *        URI that contains spec to reverse
115
 * @param aRevHost
116
 *        Out parameter
117
 */
118
nsresult GetReversedHostname(nsIURI* aURI, nsString& aRevHost);
119
120
/**
121
 * Similar method to GetReversedHostName but for strings
122
 */
123
void GetReversedHostname(const nsString& aForward, nsString& aRevHost);
124
125
/**
126
 * Reverses a string.
127
 *
128
 * @param aInput
129
 *        The string to be reversed
130
 * @param aReversed
131
 *        Output parameter will contain the reversed string
132
 */
133
void ReverseString(const nsString& aInput, nsString& aReversed);
134
135
/**
136
 * Generates an 12 character guid to be used by bookmark and history entries.
137
 *
138
 * @note This guid uses the characters a-z, A-Z, 0-9, '-', and '_'.
139
 */
140
nsresult GenerateGUID(nsACString& _guid);
141
142
/**
143
 * Determines if the string is a valid guid or not.
144
 *
145
 * @param aGUID
146
 *        The guid to test.
147
 * @return true if it is a valid guid, false otherwise.
148
 */
149
bool IsValidGUID(const nsACString& aGUID);
150
151
/**
152
 * Truncates the title if it's longer than TITLE_LENGTH_MAX.
153
 *
154
 * @param aTitle
155
 *        The title to truncate (if necessary)
156
 * @param aTrimmed
157
 *        Output parameter to return the trimmed string
158
 */
159
void TruncateTitle(const nsACString& aTitle, nsACString& aTrimmed);
160
161
/**
162
 * Round down a PRTime value to milliseconds precision (...000).
163
 *
164
 * @param aTime
165
 *        a PRTime value.
166
 * @return aTime rounded down to milliseconds precision.
167
 */
168
PRTime RoundToMilliseconds(PRTime aTime);
169
170
/**
171
 * Round down PR_Now() to milliseconds precision.
172
 *
173
 * @return @see PR_Now, RoundToMilliseconds.
174
 */
175
PRTime RoundedPRNow();
176
177
nsresult HashURL(const nsAString& aSpec, const nsACString& aMode,
178
                 uint64_t *_hash);
179
180
class QueryKeyValuePair final
181
{
182
public:
183
184
  QueryKeyValuePair(const nsACString &aKey, const nsACString &aValue)
185
0
  {
186
0
    key = aKey;
187
0
    value = aValue;
188
0
  };
189
190
  // QueryKeyValuePair
191
  //
192
  //                  01234567890
193
  //    input : qwerty&key=value&qwerty
194
  //                  ^   ^     ^
195
  //          aKeyBegin   |     aPastEnd (may point to null terminator)
196
  //                      aEquals
197
  //
198
  //    Special case: if aKeyBegin == aEquals, then there is only one string
199
  //    and no equal sign, so we treat the entire thing as a key with no value
200
201
  QueryKeyValuePair(const nsACString& aSource, int32_t aKeyBegin,
202
                    int32_t aEquals, int32_t aPastEnd)
203
0
  {
204
0
    if (aEquals == aKeyBegin)
205
0
      aEquals = aPastEnd;
206
0
    key = Substring(aSource, aKeyBegin, aEquals - aKeyBegin);
207
0
    if (aPastEnd - aEquals > 0)
208
0
      value = Substring(aSource, aEquals + 1, aPastEnd - aEquals - 1);
209
0
  }
210
  nsCString key;
211
  nsCString value;
212
 };
213
214
 /**
215
  * Tokenizes a QueryString.
216
  *
217
  * @param aQuery The string to tokenize.
218
  * @param aTokens The tokenized result.
219
  */
220
nsresult TokenizeQueryString(const nsACString& aQuery,
221
                             nsTArray<QueryKeyValuePair>* aTokens);
222
223
void TokensToQueryString(const nsTArray<QueryKeyValuePair> &aTokens,
224
                         nsACString &aQuery);
225
226
/**
227
 * Used to finalize a statementCache on a specified thread.
228
 */
229
template<typename StatementType>
230
class FinalizeStatementCacheProxy : public Runnable
231
{
232
public:
233
  /**
234
   * Constructor.
235
   *
236
   * @param aStatementCache
237
   *        The statementCache that should be finalized.
238
   * @param aOwner
239
   *        The object that owns the statement cache.  This runnable will hold
240
   *        a strong reference to it so aStatementCache will not disappear from
241
   *        under us.
242
   */
243
  FinalizeStatementCacheProxy(
244
    mozilla::storage::StatementCache<StatementType>& aStatementCache,
245
    nsISupports* aOwner)
246
    : Runnable("places::FinalizeStatementCacheProxy")
247
    , mStatementCache(aStatementCache)
248
    , mOwner(aOwner)
249
    , mCallingThread(do_GetCurrentThread())
250
0
  {
251
0
  }
252
253
  NS_IMETHOD Run() override
254
0
  {
255
0
    mStatementCache.FinalizeStatements();
256
0
    // Release the owner back on the calling thread.
257
0
    NS_ProxyRelease("FinalizeStatementCacheProxy::mOwner",
258
0
      mCallingThread, mOwner.forget());
259
0
    return NS_OK;
260
0
  }
261
262
protected:
263
  mozilla::storage::StatementCache<StatementType>& mStatementCache;
264
  nsCOMPtr<nsISupports> mOwner;
265
  nsCOMPtr<nsIThread> mCallingThread;
266
};
267
268
/**
269
 * Determines if a visit should be marked as hidden given its transition type
270
 * and whether or not it was a redirect.
271
 *
272
 * @param aIsRedirect
273
 *        True if this visit was a redirect, false otherwise.
274
 * @param aTransitionType
275
 *        The transition type of the visit.
276
 * @return true if this visit should be hidden.
277
 */
278
bool GetHiddenState(bool aIsRedirect,
279
                    uint32_t aTransitionType);
280
281
/**
282
 * Used to notify a topic to system observers on async execute completion.
283
 */
284
class AsyncStatementCallbackNotifier : public AsyncStatementCallback
285
{
286
public:
287
  explicit AsyncStatementCallbackNotifier(const char* aTopic)
288
    : mTopic(aTopic)
289
0
  {
290
0
  }
291
292
  NS_IMETHOD HandleCompletion(uint16_t aReason) override;
293
294
private:
295
  const char* mTopic;
296
};
297
298
/**
299
 * Used to notify a topic to system observers on async execute completion.
300
 */
301
class AsyncStatementTelemetryTimer : public AsyncStatementCallback
302
{
303
public:
304
  explicit AsyncStatementTelemetryTimer(Telemetry::HistogramID aHistogramId,
305
                                        TimeStamp aStart = TimeStamp::Now())
306
    : mHistogramId(aHistogramId)
307
    , mStart(aStart)
308
0
  {
309
0
  }
310
311
  NS_IMETHOD HandleCompletion(uint16_t aReason) override;
312
313
private:
314
  const Telemetry::HistogramID mHistogramId;
315
  const TimeStamp mStart;
316
};
317
318
} // namespace places
319
} // namespace mozilla
320
321
#endif // mozilla_places_Helpers_h_