/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_ |