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/. */
11 #include "nsCommandParams.h"
12 #include "mozilla/HashFunctions.h"
14 using namespace mozilla
;
16 const PLDHashTableOps
nsCommandParams::sHashOps
= {
17 HashKey
, HashMatchEntry
, HashMoveEntry
, HashClearEntry
};
19 NS_IMPL_ISUPPORTS(nsCommandParams
, nsICommandParams
)
21 nsCommandParams::nsCommandParams()
22 : mValuesHash(&sHashOps
, sizeof(HashEntry
), 2) {}
24 nsCommandParams::~nsCommandParams() = default;
27 nsCommandParams::GetValueType(const char* aName
, int16_t* aRetVal
) {
28 NS_ENSURE_ARG_POINTER(aRetVal
);
30 HashEntry
* foundEntry
= GetNamedEntry(aName
);
32 *aRetVal
= foundEntry
->mEntryType
;
36 return NS_ERROR_FAILURE
;
40 nsCommandParams::GetBooleanValue(const char* aName
, bool* aRetVal
) {
41 NS_ENSURE_ARG_POINTER(aRetVal
);
44 *aRetVal
= GetBool(aName
, error
);
45 return error
.StealNSResult();
48 bool nsCommandParams::GetBool(const char* aName
, ErrorResult
& aRv
) const {
49 MOZ_ASSERT(!aRv
.Failed());
51 HashEntry
* foundEntry
= GetNamedEntry(aName
);
52 if (foundEntry
&& foundEntry
->mEntryType
== eBooleanType
) {
53 return foundEntry
->mData
.mBoolean
;
55 aRv
.Throw(NS_ERROR_FAILURE
);
60 nsCommandParams::GetLongValue(const char* aName
, int32_t* aRetVal
) {
61 NS_ENSURE_ARG_POINTER(aRetVal
);
64 *aRetVal
= GetInt(aName
, error
);
65 return error
.StealNSResult();
68 int32_t nsCommandParams::GetInt(const char* aName
, ErrorResult
& aRv
) const {
69 MOZ_ASSERT(!aRv
.Failed());
71 HashEntry
* foundEntry
= GetNamedEntry(aName
);
72 if (foundEntry
&& foundEntry
->mEntryType
== eLongType
) {
73 return foundEntry
->mData
.mLong
;
75 aRv
.Throw(NS_ERROR_FAILURE
);
80 nsCommandParams::GetDoubleValue(const char* aName
, double* aRetVal
) {
81 NS_ENSURE_ARG_POINTER(aRetVal
);
84 *aRetVal
= GetDouble(aName
, error
);
85 return error
.StealNSResult();
88 double nsCommandParams::GetDouble(const char* aName
, ErrorResult
& aRv
) const {
89 MOZ_ASSERT(!aRv
.Failed());
91 HashEntry
* foundEntry
= GetNamedEntry(aName
);
92 if (foundEntry
&& foundEntry
->mEntryType
== eDoubleType
) {
93 return foundEntry
->mData
.mDouble
;
95 aRv
.Throw(NS_ERROR_FAILURE
);
100 nsCommandParams::GetStringValue(const char* aName
, nsAString
& aRetVal
) {
101 return GetString(aName
, aRetVal
);
104 nsresult
nsCommandParams::GetString(const char* aName
,
105 nsAString
& aRetVal
) const {
106 HashEntry
* foundEntry
= GetNamedEntry(aName
);
107 if (foundEntry
&& foundEntry
->mEntryType
== eWStringType
) {
108 NS_ASSERTION(foundEntry
->mData
.mString
, "Null string");
109 aRetVal
.Assign(*foundEntry
->mData
.mString
);
113 return NS_ERROR_FAILURE
;
117 nsCommandParams::GetCStringValue(const char* aName
, nsACString
& aRetVal
) {
118 return GetCString(aName
, aRetVal
);
121 nsresult
nsCommandParams::GetCString(const char* aName
,
122 nsACString
& aRetVal
) const {
123 HashEntry
* foundEntry
= GetNamedEntry(aName
);
124 if (foundEntry
&& foundEntry
->mEntryType
== eStringType
) {
125 NS_ASSERTION(foundEntry
->mData
.mCString
, "Null string");
126 aRetVal
.Assign(*foundEntry
->mData
.mCString
);
130 return NS_ERROR_FAILURE
;
134 nsCommandParams::GetISupportsValue(const char* aName
, nsISupports
** aRetVal
) {
135 NS_ENSURE_ARG_POINTER(aRetVal
);
138 nsCOMPtr
<nsISupports
> result
= GetISupports(aName
, error
);
140 result
.forget(aRetVal
);
144 return error
.StealNSResult();
147 already_AddRefed
<nsISupports
> nsCommandParams::GetISupports(
148 const char* aName
, ErrorResult
& aRv
) const {
149 MOZ_ASSERT(!aRv
.Failed());
151 HashEntry
* foundEntry
= GetNamedEntry(aName
);
152 if (foundEntry
&& foundEntry
->mEntryType
== eISupportsType
) {
153 nsCOMPtr
<nsISupports
> result
= foundEntry
->mISupports
;
154 return result
.forget();
156 aRv
.Throw(NS_ERROR_FAILURE
);
161 nsCommandParams::SetBooleanValue(const char* aName
, bool aValue
) {
162 return SetBool(aName
, aValue
);
165 nsresult
nsCommandParams::SetBool(const char* aName
, bool aValue
) {
166 HashEntry
* foundEntry
= GetOrMakeEntry(aName
, eBooleanType
);
168 return NS_ERROR_OUT_OF_MEMORY
;
170 foundEntry
->mData
.mBoolean
= aValue
;
175 nsCommandParams::SetLongValue(const char* aName
, int32_t aValue
) {
176 return SetInt(aName
, aValue
);
179 nsresult
nsCommandParams::SetInt(const char* aName
, int32_t aValue
) {
180 HashEntry
* foundEntry
= GetOrMakeEntry(aName
, eLongType
);
182 return NS_ERROR_OUT_OF_MEMORY
;
184 foundEntry
->mData
.mLong
= aValue
;
189 nsCommandParams::SetDoubleValue(const char* aName
, double aValue
) {
190 return SetDouble(aName
, aValue
);
193 nsresult
nsCommandParams::SetDouble(const char* aName
, double aValue
) {
194 HashEntry
* foundEntry
= GetOrMakeEntry(aName
, eDoubleType
);
196 return NS_ERROR_OUT_OF_MEMORY
;
198 foundEntry
->mData
.mDouble
= aValue
;
203 nsCommandParams::SetStringValue(const char* aName
, const nsAString
& aValue
) {
204 return SetString(aName
, aValue
);
207 nsresult
nsCommandParams::SetString(const char* aName
,
208 const nsAString
& aValue
) {
209 HashEntry
* foundEntry
= GetOrMakeEntry(aName
, eWStringType
);
211 return NS_ERROR_OUT_OF_MEMORY
;
213 foundEntry
->mData
.mString
= new nsString(aValue
);
218 nsCommandParams::SetCStringValue(const char* aName
, const nsACString
& aValue
) {
219 return SetCString(aName
, aValue
);
222 nsresult
nsCommandParams::SetCString(const char* aName
,
223 const nsACString
& aValue
) {
224 HashEntry
* foundEntry
= GetOrMakeEntry(aName
, eStringType
);
226 return NS_ERROR_OUT_OF_MEMORY
;
228 foundEntry
->mData
.mCString
= new nsCString(aValue
);
233 nsCommandParams::SetISupportsValue(const char* aName
, nsISupports
* aValue
) {
234 return SetISupports(aName
, aValue
);
237 nsresult
nsCommandParams::SetISupports(const char* aName
, nsISupports
* aValue
) {
238 HashEntry
* foundEntry
= GetOrMakeEntry(aName
, eISupportsType
);
240 return NS_ERROR_OUT_OF_MEMORY
;
242 foundEntry
->mISupports
= aValue
; // addrefs
247 nsCommandParams::RemoveValue(const char* aName
) {
248 mValuesHash
.Remove((void*)aName
);
252 nsCommandParams::HashEntry
* nsCommandParams::GetNamedEntry(
253 const char* aName
) const {
254 return static_cast<HashEntry
*>(mValuesHash
.Search((void*)aName
));
257 nsCommandParams::HashEntry
* nsCommandParams::GetOrMakeEntry(
258 const char* aName
, uint8_t aEntryType
) {
259 auto foundEntry
= static_cast<HashEntry
*>(mValuesHash
.Search((void*)aName
));
260 if (foundEntry
) { // reuse existing entry
261 foundEntry
->Reset(aEntryType
);
265 foundEntry
= static_cast<HashEntry
*>(mValuesHash
.Add((void*)aName
, fallible
));
270 // Use placement new. Our ctor does not clobber keyHash, which is important.
271 new (foundEntry
) HashEntry(aEntryType
, aName
);
275 PLDHashNumber
nsCommandParams::HashKey(const void* aKey
) {
276 return HashString((const char*)aKey
);
279 bool nsCommandParams::HashMatchEntry(const PLDHashEntryHdr
* aEntry
,
281 const char* keyString
= (const char*)aKey
;
282 const HashEntry
* thisEntry
= static_cast<const HashEntry
*>(aEntry
);
283 return thisEntry
->mEntryName
.Equals(keyString
);
286 void nsCommandParams::HashMoveEntry(PLDHashTable
* aTable
,
287 const PLDHashEntryHdr
* aFrom
,
288 PLDHashEntryHdr
* aTo
) {
290 const_cast<HashEntry
*>(static_cast<const HashEntry
*>(aFrom
));
291 HashEntry
* toEntry
= static_cast<HashEntry
*>(aTo
);
293 new (KnownNotNull
, toEntry
) HashEntry(std::move(*fromEntry
));
295 fromEntry
->~HashEntry();
298 void nsCommandParams::HashClearEntry(PLDHashTable
* aTable
,
299 PLDHashEntryHdr
* aEntry
) {
300 HashEntry
* thisEntry
= static_cast<HashEntry
*>(aEntry
);
301 thisEntry
->~HashEntry();