📄 slist.c
字号:
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- *//* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Netscape security libraries. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1994-2000 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */#include "slist.h"SSMSortedList *SSMSortedList_New(SSMSortedListFn * functions) { SSMSortedList * list = NULL; if (!functions) goto loser; list = PR_NEWZAP(SSMSortedList); if (list == NULL) goto loser; list->lock = PR_NewMonitor(); if (list->lock == NULL) goto loser; list->func.keyCompare = functions->keyCompare; list->func.freeListItemData = functions->freeListItemData; list->func.freeListItemKey = functions->freeListItemKey; PR_INIT_CLIST(&list->list); list->nItems = 0; return list;loser: if (list) { if (list->lock) PR_DestroyMonitor(list->lock); PR_Free(list); } return NULL;}SSMStatus SSMSortedList_Destroy(SSMSortedList *victim){ PRCList * link, *next; if (!victim) goto done; PR_EnterMonitor(victim->lock); /* free elements */ for(link = PR_LIST_HEAD(&victim->list); link != &victim->list;){ next = PR_NEXT_LINK(link); slist_remove_item(victim, (SSMSortedListItem *)link, PR_TRUE); link = next; } PR_ExitMonitor(victim->lock); PR_ASSERT(victim->nItems == 0); PR_DestroyMonitor(victim->lock); PR_Free(victim);done: return SSM_SUCCESS;}SSMSortedListItem * slist_remove_item(SSMSortedList * list, SSMSortedListItem * item, PRBool doFree) { PR_REMOVE_LINK(&item->link); list->nItems--; if (doFree) { list->func.freeListItemData(item->data); list->func.freeListItemKey(item->key); PR_Free(item); return NULL; } else return item;}SSMStatusSSMSortedList_Insert(SSMSortedList * slist, void * key, void * data){ SSMSortedListItem * item, * nextItem; if (!slist) goto loser; item = slist_allocate_item(key, data); if (!item) goto loser; PR_EnterMonitor(slist->lock); nextItem = slist_find_next(slist, key); PR_INSERT_BEFORE(&item->link, &nextItem->link); slist->nItems++; PR_ExitMonitor(slist->lock); return SSM_SUCCESS;loser: return SSM_FAILURE;}SSMSortedListItem * slist_allocate_item(void * key, void * data){ SSMSortedListItem * item; item = PR_NEWZAP(SSMSortedListItem); if (item) { item->data = data; item->key = key; } return item;} SSMStatus SSMSortedList_Find(SSMSortedList * slist, void * key, void ** data){ SSMStatus rv = SSM_FAILURE; SSMSortedListItem * item; if (!slist || !data) goto loser; *data = NULL; PR_EnterMonitor(slist->lock); item = slist_find_item(slist, key); if (item) { *data = item->data; rv = SSM_SUCCESS; } PR_ExitMonitor(slist->lock);loser: return rv;}SSMStatusSSMSortedList_Remove(SSMSortedList * slist, void * key, void ** data){ SSMSortedListItem * item; SSMStatus rv = SSM_FAILURE; if (!slist) goto loser; PR_EnterMonitor(slist->lock); item = slist_find_item(slist, key); if (item) { rv = SSM_SUCCESS; if (data) *data = item->data; slist_remove_item(slist, item, PR_FALSE); slist->func.freeListItemKey(item->key); PR_Free(item); } PR_ExitMonitor(slist->lock);loser: return rv;}SSMStatus SSMSortedList_FindNext(SSMSortedList * slist, void * key, void ** data){ SSMSortedListItem * item; if (!slist || !data) return SSM_FAILURE; PR_EnterMonitor(slist->lock); item = slist_find_next(slist, key); *data = item->data; PR_ExitMonitor(slist->lock); return SSM_SUCCESS;}SSMSortedListItem *slist_find_next(SSMSortedList * slist, void * key){ PRCList * link; SSMSortedListItem * item; for(link = PR_LIST_HEAD(&slist->list); link != &slist->list; link = PR_NEXT_LINK(link)) if (slist->func.keyCompare(((SSMSortedListItem *)link)->key, key) > 0) { /* insert here */ item = (SSMSortedListItem *)link; goto done; } item = (SSMSortedListItem *)&slist->list;done: return item;}PRBoolSSMSortedList_Lookup(SSMSortedList * slist, void * key){ SSMSortedListItem * item; if (!slist) goto loser; PR_EnterMonitor(slist->lock); item = slist_find_item(slist, key); PR_ExitMonitor(slist->lock); if (item) return PR_TRUE;loser: return PR_FALSE;}SSMSortedListItem *slist_find_item(SSMSortedList * slist, void * key){ PRCList * link; for(link = PR_LIST_HEAD(&slist->list); link != &slist->list; link = PR_NEXT_LINK(link)) if (slist->func.keyCompare(((SSMSortedListItem *)link)->key, key) == 0) /* found it */ return ((SSMSortedListItem *)link); return NULL;}PRIntnSSMSortedList_Enumerate(SSMSortedList * slist, SSMSortedListEnumerator_fn func, void * arg){ PRCList * link; PRIntn numentries = 0; SSMStatus rv; if (!slist || !func) goto loser; PR_EnterMonitor(slist->lock); for(link = PR_LIST_HEAD(&slist->list); link != &slist->list; link = PR_NEXT_LINK(link)) { rv = func(numentries, arg, ((SSMSortedListItem *)link)->key, ((SSMSortedListItem *)link)->data); if (rv == SSM_SUCCESS) numentries ++; } PR_ExitMonitor(slist->lock); loser: return numentries;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -