PageRenderTime 40ms CodeModel.GetById 13ms app.highlight 23ms RepoModel.GetById 2ms app.codeStats 0ms

/embedding/components/commandhandler/src/nsCommandParams.cpp

http://github.com/zpao/v8monkey
C++ | 427 lines | 292 code | 76 blank | 59 comment | 38 complexity | 7bf2112a50a6e15ecdf61edb15ed5190 MD5 | raw file
  1/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2/* ***** BEGIN LICENSE BLOCK *****
  3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  4 *
  5 * The contents of this file are subject to the Mozilla Public License Version
  6 * 1.1 (the "License"); you may not use this file except in compliance with
  7 * the License. You may obtain a copy of the License at
  8 * http://www.mozilla.org/MPL/
  9 *
 10 * Software distributed under the License is distributed on an "AS IS" basis,
 11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 12 * for the specific language governing rights and limitations under the
 13 * License.
 14 *
 15 * The Original Code is mozilla.org code.
 16 *
 17 * The Initial Developer of the Original Code is
 18 * Netscape Communications Corporation.
 19 * Portions created by the Initial Developer are Copyright (C) 1998
 20 * the Initial Developer. All Rights Reserved.
 21 *
 22 * Contributor(s):
 23 *
 24 * Alternatively, the contents of this file may be used under the terms of
 25 * either the GNU General Public License Version 2 or later (the "GPL"), or
 26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 27 * in which case the provisions of the GPL or the LGPL are applicable instead
 28 * of those above. If you wish to allow use of your version of this file only
 29 * under the terms of either the GPL or the LGPL, and not to allow others to
 30 * use your version of this file under the terms of the MPL, indicate your
 31 * decision by deleting the provisions above and replace them with the notice
 32 * and other provisions required by the GPL or the LGPL. If you do not delete
 33 * the provisions above, a recipient may use your version of this file under
 34 * the terms of any one of the MPL, the GPL or the LGPL.
 35 *
 36 * ***** END LICENSE BLOCK ***** */
 37
 38#include "xpcom-config.h"
 39#include NEW_H    // for placement new
 40#include "nscore.h"
 41#include "nsCRT.h"
 42
 43#include "nsCommandParams.h"
 44
 45
 46PLDHashTableOps nsCommandParams::sHashOps =
 47{
 48    PL_DHashAllocTable,
 49    PL_DHashFreeTable,
 50    HashKey,
 51    HashMatchEntry,
 52    HashMoveEntry,
 53    HashClearEntry,
 54    PL_DHashFinalizeStub
 55};
 56
 57
 58NS_IMPL_ISUPPORTS1(nsCommandParams, nsICommandParams)
 59
 60nsCommandParams::nsCommandParams()
 61: mCurEntry(0)
 62, mNumEntries(eNumEntriesUnknown)
 63{
 64  // init the hash table later
 65}
 66
 67nsCommandParams::~nsCommandParams()
 68{
 69  PL_DHashTableFinish(&mValuesHash);
 70}
 71
 72nsresult
 73nsCommandParams::Init()
 74{
 75  if (!PL_DHashTableInit(&mValuesHash, &sHashOps, (void *)this, sizeof(HashEntry), 4))
 76    return NS_ERROR_FAILURE;
 77    
 78  return NS_OK;
 79}
 80
 81#if 0
 82#pragma mark -
 83#endif
 84
 85/* short getValueType (in string name); */
 86NS_IMETHODIMP nsCommandParams::GetValueType(const char * name, PRInt16 *_retval)
 87{
 88  NS_ENSURE_ARG_POINTER(_retval);
 89  *_retval = eNoType;
 90  HashEntry*  foundEntry = GetNamedEntry(name);
 91  if (foundEntry)
 92  {
 93    *_retval = foundEntry->mEntryType;
 94    return NS_OK;
 95  }
 96  
 97  return NS_ERROR_FAILURE;
 98}
 99
