embedding/components/commandhandler/src/nsCommandParams.cpp

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:fd36215f805b
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
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 #include "xpcom-config.h"
7 #include <new> // for placement new
8 #include "nscore.h"
9 #include "nsCRT.h"
10
11 #include "nsCommandParams.h"
12 #include "mozilla/HashFunctions.h"
13
14 using namespace mozilla;
15
16 const PLDHashTableOps nsCommandParams::sHashOps =
17 {
18 PL_DHashAllocTable,
19 PL_DHashFreeTable,
20 HashKey,
21 HashMatchEntry,
22 HashMoveEntry,
23 HashClearEntry,
24 PL_DHashFinalizeStub
25 };
26
27
28 NS_IMPL_ISUPPORTS(nsCommandParams, nsICommandParams)
29
30 nsCommandParams::nsCommandParams()
31 : mCurEntry(0)
32 , mNumEntries(eNumEntriesUnknown)
33 {
34 // init the hash table later
35 }
36
37 nsCommandParams::~nsCommandParams()
38 {
39 PL_DHashTableFinish(&mValuesHash);
40 }
41
42 nsresult
43 nsCommandParams::Init()
44 {
45 PL_DHashTableInit(&mValuesHash, &sHashOps, (void *)this, sizeof(HashEntry), 4);
46
47 return NS_OK;
48 }
49
50 #if 0
51 #pragma mark -
52 #endif
53
54 /* short getValueType (in string name); */
55 NS_IMETHODIMP nsCommandParams::GetValueType(const char * name, int16_t *_retval)
56 {
57 NS_ENSURE_ARG_POINTER(_retval);
58 *_retval = eNoType;
59 HashEntry* foundEntry = GetNamedEntry(name);
60 if (foundEntry)
61 {
62 *_retval = foundEntry->mEntryType;
63 return NS_OK;
64 }
65
66 return NS_ERROR_FAILURE;
67 }
68
69 /* boolean getBooleanValue (in AString name); */
70 NS_IMETHODIMP nsCommandParams::GetBooleanValue(const char * name, bool *_retval)
71 {
72 NS_ENSURE_ARG_POINTER(_retval);
73 *_retval = false;
74
75 HashEntry* foundEntry = GetNamedEntry(name);
76 if (foundEntry && foundEntry->mEntryType == eBooleanType)
77 {
78 *_retval = foundEntry->mData.mBoolean;
79 return NS_OK;
80 }
81
82 return NS_ERROR_FAILURE;
83 }
84
85 /* long getLongValue (in AString name); */
86 NS_IMETHODIMP nsCommandParams::GetLongValue(const char * name, int32_t *_retval)
87 {
88 NS_ENSURE_ARG_POINTER(_retval);
89 *_retval = false;
90
91 HashEntry* foundEntry = GetNamedEntry(name);
92 if (foundEntry && foundEntry->mEntryType == eLongType)
93 {
94 *_retval = foundEntry->mData.mLong;
95 return NS_OK;
96 }
97
98 return NS_ERROR_FAILURE;
99 }
100
101 /* double getDoubleValue (in AString name); */
102 NS_IMETHODIMP nsCommandParams::GetDoubleValue(const char * name, double *_retval)
103 {
104 NS_ENSURE_ARG_POINTER(_retval);
105 *_retval = 0.0;
106
107 HashEntry* foundEntry = GetNamedEntry(name);
108 if (foundEntry && foundEntry->mEntryType == eDoubleType)
109 {
110 *_retval = foundEntry->mData.mDouble;
111 return NS_OK;
112 }
113
114 return NS_ERROR_FAILURE;
115 }
116
117 /* AString getStringValue (in AString name); */
118 NS_IMETHODIMP nsCommandParams::GetStringValue(const char *name, nsAString & _retval)
119 {
120 _retval.Truncate();
121 HashEntry* foundEntry = GetNamedEntry(name);
122 if (foundEntry && foundEntry->mEntryType == eWStringType)
123 {
124 NS_ASSERTION(foundEntry->mData.mString, "Null string");
125 _retval.Assign(*foundEntry->mData.mString);
126 return NS_OK;
127 }
128
129 return NS_ERROR_FAILURE;
130 }
131
132 /* AString getStringValue (in AString name); */
133 NS_IMETHODIMP nsCommandParams::GetCStringValue(const char * name, char **_retval)
134 {
135 HashEntry* foundEntry = GetNamedEntry(name);
136 if (foundEntry && foundEntry->mEntryType == eStringType)
137 {
138 NS_ASSERTION(foundEntry->mData.mCString, "Null string");
139 *_retval = ToNewCString(*foundEntry->mData.mCString);
140 return NS_OK;
141 }
142
143 return NS_ERROR_FAILURE;
144 }
145
146 /* nsISupports getISupportsValue (in AString name); */
147 NS_IMETHODIMP nsCommandParams::GetISupportsValue(const char * name, nsISupports **_retval)
148 {
149 NS_ENSURE_ARG_POINTER(_retval);
150 *_retval = nullptr;
151
152 HashEntry* foundEntry = GetNamedEntry(name);
153 if (foundEntry && foundEntry->mEntryType == eISupportsType)
154 {
155 NS_IF_ADDREF(*_retval = foundEntry->mISupports.get());
156 return NS_OK;
157 }
158
159 return NS_ERROR_FAILURE;
160 }
161
162 #if 0
163 #pragma mark -
164 #endif
165
166 /* void setBooleanValue (in AString name, in boolean value); */
167 NS_IMETHODIMP nsCommandParams::SetBooleanValue(const char * name, bool value)
168 {
169 HashEntry* foundEntry;
170 GetOrMakeEntry(name, eBooleanType, foundEntry);
171 if (!foundEntry) return NS_ERROR_OUT_OF_MEMORY;
172
173 foundEntry->mData.mBoolean = value;
174
175 return NS_OK;
176 }
177
178 /* void setLongValue (in AString name, in long value); */
179 NS_IMETHODIMP nsCommandParams::SetLongValue(const char * name, int32_t value)
180 {
181 HashEntry* foundEntry;
182 GetOrMakeEntry(name, eLongType, foundEntry);
183 if (!foundEntry) return NS_ERROR_OUT_OF_MEMORY;
184
185 foundEntry->mData.mLong = value;
186 return NS_OK;
187 }
188
189 /* void setDoubleValue (in AString name, in double value); */
190 NS_IMETHODIMP nsCommandParams::SetDoubleValue(const char * name, double value)
191 {
192 HashEntry* foundEntry;
193 GetOrMakeEntry(name, eDoubleType, foundEntry);
194 if (!foundEntry) return NS_ERROR_OUT_OF_MEMORY;
195
196 foundEntry->mData.mDouble = value;
197 return NS_OK;
198 }
199
200 /* void setStringValue (in AString name, in AString value); */
201 NS_IMETHODIMP nsCommandParams::SetStringValue(const char * name, const nsAString & value)
202 {
203 HashEntry* foundEntry;
204 GetOrMakeEntry(name, eWStringType, foundEntry);
205 if (!foundEntry) return NS_ERROR_OUT_OF_MEMORY;
206
207 foundEntry->mData.mString = new nsString(value);
208 return NS_OK;
209 }
210
211 /* void setCStringValue (in string name, in string value); */
212 NS_IMETHODIMP nsCommandParams::SetCStringValue(const char * name, const char * value)
213 {
214 HashEntry* foundEntry;
215 GetOrMakeEntry(name, eStringType, foundEntry);
216 if (!foundEntry)
217 return NS_ERROR_OUT_OF_MEMORY;
218 foundEntry->mData.mCString = new nsCString(value);
219 return NS_OK;
220 }
221
222 /* void setISupportsValue (in AString name, in nsISupports value); */
223 NS_IMETHODIMP nsCommandParams::SetISupportsValue(const char * name, nsISupports *value)
224 {
225 HashEntry* foundEntry;
226 GetOrMakeEntry(name, eISupportsType, foundEntry);
227 if (!foundEntry) return NS_ERROR_OUT_OF_MEMORY;
228
229 foundEntry->mISupports = value; // addrefs
230 return NS_OK;
231 }
232
233 /* void removeValue (in AString name); */
234 NS_IMETHODIMP
235 nsCommandParams::RemoveValue(const char * name)
236 {
237 // PL_DHASH_REMOVE doesn't tell us if the entry was really removed, so we return
238 // NS_OK unconditionally.
239 (void)PL_DHashTableOperate(&mValuesHash, (void *)name, PL_DHASH_REMOVE);
240
241 // inval the number of entries
242 mNumEntries = eNumEntriesUnknown;
243 return NS_OK;
244 }
245
246 #if 0
247 #pragma mark -
248 #endif
249
250 nsCommandParams::HashEntry*
251 nsCommandParams::GetNamedEntry(const char * name)
252 {
253 HashEntry *foundEntry = (HashEntry *)PL_DHashTableOperate(&mValuesHash, (void *)name, PL_DHASH_LOOKUP);
254
255 if (PL_DHASH_ENTRY_IS_BUSY(foundEntry))
256 return foundEntry;
257
258 return nullptr;
259 }
260
261
262 nsCommandParams::HashEntry*
263 nsCommandParams::GetIndexedEntry(int32_t index)
264 {
265 HashEntry* entry = reinterpret_cast<HashEntry*>(mValuesHash.entryStore);
266 HashEntry* limit = entry + PL_DHASH_TABLE_SIZE(&mValuesHash);
267 uint32_t entryCount = 0;
268
269 do
270 {
271 if (!PL_DHASH_ENTRY_IS_LIVE(entry))
272 continue;
273
274 if ((int32_t)entryCount == index)
275 return entry;
276
277 entryCount ++;
278 } while (++entry < limit);
279
280 return nullptr;
281 }
282
283
284 uint32_t
285 nsCommandParams::GetNumEntries()
286 {
287 HashEntry* entry = reinterpret_cast<HashEntry*>(mValuesHash.entryStore);
288 HashEntry* limit = entry + PL_DHASH_TABLE_SIZE(&mValuesHash);
289 uint32_t entryCount = 0;
290
291 do
292 {
293 if (PL_DHASH_ENTRY_IS_LIVE(entry))
294 entryCount ++;
295 } while (++entry < limit);
296
297 return entryCount;
298 }
299
300 nsresult
301 nsCommandParams::GetOrMakeEntry(const char * name, uint8_t entryType, HashEntry*& outEntry)
302 {
303
304 HashEntry *foundEntry = (HashEntry *)PL_DHashTableOperate(&mValuesHash, (void *)name, PL_DHASH_LOOKUP);
305 if (PL_DHASH_ENTRY_IS_BUSY(foundEntry)) // reuse existing entry
306 {
307 foundEntry->Reset(entryType);
308 foundEntry->mEntryName.Assign(name);
309 outEntry = foundEntry;
310 return NS_OK;
311 }
312
313 foundEntry = (HashEntry *)PL_DHashTableOperate(&mValuesHash, (void *)name, PL_DHASH_ADD);
314 if (!foundEntry) return NS_ERROR_OUT_OF_MEMORY;
315
316 // placement new that sucker. Our ctor does not clobber keyHash, which is important.
317 outEntry = new (foundEntry) HashEntry(entryType, name);
318 return NS_OK;
319 }
320
321 #if 0
322 #pragma mark -
323 #endif
324
325 PLDHashNumber
326 nsCommandParams::HashKey(PLDHashTable *table, const void *key)
327 {
328 return HashString((const char *)key);
329 }
330
331 bool
332 nsCommandParams::HashMatchEntry(PLDHashTable *table,
333 const PLDHashEntryHdr *entry, const void *key)
334 {
335 const char* keyString = (const char*)key;
336 const HashEntry* thisEntry = static_cast<const HashEntry*>(entry);
337
338 return thisEntry->mEntryName.Equals(keyString);
339 }
340
341 void
342 nsCommandParams::HashMoveEntry(PLDHashTable *table, const PLDHashEntryHdr *from,
343 PLDHashEntryHdr *to)
344 {
345 const HashEntry* fromEntry = static_cast<const HashEntry*>(from);
346 HashEntry* toEntry = static_cast<HashEntry*>(to);
347
348 *toEntry = *fromEntry;
349 // we leave from dirty, but that's OK
350 }
351
352 void
353 nsCommandParams::HashClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
354 {
355 HashEntry* thisEntry = static_cast<HashEntry*>(entry);
356 thisEntry->~HashEntry(); // call dtor explicitly
357 memset(thisEntry, 0, sizeof(HashEntry)); // and clear out
358 }
359
360 #if 0
361 #pragma mark -
362 #endif
363
364 /* boolean hasMoreElements (); */
365 NS_IMETHODIMP
366 nsCommandParams::HasMoreElements(bool *_retval)
367 {
368 NS_ENSURE_ARG_POINTER(_retval);
369
370 if (mNumEntries == eNumEntriesUnknown)
371 mNumEntries = GetNumEntries();
372
373 *_retval = mCurEntry < mNumEntries;
374 return NS_OK;
375 }
376
377 /* void first (); */
378 NS_IMETHODIMP
379 nsCommandParams::First()
380 {
381 mCurEntry = 0;
382 return NS_OK;
383 }
384
385 /* AString getNext (); */
386 NS_IMETHODIMP
387 nsCommandParams::GetNext(char **_retval)
388 {
389 HashEntry* thisEntry = GetIndexedEntry(mCurEntry);
390 if (!thisEntry)
391 return NS_ERROR_FAILURE;
392
393 *_retval = ToNewCString(thisEntry->mEntryName);
394 mCurEntry++;
395 return NS_OK;
396 }

mercurial