Line data Source code
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 0 : NS_IMPL_ISUPPORTS(nsCommandParams, nsICommandParams)
26 :
27 0 : nsCommandParams::nsCommandParams()
28 0 : : mValuesHash(&sHashOps, sizeof(HashEntry), 2)
29 : {
30 0 : }
31 :
32 0 : nsCommandParams::~nsCommandParams()
33 : {
34 0 : }
35 :
36 : NS_IMETHODIMP
37 0 : nsCommandParams::GetValueType(const char* aName, int16_t* aRetVal)
38 : {
39 0 : NS_ENSURE_ARG_POINTER(aRetVal);
40 :
41 0 : HashEntry* foundEntry = GetNamedEntry(aName);
42 0 : if (foundEntry) {
43 0 : *aRetVal = foundEntry->mEntryType;
44 0 : return NS_OK;
45 : }
46 0 : *aRetVal = eNoType;
47 0 : return NS_ERROR_FAILURE;
48 : }
49 :
50 : NS_IMETHODIMP
51 0 : nsCommandParams::GetBooleanValue(const char* aName, bool* aRetVal)
52 : {
53 0 : NS_ENSURE_ARG_POINTER(aRetVal);
54 :
55 0 : HashEntry* foundEntry = GetNamedEntry(aName);
56 0 : if (foundEntry && foundEntry->mEntryType == eBooleanType) {
57 0 : *aRetVal = foundEntry->mData.mBoolean;
58 0 : return NS_OK;
59 : }
60 0 : *aRetVal = false;
61 0 : return NS_ERROR_FAILURE;
62 : }
63 :
64 : NS_IMETHODIMP
65 0 : nsCommandParams::GetLongValue(const char* aName, int32_t* aRetVal)
66 : {
67 0 : NS_ENSURE_ARG_POINTER(aRetVal);
68 :
69 0 : HashEntry* foundEntry = GetNamedEntry(aName);
70 0 : if (foundEntry && foundEntry->mEntryType == eLongType) {
71 0 : *aRetVal = foundEntry->mData.mLong;
72 0 : return NS_OK;
73 : }
74 0 : *aRetVal = false;
75 0 : return NS_ERROR_FAILURE;
76 : }
77 :
78 : NS_IMETHODIMP
79 0 : nsCommandParams::GetDoubleValue(const char* aName, double* aRetVal)
80 : {
81 0 : NS_ENSURE_ARG_POINTER(aRetVal);
82 :
83 0 : HashEntry* foundEntry = GetNamedEntry(aName);
84 0 : if (foundEntry && foundEntry->mEntryType == eDoubleType) {
85 0 : *aRetVal = foundEntry->mData.mDouble;
86 0 : return NS_OK;
87 : }
88 0 : *aRetVal = 0.0;
89 0 : return NS_ERROR_FAILURE;
90 : }
91 :
92 : NS_IMETHODIMP
93 0 : nsCommandParams::GetStringValue(const char* aName, nsAString& aRetVal)
94 : {
95 0 : HashEntry* foundEntry = GetNamedEntry(aName);
96 0 : if (foundEntry && foundEntry->mEntryType == eWStringType) {
97 0 : NS_ASSERTION(foundEntry->mData.mString, "Null string");
98 0 : aRetVal.Assign(*foundEntry->mData.mString);
99 0 : return NS_OK;
100 : }
101 0 : aRetVal.Truncate();
102 0 : return NS_ERROR_FAILURE;
103 : }
104 :
105 : NS_IMETHODIMP
106 0 : nsCommandParams::GetCStringValue(const char* aName, char** aRetVal)
107 : {
108 0 : NS_ENSURE_ARG_POINTER(aRetVal);
109 :
110 0 : HashEntry* foundEntry = GetNamedEntry(aName);
111 0 : if (foundEntry && foundEntry->mEntryType == eStringType) {
112 0 : NS_ASSERTION(foundEntry->mData.mCString, "Null string");
113 0 : *aRetVal = ToNewCString(*foundEntry->mData.mCString);
114 0 : return NS_OK;
115 : }
116 0 : *aRetVal = nullptr;
117 0 : return NS_ERROR_FAILURE;
118 : }
119 :
120 : NS_IMETHODIMP
121 0 : nsCommandParams::GetISupportsValue(const char* aName, nsISupports** aRetVal)
122 : {
123 0 : NS_ENSURE_ARG_POINTER(aRetVal);
124 :
125 0 : HashEntry* foundEntry = GetNamedEntry(aName);
126 0 : if (foundEntry && foundEntry->mEntryType == eISupportsType) {
127 0 : NS_IF_ADDREF(*aRetVal = foundEntry->mISupports.get());
128 0 : return NS_OK;
129 : }
130 0 : *aRetVal = nullptr;
131 0 : return NS_ERROR_FAILURE;
132 : }
133 :
134 : NS_IMETHODIMP
135 0 : nsCommandParams::SetBooleanValue(const char* aName, bool aValue)
136 : {
137 0 : HashEntry* foundEntry = GetOrMakeEntry(aName, eBooleanType);
138 0 : if (!foundEntry) {
139 0 : return NS_ERROR_OUT_OF_MEMORY;
140 : }
141 0 : foundEntry->mData.mBoolean = aValue;
142 0 : return NS_OK;
143 : }
144 :
145 : NS_IMETHODIMP
146 0 : nsCommandParams::SetLongValue(const char* aName, int32_t aValue)
147 : {
148 0 : HashEntry* foundEntry = GetOrMakeEntry(aName, eLongType);
149 0 : if (!foundEntry) {
150 0 : return NS_ERROR_OUT_OF_MEMORY;
151 : }
152 0 : foundEntry->mData.mLong = aValue;
153 0 : return NS_OK;
154 : }
155 :
156 : NS_IMETHODIMP
157 0 : nsCommandParams::SetDoubleValue(const char* aName, double aValue)
158 : {
159 0 : HashEntry* foundEntry = GetOrMakeEntry(aName, eDoubleType);
160 0 : if (!foundEntry) {
161 0 : return NS_ERROR_OUT_OF_MEMORY;
162 : }
163 0 : foundEntry->mData.mDouble = aValue;
164 0 : return NS_OK;
165 : }
166 :
167 : NS_IMETHODIMP
168 0 : nsCommandParams::SetStringValue(const char* aName, const nsAString& aValue)
169 : {
170 0 : HashEntry* foundEntry = GetOrMakeEntry(aName, eWStringType);
171 0 : if (!foundEntry) {
172 0 : return NS_ERROR_OUT_OF_MEMORY;
173 : }
174 0 : foundEntry->mData.mString = new nsString(aValue);
175 0 : return NS_OK;
176 : }
177 :
178 : NS_IMETHODIMP
179 0 : nsCommandParams::SetCStringValue(const char* aName, const char* aValue)
180 : {
181 0 : HashEntry* foundEntry = GetOrMakeEntry(aName, eStringType);
182 0 : if (!foundEntry) {
183 0 : return NS_ERROR_OUT_OF_MEMORY;
184 : }
185 0 : foundEntry->mData.mCString = new nsCString(aValue);
186 0 : return NS_OK;
187 : }
188 :
189 : NS_IMETHODIMP
190 0 : nsCommandParams::SetISupportsValue(const char* aName, nsISupports* aValue)
191 : {
192 0 : HashEntry* foundEntry = GetOrMakeEntry(aName, eISupportsType);
193 0 : if (!foundEntry) {
194 0 : return NS_ERROR_OUT_OF_MEMORY;
195 : }
196 0 : foundEntry->mISupports = aValue; // addrefs
197 0 : return NS_OK;
198 : }
199 :
200 : NS_IMETHODIMP
201 0 : nsCommandParams::RemoveValue(const char* aName)
202 : {
203 0 : mValuesHash.Remove((void*)aName);
204 0 : return NS_OK;
205 : }
206 :
207 : nsCommandParams::HashEntry*
208 0 : nsCommandParams::GetNamedEntry(const char* aName)
209 : {
210 0 : return static_cast<HashEntry*>(mValuesHash.Search((void*)aName));
211 : }
212 :
213 : nsCommandParams::HashEntry*
214 0 : nsCommandParams::GetOrMakeEntry(const char* aName, uint8_t aEntryType)
215 : {
216 0 : auto foundEntry = static_cast<HashEntry*>(mValuesHash.Search((void*)aName));
217 0 : if (foundEntry) { // reuse existing entry
218 0 : foundEntry->Reset(aEntryType);
219 0 : return foundEntry;
220 : }
221 :
222 0 : foundEntry = static_cast<HashEntry*>(mValuesHash.Add((void*)aName, fallible));
223 0 : if (!foundEntry) {
224 0 : return nullptr;
225 : }
226 :
227 : // Use placement new. Our ctor does not clobber keyHash, which is important.
228 0 : new (foundEntry) HashEntry(aEntryType, aName);
229 0 : return foundEntry;
230 : }
231 :
232 : PLDHashNumber
233 0 : nsCommandParams::HashKey(const void* aKey)
234 : {
235 0 : return HashString((const char*)aKey);
236 : }
237 :
238 : bool
239 0 : nsCommandParams::HashMatchEntry(const PLDHashEntryHdr* aEntry, const void* aKey)
240 : {
241 0 : const char* keyString = (const char*)aKey;
242 0 : const HashEntry* thisEntry = static_cast<const HashEntry*>(aEntry);
243 0 : return thisEntry->mEntryName.Equals(keyString);
244 : }
245 :
246 : void
247 0 : nsCommandParams::HashMoveEntry(PLDHashTable* aTable,
248 : const PLDHashEntryHdr* aFrom,
249 : PLDHashEntryHdr* aTo)
250 : {
251 0 : const HashEntry* fromEntry = static_cast<const HashEntry*>(aFrom);
252 0 : HashEntry* toEntry = static_cast<HashEntry*>(aTo);
253 :
254 0 : new (toEntry) HashEntry(*fromEntry);
255 :
256 0 : fromEntry->~HashEntry();
257 0 : }
258 :
259 : void
260 0 : nsCommandParams::HashClearEntry(PLDHashTable* aTable, PLDHashEntryHdr* aEntry)
261 : {
262 0 : HashEntry* thisEntry = static_cast<HashEntry*>(aEntry);
263 0 : thisEntry->~HashEntry();
264 0 : }
|