100/* boolean getBooleanValue (in AString name); */
101NS_IMETHODIMP nsCommandParams::GetBooleanValue(const char * name, bool *_retval)
102{
103  NS_ENSURE_ARG_POINTER(_retval);
104  *_retval = false;
105
106  HashEntry*  foundEntry = GetNamedEntry(name);
107  if (foundEntry && foundEntry->mEntryType == eBooleanType)
108  {
109    *_retval = foundEntry->mData.mBoolean;
110    return NS_OK;
111  }
112  
113  return NS_ERROR_FAILURE;
114}
115
116/* long getLongValue (in AString name); */
117NS_IMETHODIMP nsCommandParams::GetLongValue(const char * name, PRInt32 *_retval)
118{
119  NS_ENSURE_ARG_POINTER(_retval);
120  *_retval = false;
121
122  HashEntry*  foundEntry = GetNamedEntry(name);
123  if (foundEntry && foundEntry->mEntryType == eLongType)
124  {
125    *_retval = foundEntry->mData.mLong;
126    return NS_OK;
127  }
128  
129  return NS_ERROR_FAILURE;
130}
131
132/* double getDoubleValue (in AString name); */
133NS_IMETHODIMP nsCommandParams::GetDoubleValue(const char * name, double *_retval)
134{
135  NS_ENSURE_ARG_POINTER(_retval);
136  *_retval = 0.0;
137
138  HashEntry*  foundEntry = GetNamedEntry(name);
139  if (foundEntry && foundEntry->mEntryType == eDoubleType)
140  {
141    *_retval = foundEntry->mData.mDouble;
142    return NS_OK;
143  }
144  
145  return NS_ERROR_FAILURE;
146}
147
148/* AString getStringValue (in AString name); */
149NS_IMETHODIMP nsCommandParams::GetStringValue(const char *name, nsAString & _retval)
150{
151  _retval.Truncate();
152  HashEntry*  foundEntry = GetNamedEntry(name);
153  if (foundEntry && foundEntry->mEntryType == eWStringType)
154  {
155    NS_ASSERTION(foundEntry->mData.mString, "Null string");
156    _retval.Assign(*foundEntry->mData.mString);
157    return NS_OK;
158  }
159  
160  return NS_ERROR_FAILURE;
161}
162
163/* AString getStringValue (in AString name); */
164NS_IMETHODIMP nsCommandParams::GetCStringValue(const char * name, char **_retval)
165{
166  HashEntry*  foundEntry = GetNamedEntry(name);
167  if (foundEntry && foundEntry->mEntryType == eStringType)
168  {
169    NS_ASSERTION(foundEntry->mData.mCString, "Null string");
170    *_retval = ToNewCString(*foundEntry->mData.mCString);
171    return NS_OK;
172  }
173  
174  return NS_ERROR_FAILURE;
175}
176
177/* nsISupports getISupportsValue (in AString name); */
178NS_IMETHODIMP nsCommandParams::GetISupportsValue(const char * name, nsISupports **_retval)
179{
180  NS_ENSURE_ARG_POINTER(_retval);
181  *_retval = nsnull;
182
183  HashEntry*  foundEntry = GetNamedEntry(name);
184  if (foundEntry && foundEntry->mEntryType == eISupportsType)
185  {
186    NS_IF_ADDREF(*_retval = foundEntry->mISupports.get());
187    return NS_OK;
188  }
189  
190  return NS_ERROR_FAILURE;
191}
192
193#if 0
194#pragma mark -
195#endif
196
197/* void setBooleanValue (in AString name, in boolean value); */
198NS_IMETHODIMP nsCommandParams::SetBooleanValue(const char * name, bool value)
199{
200  HashEntry*  foundEntry;
201  GetOrMakeEntry(name, eBooleanType, foundEntry);
202  if (!foundEntry) return NS_ERROR_OUT_OF_MEMORY;
203  
204  foundEntry->mData.mBoolean = value;
205  
206  return NS_OK;
207}
208
209/* void setLongValue (in AString name, in long value); */
210NS_IMETHODIMP nsCommandParams::SetLongValue(const char * name, PRInt32 value)
211{
212  HashEntry*  foundEntry;
213  GetOrMakeEntry(name, eLongType, foundEntry);
214  if (!foundEntry) return NS_ERROR_OUT_OF_MEMORY;
215  
216  foundEntry->mData.mLong = value;
217  return NS_OK;
218}
219
220/* void setDoubleValue (in AString name, in double value); */
221NS_IMETHODIMP nsCommandParams::SetDoubleValue(const char * name, double value)
222{
223  HashEntry*  foundEntry;
224  GetOrMakeEntry(name, eDoubleType, foundEntry);
225  if (!foundEntry) return NS_ERROR_OUT_OF_MEMORY;
226  
227  foundEntry->mData.mDouble = value;
228  return NS_OK;
229}
230
231/* void setStringValue (in AString name, in AString value); */
232NS_IMETHODIMP nsCommandParams::SetStringValue(const char * name, const nsAString & value)
233{
234  HashEntry*  foundEntry;
235  GetOrMakeEntry(name, eWStringType, foundEntry);
236  if (!foundEntry) return NS_ERROR_OUT_OF_MEMORY;
237  
238  foundEntry->mData.mString = new nsString(value);
239  return NS_OK;
240}
241
242/* void setCStringValue (in string name, in string value); */
243NS_IMETHODIMP nsCommandParams::SetCStringValue(const char * name, const char * value)
244{
245  HashEntry*  foundEntry;
246  GetOrMakeEntry(name, eStringType, foundEntry);
247  if (!foundEntry)
248    return NS_ERROR_OUT_OF_MEMORY;
249  foundEntry->mData.mCString = new nsCString(value);
250  return NS_OK;
251}
252
253/* void setISupportsValue (in AString name, in nsISupports value); */
254NS_IMETHODIMP nsCommandParams::SetISupportsValue(const char * name, nsISupports *value)
255{
256  HashEntry*  foundEntry;
257  GetOrMakeEntry(name, eISupportsType, foundEntry);
258  if (!foundEntry) return NS_ERROR_OUT_OF_MEMORY;
259  
260  foundEntry->mISupports = value;   // addrefs
261  return NS_OK;
262}
263
264/* void removeValue (in AString name); */
265NS_IMETHODIMP
266nsCommandParams::RemoveValue(const char * name)
267{
268  // PL_DHASH_REMOVE doesn't tell us if the entry was really removed, so we return
269  // NS_OK unconditionally.
270  (void)PL_DHashTableOperate(&mValuesHash, (void *)name, PL_DHASH_REMOVE);
271
272  // inval the number of entries
273  mNumEntries = eNumEntriesUnknown;
274  return NS_OK;
275}
276
277#if 0
278#pragma mark -
279#endif
280
281nsCommandParams::HashEntry*
282nsCommandParams::GetNamedEntry(const char * name)
283{
284  HashEntry *foundEntry = (HashEntry *)PL_DHashTableOperate(&mValuesHash, (void *)name, PL_DHASH_LOOKUP);
285
286  if (PL_DHASH_ENTRY_IS_BUSY(foundEntry))
287    return foundEntry;
288   
289  return nsnull;
290}
291
292
293nsCommandParams::HashEntry*
294nsCommandParams::GetIndexedEntry(PRInt32 index)
295{
296  HashEntry*  entry = reinterpret_cast<HashEntry*>(mValuesHash.entryStore);
297  HashEntry*  limit = entry + PL_DHASH_TABLE_SIZE(&mValuesHash);
298  PRUint32    entryCount = 0;
299  
300  do
301  {  
302    if (!PL_DHASH_ENTRY_IS_LIVE(entry))
303      continue;
304
305    if ((PRInt32)entryCount == index)
306      return entry;
307    
308    entryCount ++;
309  } while (++entry < limit);
310
311  return nsnull;
312}
313
314
315PRUint32
316nsCommandParams::GetNumEntries()
317{
318  HashEntry*  entry = reinterpret_cast<HashEntry*>(mValuesHash.entryStore);
319  HashEntry*  limit = entry + PL_DHASH_TABLE_SIZE(&mValuesHash);
320  PRUint32    entryCount = 0;
321  
322  do
323  {  
324    if (PL_DHASH_ENTRY_IS_LIVE(entry))
325      entryCount ++;
326  } while (++entry < limit);
327
328  return entryCount;
329}
330
331nsresult
332nsCommandParams::GetOrMakeEntry(const char * name, PRUint8 entryType, HashEntry*& outEntry)
333{
334
335  HashEntry *foundEntry = (HashEntry *)PL_DHashTableOperate(&mValuesHash, (void *)name, PL_DHASH_LOOKUP);
336  if (PL_DHASH_ENTRY_IS_BUSY(foundEntry))   // reuse existing entry  
337  {
338    foundEntry->Reset(entryType);
339    foundEntry->mEntryName.Assign(name);
340    outEntry = foundEntry;
341    return NS_OK;
342  }
343
344  foundEntry = (HashEntry *)PL_DHashTableOperate(&mValuesHash, (void *)name, PL_DHASH_ADD);
345  if (!foundEntry) return NS_ERROR_OUT_OF_MEMORY;
346  
347  // placement new that sucker. Our ctor does not clobber keyHash, which is important.
348  outEntry = new (foundEntry) HashEntry(entryType, name);  
349  return NS_OK;
350}
351
352#if 0
353#pragma mark -
354#endif
355
356PLDHashNumber
357nsCommandParams::HashKey(PLDHashTable *table, const void *key)
358{
359  return nsCRT::HashCode((const char *)key);
360}
361
362bool
363nsCommandParams::HashMatchEntry(PLDHashTable *table,
364                                const PLDHashEntryHdr *entry, const void *key)
365{
366  const char*   keyString = (const char*)key;
367  const HashEntry*   thisEntry = static_cast<const HashEntry*>(entry);
368  
369  return thisEntry->mEntryName.Equals(keyString);
370}
371
372void
373nsCommandParams::HashMoveEntry(PLDHashTable *table, const PLDHashEntryHdr *from,
374                                PLDHashEntryHdr *to)
375{
376  const HashEntry*   fromEntry  = static_cast<const HashEntry*>(from);
377  HashEntry*         toEntry    = static_cast<HashEntry*>(to);
378  
379  *toEntry = *fromEntry;
380  // we leave from dirty, but that's OK
381}
382
383void
384nsCommandParams::HashClearEntry(PLDHashTable *table, PLDHashEntryHdr *entry)
385{
386  HashEntry*    thisEntry = static_cast<HashEntry*>(entry);
387  thisEntry->~HashEntry();      // call dtor explicitly
388  memset(thisEntry, 0, sizeof(HashEntry));    // and clear out
389}
390
391#if 0
392#pragma mark -
393#endif
394
395/* boolean hasMoreElements (); */
396NS_IMETHODIMP
397nsCommandParams::HasMoreElements(bool *_retval)
398{
399  NS_ENSURE_ARG_POINTER(_retval);
400
401  if (mNumEntries == eNumEntriesUnknown)
402    mNumEntries = GetNumEntries();
403  
404  *_retval = mCurEntry < mNumEntries;
405  return NS_OK;
406}
407
408/* void first (); */
409NS_IMETHODIMP
410nsCommandParams::First()
411{
412  mCurEntry = 0;
413  return NS_OK;
414}
415
416/* AString getNext (); */
417NS_IMETHODIMP
418nsCommandParams::GetNext(char **_retval)
419{
420  HashEntry*    thisEntry = GetIndexedEntry(mCurEntry);
421  if (!thisEntry)
422    return NS_ERROR_FAILURE;
423  
424  *_retval = ToNewCString(thisEntry->mEntryName);
425  mCurEntry++;
426  return NS_OK;
427}