hash.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:6k
源码类别:

CA认证

开发平台:

WINDOWS

  1. /* 
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is the Netscape security libraries.
  13.  * 
  14.  * The Initial Developer of the Original Code is Netscape
  15.  * Communications Corporation.  Portions created by Netscape are 
  16.  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
  17.  * Rights Reserved.
  18.  * 
  19.  * Contributor(s):
  20.  * 
  21.  * Alternatively, the contents of this file may be used under the
  22.  * terms of the GNU General Public License Version 2 or later (the
  23.  * "GPL"), in which case the provisions of the GPL are applicable 
  24.  * instead of those above.  If you wish to allow use of your 
  25.  * version of this file only under the terms of the GPL and not to
  26.  * allow others to use your version of this file under the MPL,
  27.  * indicate your decision by deleting the provisions above and
  28.  * replace them with the notice and other provisions required by
  29.  * the GPL.  If you do not delete the provisions above, a recipient
  30.  * may use your version of this file under either the MPL or the
  31.  * GPL.
  32.  */
  33. #ifdef DEBUG
  34. static const char CVS_ID[] = "@(#) $RCSfile: hash.c,v $ $Revision: 1.1 $ $Date: 2000/03/31 19:43:15 $ $Name: NSS_3_1_1_RTM $";
  35. #endif /* DEBUG */
  36. /*
  37.  * hash.c
  38.  *
  39.  * This is merely a couple wrappers around NSPR's PLHashTable, using
  40.  * the identity hash and arena-aware allocators.  The reason I did
  41.  * this is that hash tables are used in a few places throughout the
  42.  * NSS Cryptoki Framework in a fairly stereotyped way, and this allows
  43.  * me to pull the commonalities into one place.  Should we ever want
  44.  * to change the implementation, it's all right here.
  45.  */
  46. #ifndef CK_T
  47. #include "ck.h"
  48. #endif /* CK_T */
  49. /*
  50.  * nssCKFWHash
  51.  *
  52.  *  nssCKFWHash_Create
  53.  *  nssCKFWHash_Destroy
  54.  *  nssCKFWHash_Add
  55.  *  nssCKFWHash_Remove
  56.  *  nssCKFWHash_Count
  57.  *  nssCKFWHash_Exists
  58.  *  nssCKFWHash_Lookup
  59.  *  nssCKFWHash_Iterate
  60.  */
  61. struct nssCKFWHashStr {
  62.   NSSCKFWMutex *mutex;
  63.   /*
  64.    * The invariant that mutex protects is:
  65.    *   The count accurately reflects the hashtable state.
  66.    */
  67.   PLHashTable *plHashTable;
  68.   CK_ULONG count;
  69. };
  70. static PLHashNumber
  71. nss_ckfw_identity_hash
  72. (
  73.   const void *key
  74. )
  75. {
  76.   PRUint32 i = (PRUint32)key;
  77.   PR_ASSERT(sizeof(PLHashNumber) == sizeof(PRUint32));
  78.   return (PLHashNumber)i;
  79. }
  80. /*
  81.  * nssCKFWHash_Create
  82.  *
  83.  */
  84. NSS_IMPLEMENT nssCKFWHash *
  85. nssCKFWHash_Create
  86. (
  87.   NSSCKFWInstance *fwInstance,
  88.   NSSArena *arena,
  89.   CK_RV *pError
  90. )
  91. {
  92.   nssCKFWHash *rv;
  93. #ifdef NSSDEBUG
  94.   if( (CK_RV *)NULL == pError ) {
  95.     return (nssCKFWHash *)NULL;
  96.   }
  97.   if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
  98.     *pError = CKR_ARGUMENTS_BAD;
  99.     return (nssCKFWHash *)NULL;
  100.   }
  101. #endif /* NSSDEBUG */
  102.   rv = nss_ZNEW(arena, nssCKFWHash);
  103.   if( (nssCKFWHash *)NULL == rv ) {
  104.     *pError = CKR_HOST_MEMORY;
  105.     return (nssCKFWHash *)NULL;
  106.   }
  107.   rv->mutex = nssCKFWInstance_CreateMutex(fwInstance, arena, pError);
  108.   if( (NSSCKFWMutex *)NULL == rv->mutex ) {
  109.     if( CKR_OK == *pError ) {
  110.       *pError = CKR_GENERAL_ERROR;
  111.     }
  112.     return (nssCKFWHash *)NULL;
  113.   }
  114.   rv->plHashTable = PL_NewHashTable(0, nss_ckfw_identity_hash, 
  115.     PL_CompareValues, PL_CompareValues, &nssArenaHashAllocOps, arena);
  116.   if( (PLHashTable *)NULL == rv->plHashTable ) {
  117.     (void)nssCKFWMutex_Destroy(rv->mutex);
  118.     (void)nss_ZFreeIf(rv);
  119.     *pError = CKR_HOST_MEMORY;
  120.     return (nssCKFWHash *)NULL;
  121.   }
  122.   rv->count = 0;
  123.   return rv;
  124. }
  125. /*
  126.  * nssCKFWHash_Destroy
  127.  *
  128.  */
  129. NSS_IMPLEMENT void
  130. nssCKFWHash_Destroy
  131. (
  132.   nssCKFWHash *hash
  133. )
  134. {
  135.   (void)nssCKFWMutex_Destroy(hash->mutex);
  136.   PL_HashTableDestroy(hash->plHashTable);
  137.   (void)nss_ZFreeIf(hash);
  138. }
  139. /*
  140.  * nssCKFWHash_Add
  141.  *
  142.  */
  143. NSS_IMPLEMENT CK_RV
  144. nssCKFWHash_Add
  145. (
  146.   nssCKFWHash *hash,
  147.   const void *key,
  148.   const void *value
  149. )
  150. {
  151.   CK_RV error = CKR_OK;
  152.   PLHashEntry *he;
  153.   error = nssCKFWMutex_Lock(hash->mutex);
  154.   if( CKR_OK != error ) {
  155.     return error;
  156.   }
  157.   
  158.   he = PL_HashTableAdd(hash->plHashTable, key, (void *)value);
  159.   if( (PLHashEntry *)NULL == he ) {
  160.     error = CKR_HOST_MEMORY;
  161.   } else {
  162.     hash->count++;
  163.   }
  164.   (void)nssCKFWMutex_Unlock(hash->mutex);
  165.   return error;
  166. }
  167. /*
  168.  * nssCKFWHash_Remove
  169.  *
  170.  */
  171. NSS_IMPLEMENT void
  172. nssCKFWHash_Remove
  173. (
  174.   nssCKFWHash *hash,
  175.   const void *it
  176. )
  177. {
  178.   PRBool found;
  179.   if( CKR_OK != nssCKFWMutex_Lock(hash->mutex) ) {
  180.     return;
  181.   }
  182.   found = PL_HashTableRemove(hash->plHashTable, it);
  183.   if( found ) {
  184.     hash->count--;
  185.   }
  186.   (void)nssCKFWMutex_Unlock(hash->mutex);
  187.   return;
  188. }
  189. /*
  190.  * nssCKFWHash_Count
  191.  *
  192.  */
  193. NSS_IMPLEMENT CK_ULONG
  194. nssCKFWHash_Count
  195. (
  196.   nssCKFWHash *hash
  197. )
  198. {
  199.   CK_ULONG count;
  200.   if( CKR_OK != nssCKFWMutex_Lock(hash->mutex) ) {
  201.     return (CK_ULONG)0;
  202.   }
  203.   count = hash->count;
  204.   (void)nssCKFWMutex_Unlock(hash->mutex);
  205.   return count;
  206. }
  207. /*
  208.  * nssCKFWHash_Exists
  209.  *
  210.  */
  211. NSS_IMPLEMENT CK_BBOOL
  212. nssCKFWHash_Exists
  213. (
  214.   nssCKFWHash *hash,
  215.   const void *it
  216. )
  217. {
  218.   void *value;
  219.   if( CKR_OK != nssCKFWMutex_Lock(hash->mutex) ) {
  220.     return CK_FALSE;
  221.   }
  222.   value = PL_HashTableLookup(hash->plHashTable, it);
  223.   (void)nssCKFWMutex_Unlock(hash->mutex);
  224.   if( (void *)NULL == value ) {
  225.     return CK_FALSE;
  226.   } else {
  227.     return CK_TRUE;
  228.   }
  229. }
  230. /*
  231.  * nssCKFWHash_Lookup
  232.  *
  233.  */
  234. NSS_IMPLEMENT void *
  235. nssCKFWHash_Lookup
  236. (
  237.   nssCKFWHash *hash,
  238.   const void *it
  239. )
  240. {
  241.   void *rv;
  242.   if( CKR_OK != nssCKFWMutex_Lock(hash->mutex) ) {
  243.     return (void *)NULL;
  244.   }
  245.   rv = PL_HashTableLookup(hash->plHashTable, it);
  246.   (void)nssCKFWMutex_Unlock(hash->mutex);
  247.   return rv;
  248. }
  249. struct arg_str {
  250.   nssCKFWHashIterator fcn;
  251.   void *closure;
  252. };
  253. static PRIntn
  254. nss_ckfwhash_enumerator
  255. (
  256.   PLHashEntry *he,
  257.   PRIntn index,
  258.   void *arg
  259. )
  260. {
  261.   struct arg_str *as = (struct arg_str *)arg;
  262.   as->fcn(he->key, he->value, as->closure);
  263.   return HT_ENUMERATE_NEXT;
  264. }
  265. /*
  266.  * nssCKFWHash_Iterate
  267.  *
  268.  * NOTE that the iteration function will be called with the hashtable locked.
  269.  */
  270. NSS_IMPLEMENT void
  271. nssCKFWHash_Iterate
  272. (
  273.   nssCKFWHash *hash,
  274.   nssCKFWHashIterator fcn,
  275.   void *closure
  276. )
  277. {
  278.   struct arg_str as;
  279.   as.fcn = fcn;
  280.   as.closure = closure;
  281.   if( CKR_OK != nssCKFWMutex_Lock(hash->mutex) ) {
  282.     return;
  283.   }
  284.   PL_HashTableEnumerateEntries(hash->plHashTable, nss_ckfwhash_enumerator, &as);
  285.   (void)nssCKFWMutex_Unlock(hash->mutex);
  286.   return;
  287. }