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