Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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/. */
6 #include "xpcom-config.h"
7 #include <new> // for placement new
8 #include "nscore.h"
9 #include "nsCRT.h"
11 #include "nsCommandParams.h"
12 #include "mozilla/HashFunctions.h"
14 using namespace mozilla;
16 const PLDHashTableOps nsCommandParams::sHashOps =
17 {
18 PL_DHashAllocTable,
19 PL_DHashFreeTable,
20 HashKey,
21 HashMatchEntry,
22 HashMoveEntry,
23 HashClearEntry,
24 PL_DHashFinalizeStub
25 };
28 NS_IMPL_ISUPPORTS(nsCommandParams, nsICommandParams)
30 nsCommandParams::nsCommandParams()
31 : mCurEntry(0)
32 , mNumEntries(eNumEntriesUnknown)
33 {
34 // init the hash table later
35 }
37 nsCommandParams::~nsCommandParams()
38 {
39 PL_DHashTableFinish(&mValuesHash);
40 }
42 nsresult
43 nsCommandParams::Init()
44 {
45 PL_DHashTableInit(&mValuesHash, &sHashOps, (void *)this, sizeof(HashEntry), 4);
47 return NS_OK;
48 }
50 #if 0
51 #pragma mark -
52 #endif
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 }
66 return NS_ERROR_FAILURE;
67 }
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;
75 HashEntry* foundEntry = GetNamedEntry(name);
76 if (foundEntry && foundEntry->mEntryType == eBooleanType)
77 {
78 *_retval = foundEntry->mData.mBoolean;
79 return NS_OK;
80 }
82 return NS_ERROR_FAILURE;
83 }
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;
91 HashEntry* foundEntry = GetNamedEntry(name);
92 if (foundEntry && foundEntry->mEntryType == eLongType)
93 {
94 *_retval = foundEntry->mData.mLong;
95 return NS_OK;
96 }
98 return NS_ERROR_FAILURE;
99 }
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;
107 HashEntry* foundEntry = GetNamedEntry(name);
108 if (foundEntry && foundEntry->mEntryType == eDoubleType)
109 {
110 *_retval = foundEntry->mData.mDouble;
111 return NS_OK;
112 }
114 return NS_ERROR_FAILURE;
115 }
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 }
129 return NS_ERROR_FAILURE;
130 }
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 }
143 return NS_ERROR_FAILURE;
144 }
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;
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 }
159 return NS_ERROR_FAILURE;
160 }
162 #if 0
163 #pragma mark -
164 #endif
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;
173 foundEntry->mData.mBoolean = value;
175 return NS_OK;
176 }
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;
185 foundEntry->mData.mLong = value;
186 return NS_OK;
187 }
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;
196 foundEntry->mData.mDouble = value;
197 return NS_OK;
198 }
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;
207 foundEntry->mData.mString = new nsString(value);
208 return NS_OK;
209 }
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 }
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;
229 foundEntry->mISupports = value; // addrefs
230 return NS_OK;
231 }
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);
241 // inval the number of entries
242 mNumEntries = eNumEntriesUnknown;
243 return NS_OK;
244 }
246 #if 0
247 #pragma mark -
248 #endif
250 nsCommandParams::HashEntry*
251 nsCommandParams::GetNamedEntry(const char * name)
252 {
253 HashEntry *foundEntry = (HashEntry *)PL_DHashTableOperate(&mValuesHash, (void *)name, PL_DHASH_LOOKUP);
255 if (PL_DHASH_ENTRY_IS_BUSY(foundEntry))
256 return foundEntry;
258 return nullptr;
259 }
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;
269 do
270 {
271 if (!PL_DHASH_ENTRY_IS_LIVE(entry))
272 continue;
274 if ((int32_t)entryCount == index)
275 return entry;
277 entryCount ++;
278 } while (++entry < limit);
280 return nullptr;
281 }
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;
291 do
292 {
293 if (PL_DHASH_ENTRY_IS_LIVE(entry))
294 entryCount ++;
295 } while (++entry < limit);
297 return entryCount;
298 }
300 nsresult
301 nsCommandParams::GetOrMakeEntry(const char * name, uint8_t entryType, HashEntry*& outEntry)
302 {
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 }
313 foundEntry = (HashEntry *)PL_DHashTableOperate(&mValuesHash, (void *)name, PL_DHASH_ADD);
314 if (!foundEntry) return NS_ERROR_OUT_OF_MEMORY;
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 }
321 #if 0
322 #pragma mark -
323 #endif
325 PLDHashNumber
326 nsCommandParams::HashKey(PLDHashTable *table, const void *key)
327 {
328 return HashString((const char *)key);
329 }
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);
338 return thisEntry->mEntryName.Equals(keyString);
339 }
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);
348 *toEntry = *fromEntry;
349 // we leave from dirty, but that's OK
350 }
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 }
360 #if 0
361 #pragma mark -
362 #endif
364 /* boolean hasMoreElements (); */
365 NS_IMETHODIMP
366 nsCommandParams::HasMoreElements(bool *_retval)
367 {
368 NS_ENSURE_ARG_POINTER(_retval);
370 if (mNumEntries == eNumEntriesUnknown)
371 mNumEntries = GetNumEntries();
373 *_retval = mCurEntry < mNumEntries;
374 return NS_OK;
375 }
377 /* void first (); */
378 NS_IMETHODIMP
379 nsCommandParams::First()
380 {
381 mCurEntry = 0;
382 return NS_OK;
383 }
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;
393 *_retval = ToNewCString(thisEntry->mEntryName);
394 mCurEntry++;
395 return NS_OK;
396 }