/src/mozilla-central/dom/commandhandler/nsCommandParams.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | #include "xpcom-config.h" |
8 | | #include <new> |
9 | | #include "nscore.h" |
10 | | #include "nsCRT.h" |
11 | | |
12 | | #include "nsCommandParams.h" |
13 | | #include "mozilla/HashFunctions.h" |
14 | | |
15 | | using namespace mozilla; |
16 | | |
17 | | const PLDHashTableOps nsCommandParams::sHashOps = |
18 | | { |
19 | | HashKey, |
20 | | HashMatchEntry, |
21 | | HashMoveEntry, |
22 | | HashClearEntry |
23 | | }; |
24 | | |
25 | | NS_IMPL_ISUPPORTS(nsCommandParams, nsICommandParams) |
26 | | |
27 | | nsCommandParams::nsCommandParams() |
28 | | : mValuesHash(&sHashOps, sizeof(HashEntry), 2) |
29 | 0 | { |
30 | 0 | } |
31 | | |
32 | | nsCommandParams::~nsCommandParams() |
33 | 0 | { |
34 | 0 | } |
35 | | |
36 | | NS_IMETHODIMP |
37 | | nsCommandParams::GetValueType(const char* aName, int16_t* aRetVal) |
38 | 0 | { |
39 | 0 | NS_ENSURE_ARG_POINTER(aRetVal); |
40 | 0 |
|
41 | 0 | HashEntry* foundEntry = GetNamedEntry(aName); |
42 | 0 | if (foundEntry) { |
43 | 0 | *aRetVal = foundEntry->mEntryType; |
44 | 0 | return NS_OK; |
45 | 0 | } |
46 | 0 | *aRetVal = eNoType; |
47 | 0 | return NS_ERROR_FAILURE; |
48 | 0 | } |
49 | | |
50 | | NS_IMETHODIMP |
51 | | nsCommandParams::GetBooleanValue(const char* aName, bool* aRetVal) |
52 | 0 | { |
53 | 0 | NS_ENSURE_ARG_POINTER(aRetVal); |
54 | 0 |
|
55 | 0 | ErrorResult error; |
56 | 0 | *aRetVal = GetBool(aName, error); |
57 | 0 | return error.StealNSResult(); |
58 | 0 | } |
59 | | |
60 | | bool |
61 | | nsCommandParams::GetBool(const char* aName, ErrorResult& aRv) const |
62 | 0 | { |
63 | 0 | MOZ_ASSERT(!aRv.Failed()); |
64 | 0 |
|
65 | 0 | HashEntry* foundEntry = GetNamedEntry(aName); |
66 | 0 | if (foundEntry && foundEntry->mEntryType == eBooleanType) { |
67 | 0 | return foundEntry->mData.mBoolean; |
68 | 0 | } |
69 | 0 | aRv.Throw(NS_ERROR_FAILURE); |
70 | 0 | return false; |
71 | 0 | } |
72 | | |
73 | | NS_IMETHODIMP |
74 | | nsCommandParams::GetLongValue(const char* aName, int32_t* aRetVal) |
75 | 0 | { |
76 | 0 | NS_ENSURE_ARG_POINTER(aRetVal); |
77 | 0 |
|
78 | 0 | ErrorResult error; |
79 | 0 | *aRetVal = GetInt(aName, error); |
80 | 0 | return error.StealNSResult(); |
81 | 0 | } |
82 | | |
83 | | int32_t |
84 | | nsCommandParams::GetInt(const char* aName, ErrorResult& aRv) const |
85 | 0 | { |
86 | 0 | MOZ_ASSERT(!aRv.Failed()); |
87 | 0 |
|
88 | 0 | HashEntry* foundEntry = GetNamedEntry(aName); |
89 | 0 | if (foundEntry && foundEntry->mEntryType == eLongType) { |
90 | 0 | return foundEntry->mData.mLong; |
91 | 0 | } |
92 | 0 | aRv.Throw(NS_ERROR_FAILURE); |
93 | 0 | return 0; |
94 | 0 | } |
95 | | |
96 | | NS_IMETHODIMP |
97 | | nsCommandParams::GetDoubleValue(const char* aName, double* aRetVal) |
98 | 0 | { |
99 | 0 | NS_ENSURE_ARG_POINTER(aRetVal); |
100 | 0 |
|
101 | 0 | ErrorResult error; |
102 | 0 | *aRetVal = GetDouble(aName, error); |
103 | 0 | return error.StealNSResult(); |
104 | 0 | } |
105 | | |
106 | | double |
107 | | nsCommandParams::GetDouble(const char* aName, ErrorResult& aRv) const |
108 | 0 | { |
109 | 0 | MOZ_ASSERT(!aRv.Failed()); |
110 | 0 |
|
111 | 0 | HashEntry* foundEntry = GetNamedEntry(aName); |
112 | 0 | if (foundEntry && foundEntry->mEntryType == eDoubleType) { |
113 | 0 | return foundEntry->mData.mDouble; |
114 | 0 | } |
115 | 0 | aRv.Throw(NS_ERROR_FAILURE); |
116 | 0 | return 0.0; |
117 | 0 | } |
118 | | |
119 | | NS_IMETHODIMP |
120 | | nsCommandParams::GetStringValue(const char* aName, nsAString& aRetVal) |
121 | 0 | { |
122 | 0 | return GetString(aName, aRetVal); |
123 | 0 | } |
124 | | |
125 | | nsresult |
126 | | nsCommandParams::GetString(const char* aName, nsAString& aRetVal) const |
127 | 0 | { |
128 | 0 | HashEntry* foundEntry = GetNamedEntry(aName); |
129 | 0 | if (foundEntry && foundEntry->mEntryType == eWStringType) { |
130 | 0 | NS_ASSERTION(foundEntry->mData.mString, "Null string"); |
131 | 0 | aRetVal.Assign(*foundEntry->mData.mString); |
132 | 0 | return NS_OK; |
133 | 0 | } |
134 | 0 | aRetVal.Truncate(); |
135 | 0 | return NS_ERROR_FAILURE; |
136 | 0 | } |
137 | | |
138 | | NS_IMETHODIMP |
139 | | nsCommandParams::GetCStringValue(const char* aName, nsACString& aRetVal) |
140 | 0 | { |
141 | 0 | return GetCString(aName, aRetVal); |
142 | 0 | } |
143 | | |
144 | | nsresult |
145 | | nsCommandParams::GetCString(const char* aName, nsACString& aRetVal) const |
146 | 0 | { |
147 | 0 | HashEntry* foundEntry = GetNamedEntry(aName); |
148 | 0 | if (foundEntry && foundEntry->mEntryType == eStringType) { |
149 | 0 | NS_ASSERTION(foundEntry->mData.mCString, "Null string"); |
150 | 0 | aRetVal.Assign(*foundEntry->mData.mCString); |
151 | 0 | return NS_OK; |
152 | 0 | } |
153 | 0 | aRetVal.Truncate(); |
154 | 0 | return NS_ERROR_FAILURE; |
155 | 0 | } |
156 | | |
157 | | NS_IMETHODIMP |
158 | | nsCommandParams::GetISupportsValue(const char* aName, nsISupports** aRetVal) |
159 | 0 | { |
160 | 0 | NS_ENSURE_ARG_POINTER(aRetVal); |
161 | 0 |
|
162 | 0 | ErrorResult error; |
163 | 0 | nsCOMPtr<nsISupports> result = GetISupports(aName, error); |
164 | 0 | if (result) { |
165 | 0 | result.forget(aRetVal); |
166 | 0 | } else { |
167 | 0 | *aRetVal = nullptr; |
168 | 0 | } |
169 | 0 | return error.StealNSResult(); |
170 | 0 | } |
171 | | |
172 | | already_AddRefed<nsISupports> |
173 | | nsCommandParams::GetISupports(const char* aName, ErrorResult& aRv) const |
174 | 0 | { |
175 | 0 | MOZ_ASSERT(!aRv.Failed()); |
176 | 0 |
|
177 | 0 | HashEntry* foundEntry = GetNamedEntry(aName); |
178 | 0 | if (foundEntry && foundEntry->mEntryType == eISupportsType) { |
179 | 0 | nsCOMPtr<nsISupports> result = foundEntry->mISupports; |
180 | 0 | return result.forget(); |
181 | 0 | } |
182 | 0 | aRv.Throw(NS_ERROR_FAILURE); |
183 | 0 | return nullptr; |
184 | 0 | } |
185 | | |
186 | | NS_IMETHODIMP |
187 | | nsCommandParams::SetBooleanValue(const char* aName, bool aValue) |
188 | 0 | { |
189 | 0 | return SetBool(aName, aValue); |
190 | 0 | } |
191 | | |
192 | | nsresult |
193 | | nsCommandParams::SetBool(const char* aName, bool aValue) |
194 | 0 | { |
195 | 0 | HashEntry* foundEntry = GetOrMakeEntry(aName, eBooleanType); |
196 | 0 | if (!foundEntry) { |
197 | 0 | return NS_ERROR_OUT_OF_MEMORY; |
198 | 0 | } |
199 | 0 | foundEntry->mData.mBoolean = aValue; |
200 | 0 | return NS_OK; |
201 | 0 | } |
202 | | |
203 | | NS_IMETHODIMP |
204 | | nsCommandParams::SetLongValue(const char* aName, int32_t aValue) |
205 | 0 | { |
206 | 0 | return SetInt(aName, aValue); |
207 | 0 | } |
208 | | |
209 | | nsresult |
210 | | nsCommandParams::SetInt(const char* aName, int32_t aValue) |
211 | 0 | { |
212 | 0 | HashEntry* foundEntry = GetOrMakeEntry(aName, eLongType); |
213 | 0 | if (!foundEntry) { |
214 | 0 | return NS_ERROR_OUT_OF_MEMORY; |
215 | 0 | } |
216 | 0 | foundEntry->mData.mLong = aValue; |
217 | 0 | return NS_OK; |
218 | 0 | } |
219 | | |
220 | | NS_IMETHODIMP |
221 | | nsCommandParams::SetDoubleValue(const char* aName, double aValue) |
222 | 0 | { |
223 | 0 | return SetDouble(aName, aValue); |
224 | 0 | } |
225 | | |
226 | | nsresult |
227 | | nsCommandParams::SetDouble(const char* aName, double aValue) |
228 | 0 | { |
229 | 0 | HashEntry* foundEntry = GetOrMakeEntry(aName, eDoubleType); |
230 | 0 | if (!foundEntry) { |
231 | 0 | return NS_ERROR_OUT_OF_MEMORY; |
232 | 0 | } |
233 | 0 | foundEntry->mData.mDouble = aValue; |
234 | 0 | return NS_OK; |
235 | 0 | } |
236 | | |
237 | | NS_IMETHODIMP |
238 | | nsCommandParams::SetStringValue(const char* aName, const nsAString& aValue) |
239 | 0 | { |
240 | 0 | return SetString(aName, aValue); |
241 | 0 | } |
242 | | |
243 | | nsresult |
244 | | nsCommandParams::SetString(const char* aName, const nsAString& aValue) |
245 | 0 | { |
246 | 0 | HashEntry* foundEntry = GetOrMakeEntry(aName, eWStringType); |
247 | 0 | if (!foundEntry) { |
248 | 0 | return NS_ERROR_OUT_OF_MEMORY; |
249 | 0 | } |
250 | 0 | foundEntry->mData.mString = new nsString(aValue); |
251 | 0 | return NS_OK; |
252 | 0 | } |
253 | | |
254 | | NS_IMETHODIMP |
255 | | nsCommandParams::SetCStringValue(const char* aName, const nsACString& aValue) |
256 | 0 | { |
257 | 0 | return SetCString(aName, aValue); |
258 | 0 | } |
259 | | |
260 | | nsresult |
261 | | nsCommandParams::SetCString(const char* aName, const nsACString& aValue) |
262 | 0 | { |
263 | 0 | HashEntry* foundEntry = GetOrMakeEntry(aName, eStringType); |
264 | 0 | if (!foundEntry) { |
265 | 0 | return NS_ERROR_OUT_OF_MEMORY; |
266 | 0 | } |
267 | 0 | foundEntry->mData.mCString = new nsCString(aValue); |
268 | 0 | return NS_OK; |
269 | 0 | } |
270 | | |
271 | | NS_IMETHODIMP |
272 | | nsCommandParams::SetISupportsValue(const char* aName, nsISupports* aValue) |
273 | 0 | { |
274 | 0 | return SetISupports(aName, aValue); |
275 | 0 | } |
276 | | |
277 | | nsresult |
278 | | nsCommandParams::SetISupports(const char* aName, nsISupports* aValue) |
279 | 0 | { |
280 | 0 | HashEntry* foundEntry = GetOrMakeEntry(aName, eISupportsType); |
281 | 0 | if (!foundEntry) { |
282 | 0 | return NS_ERROR_OUT_OF_MEMORY; |
283 | 0 | } |
284 | 0 | foundEntry->mISupports = aValue; // addrefs |
285 | 0 | return NS_OK; |
286 | 0 | } |
287 | | |
288 | | NS_IMETHODIMP |
289 | | nsCommandParams::RemoveValue(const char* aName) |
290 | 0 | { |
291 | 0 | mValuesHash.Remove((void*)aName); |
292 | 0 | return NS_OK; |
293 | 0 | } |
294 | | |
295 | | nsCommandParams::HashEntry* |
296 | | nsCommandParams::GetNamedEntry(const char* aName) const |
297 | 0 | { |
298 | 0 | return static_cast<HashEntry*>(mValuesHash.Search((void*)aName)); |
299 | 0 | } |
300 | | |
301 | | nsCommandParams::HashEntry* |
302 | | nsCommandParams::GetOrMakeEntry(const char* aName, uint8_t aEntryType) |
303 | 0 | { |
304 | 0 | auto foundEntry = static_cast<HashEntry*>(mValuesHash.Search((void*)aName)); |
305 | 0 | if (foundEntry) { // reuse existing entry |
306 | 0 | foundEntry->Reset(aEntryType); |
307 | 0 | return foundEntry; |
308 | 0 | } |
309 | 0 | |
310 | 0 | foundEntry = static_cast<HashEntry*>(mValuesHash.Add((void*)aName, fallible)); |
311 | 0 | if (!foundEntry) { |
312 | 0 | return nullptr; |
313 | 0 | } |
314 | 0 | |
315 | 0 | // Use placement new. Our ctor does not clobber keyHash, which is important. |
316 | 0 | new (foundEntry) HashEntry(aEntryType, aName); |
317 | 0 | return foundEntry; |
318 | 0 | } |
319 | | |
320 | | PLDHashNumber |
321 | | nsCommandParams::HashKey(const void* aKey) |
322 | 0 | { |
323 | 0 | return HashString((const char*)aKey); |
324 | 0 | } |
325 | | |
326 | | bool |
327 | | nsCommandParams::HashMatchEntry(const PLDHashEntryHdr* aEntry, const void* aKey) |
328 | 0 | { |
329 | 0 | const char* keyString = (const char*)aKey; |
330 | 0 | const HashEntry* thisEntry = static_cast<const HashEntry*>(aEntry); |
331 | 0 | return thisEntry->mEntryName.Equals(keyString); |
332 | 0 | } |
333 | | |
334 | | void |
335 | | nsCommandParams::HashMoveEntry(PLDHashTable* aTable, |
336 | | const PLDHashEntryHdr* aFrom, |
337 | | PLDHashEntryHdr* aTo) |
338 | 0 | { |
339 | 0 | auto* fromEntry = const_cast<HashEntry*>(static_cast<const HashEntry*>(aFrom)); |
340 | 0 | HashEntry* toEntry = static_cast<HashEntry*>(aTo); |
341 | 0 |
|
342 | 0 | new (KnownNotNull, toEntry) HashEntry(std::move(*fromEntry)); |
343 | 0 |
|
344 | 0 | fromEntry->~HashEntry(); |
345 | 0 | } |
346 | | |
347 | | void |
348 | | nsCommandParams::HashClearEntry(PLDHashTable* aTable, PLDHashEntryHdr* aEntry) |
349 | 0 | { |
350 | 0 | HashEntry* thisEntry = static_cast<HashEntry*>(aEntry); |
351 | 0 | thisEntry->~HashEntry(); |
352 | 0 | } |