slist.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. #include "slist.h"
  34. SSMSortedList *
  35. SSMSortedList_New(SSMSortedListFn * functions) 
  36. {
  37.   SSMSortedList * list = NULL;
  38.   
  39.   if (!functions) 
  40.     goto loser;
  41.   
  42.   list = PR_NEWZAP(SSMSortedList);
  43.   if (list == NULL)
  44.     goto loser;
  45.   
  46.   list->lock = PR_NewMonitor();
  47.   if (list->lock == NULL)
  48.     goto loser;
  49.   
  50.   list->func.keyCompare = functions->keyCompare;
  51.   list->func.freeListItemData = functions->freeListItemData;
  52.   list->func.freeListItemKey = functions->freeListItemKey;
  53.   
  54.   PR_INIT_CLIST(&list->list);
  55.   list->nItems = 0;
  56.   return list;
  57. loser:
  58.   if (list) {
  59.     if (list->lock)
  60.       PR_DestroyMonitor(list->lock);
  61.     PR_Free(list);
  62.   }
  63.   return NULL;
  64. }
  65. SSMStatus 
  66. SSMSortedList_Destroy(SSMSortedList *victim)
  67. {
  68.   PRCList * link, *next;
  69.   
  70.   if (!victim)
  71.     goto done;
  72.   
  73.   PR_EnterMonitor(victim->lock);
  74.   /* free elements */
  75.   for(link = PR_LIST_HEAD(&victim->list); link != &victim->list;){
  76.     next = PR_NEXT_LINK(link);
  77.     slist_remove_item(victim, (SSMSortedListItem *)link, PR_TRUE);
  78.     link = next;
  79.   }
  80.   PR_ExitMonitor(victim->lock);
  81.   PR_ASSERT(victim->nItems == 0);
  82.   PR_DestroyMonitor(victim->lock);  
  83.   PR_Free(victim);
  84. done:
  85.   return SSM_SUCCESS;
  86. }
  87. SSMSortedListItem * slist_remove_item(SSMSortedList * list, 
  88.       SSMSortedListItem * item, 
  89.       PRBool doFree) 
  90. {
  91.   PR_REMOVE_LINK(&item->link);
  92.   list->nItems--;
  93.   if (doFree) {
  94.     list->func.freeListItemData(item->data);
  95.     list->func.freeListItemKey(item->key);
  96.     PR_Free(item);
  97.     return NULL;
  98.   }
  99.   else return item;
  100. }
  101. SSMStatus
  102. SSMSortedList_Insert(SSMSortedList * slist, void * key, void * data)
  103. {
  104.   SSMSortedListItem * item, * nextItem;
  105.   if (!slist)  
  106.     goto loser;
  107.   
  108.   item = slist_allocate_item(key, data);
  109.   if (!item) 
  110.     goto loser;
  111.   PR_EnterMonitor(slist->lock);
  112.   nextItem = slist_find_next(slist, key);
  113.   PR_INSERT_BEFORE(&item->link, &nextItem->link);
  114.   slist->nItems++;
  115.   PR_ExitMonitor(slist->lock);
  116.   return SSM_SUCCESS;
  117. loser:
  118.   return SSM_FAILURE;
  119. }
  120. SSMSortedListItem * slist_allocate_item(void * key, void * data)
  121. {
  122.   SSMSortedListItem * item;
  123.   item = PR_NEWZAP(SSMSortedListItem);
  124.   if (item) 
  125.     {
  126.       item->data = data;
  127.       item->key = key;
  128.     }
  129.   return item;
  130. }
  131.   
  132. SSMStatus 
  133. SSMSortedList_Find(SSMSortedList * slist, void * key, void ** data)
  134. {
  135.   SSMStatus rv = SSM_FAILURE;
  136.   SSMSortedListItem * item; 
  137.   if (!slist || !data)
  138.     goto loser;
  139.   *data = NULL;
  140.   PR_EnterMonitor(slist->lock);
  141.   item = slist_find_item(slist, key);
  142.   if (item) {
  143.     *data = item->data;
  144.     rv = SSM_SUCCESS;
  145.   }
  146.   PR_ExitMonitor(slist->lock);
  147. loser:
  148.   return rv;
  149. }
  150. SSMStatus
  151. SSMSortedList_Remove(SSMSortedList * slist, void * key, void ** data)
  152. {
  153.   SSMSortedListItem * item;
  154.   SSMStatus rv = SSM_FAILURE;
  155.   if (!slist) 
  156.     goto loser;
  157.   PR_EnterMonitor(slist->lock);
  158.   item = slist_find_item(slist, key);
  159.   if (item) {
  160.     rv = SSM_SUCCESS;
  161.     if (data)
  162.       *data = item->data;
  163.     slist_remove_item(slist, item, PR_FALSE); 
  164.     slist->func.freeListItemKey(item->key);
  165.     PR_Free(item);
  166.   }
  167.   PR_ExitMonitor(slist->lock);
  168. loser:
  169.   return rv;
  170. }
  171. SSMStatus 
  172. SSMSortedList_FindNext(SSMSortedList * slist, void * key, void ** data)
  173. {
  174.   SSMSortedListItem * item;
  175.   
  176.   if (!slist || !data) 
  177.     return SSM_FAILURE;
  178.   
  179.   PR_EnterMonitor(slist->lock);
  180.   item = slist_find_next(slist, key);
  181.   *data = item->data;
  182.   PR_ExitMonitor(slist->lock);
  183.   return SSM_SUCCESS;
  184. }
  185. SSMSortedListItem *
  186. slist_find_next(SSMSortedList * slist, void * key)
  187. {
  188.   PRCList * link;
  189.   SSMSortedListItem * item; 
  190.   for(link = PR_LIST_HEAD(&slist->list); link != &slist->list;
  191. link = PR_NEXT_LINK(link))
  192.     if (slist->func.keyCompare(((SSMSortedListItem *)link)->key, key) > 0) {
  193.       /* insert here */ 
  194.       item = (SSMSortedListItem *)link; 
  195.       goto done;
  196.     }
  197.   item = (SSMSortedListItem *)&slist->list;
  198. done:
  199.   return item;
  200. }
  201. PRBool
  202. SSMSortedList_Lookup(SSMSortedList * slist, void * key)
  203. {
  204.   SSMSortedListItem * item;
  205.   if (!slist) 
  206.     goto loser;
  207.   PR_EnterMonitor(slist->lock);
  208.   item = slist_find_item(slist, key);
  209.   PR_ExitMonitor(slist->lock);
  210.   if (item)
  211.     return PR_TRUE;
  212. loser:
  213.   return PR_FALSE;
  214. }
  215. SSMSortedListItem *
  216. slist_find_item(SSMSortedList * slist, void * key)
  217. {
  218.   PRCList * link;
  219.   
  220.   for(link = PR_LIST_HEAD(&slist->list); link != &slist->list;
  221.       link = PR_NEXT_LINK(link))
  222.     if (slist->func.keyCompare(((SSMSortedListItem *)link)->key, key) == 0) /* found it */ 
  223.       return ((SSMSortedListItem *)link);
  224.   return NULL;
  225. }
  226. PRIntn
  227. SSMSortedList_Enumerate(SSMSortedList * slist, SSMSortedListEnumerator_fn func,
  228. void * arg)
  229. {
  230.   PRCList * link;
  231.   PRIntn numentries = 0;
  232.   SSMStatus rv;
  233.   if (!slist || !func) 
  234.     goto loser;
  235.   PR_EnterMonitor(slist->lock);
  236.   for(link = PR_LIST_HEAD(&slist->list); link != &slist->list;
  237.       link = PR_NEXT_LINK(link)) {
  238.     rv = func(numentries, arg, ((SSMSortedListItem *)link)->key, 
  239.       ((SSMSortedListItem *)link)->data); 
  240.     if (rv == SSM_SUCCESS) 
  241.       numentries ++;
  242.   }
  243.   PR_ExitMonitor(slist->lock);
  244.   
  245. loser:
  246.   return numentries;
  247. }
  248.