Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Typedefs | Functions
list.c File Reference
#include "base.h"

Go to the source code of this file.

Classes

struct  nssListElementStr
struct  nssListStr
struct  nssListIteratorStr

Defines

#define NSSLIST_LOCK_IF(list)   if ((list)->lock) PZ_Lock((list)->lock)
#define NSSLIST_UNLOCK_IF(list)   if ((list)->lock) PZ_Unlock((list)->lock)

Typedefs

typedef struct nssListElementStr

Functions

static PRBool pointer_compare (void *a, void *b)
static nssListElement * nsslist_get_matching_element (nssList *list, void *data)
NSS_IMPLEMENT nssList * nssList_Create (NSSArena *arenaOpt, PRBool threadSafe)
NSS_IMPLEMENT PRStatus nssList_Destroy (nssList *list)
NSS_IMPLEMENT void nssList_SetCompareFunction (nssList *list, nssListCompareFunc compareFunc)
NSS_IMPLEMENT void nssList_SetSortFunction (nssList *list, nssListSortFunc sortFunc)
NSS_IMPLEMENT nssListCompareFunc nssList_GetCompareFunction (nssList *list)
NSS_IMPLEMENT void nssList_Clear (nssList *list, nssListElementDestructorFunc destructor)
static PRStatus nsslist_add_element (nssList *list, void *data)
NSS_IMPLEMENT PRStatus nssList_Add (nssList *list, void *data)
NSS_IMPLEMENT PRStatus nssList_AddUnique (nssList *list, void *data)
NSS_IMPLEMENT PRStatus nssList_Remove (nssList *list, void *data)
NSS_IMPLEMENT voidnssList_Get (nssList *list, void *data)
NSS_IMPLEMENT PRUint32 nssList_Count (nssList *list)
NSS_IMPLEMENT PRStatus nssList_GetArray (nssList *list, void **rvArray, PRUint32 maxElements)
NSS_IMPLEMENT nssList * nssList_Clone (nssList *list)
NSS_IMPLEMENT nssListIterator * nssList_CreateIterator (nssList *list)
NSS_IMPLEMENT void nssListIterator_Destroy (nssListIterator *iter)
NSS_IMPLEMENT voidnssListIterator_Start (nssListIterator *iter)
NSS_IMPLEMENT voidnssListIterator_Next (nssListIterator *iter)
NSS_IMPLEMENT PRStatus nssListIterator_Finish (nssListIterator *iter)

Class Documentation

struct nssListElementStr

Definition at line 51 of file list.c.

Class Members
void * data
PRCList link
struct nssListStr

Definition at line 58 of file list.c.

Class Members
NSSArena * arena
nssListCompareFunc compareFunc
PRUint32 count
nssListElement * head
PRBool i_alloced_arena
PZLock * lock
nssListSortFunc sortFunc
struct nssListIteratorStr

Definition at line 68 of file list.c.

Class Members
nssListElement * current
nssList * list
PZLock * lock

Define Documentation

Definition at line 74 of file list.c.

Definition at line 77 of file list.c.


Typedef Documentation

typedef struct nssListElementStr

Definition at line 56 of file list.c.


Function Documentation

NSS_IMPLEMENT PRStatus nssList_Add ( nssList *  list,
void data 
)

Definition at line 254 of file list.c.

static PRStatus nsslist_add_element ( nssList *  list,
void data 
) [static]

Definition at line 212 of file list.c.

{
    nssListElement *node = nss_ZNEW(list->arena, nssListElement);
    if (!node) {
       return PR_FAILURE;
    }
    PR_INIT_CLIST(&node->link);
    node->data = data;
    if (list->head) {
       if (list->sortFunc) {
           PRCList *link;
           nssListElement *currNode;
           currNode = list->head;
           /* insert in ordered list */
           while (currNode) {
              link = &currNode->link;
              if (list->sortFunc(data, currNode->data) <= 0) {
                  /* new element goes before current node */
                  PR_INSERT_BEFORE(&node->link, link);
                  /* reset head if this is first */
                  if (currNode == list->head) list->head = node;
                  break;
              }
              if (link == PR_LIST_TAIL(&list->head->link)) {
                  /* reached end of list, append */
                  PR_INSERT_AFTER(&node->link, link);
                  break;
              }
              currNode = (nssListElement *)PR_NEXT_LINK(&currNode->link);
           }
       } else {
           /* not sorting */
           PR_APPEND_LINK(&node->link, &list->head->link);
       }
    } else {
       list->head = node;
    }
    ++list->count;
    return PR_SUCCESS;
}

Here is the caller graph for this function:

NSS_IMPLEMENT PRStatus nssList_AddUnique ( nssList *  list,
void data 
)

Definition at line 264 of file list.c.

{
    PRStatus nssrv;
    nssListElement *node;
    NSSLIST_LOCK_IF(list);
    node = nsslist_get_matching_element(list, data);
    if (node) {
       /* already in, finish */
       NSSLIST_UNLOCK_IF(list);
       return PR_SUCCESS;
    }
    nssrv = nsslist_add_element(list, data);
    NSSLIST_UNLOCK_IF(list);
    return nssrv;
}
NSS_IMPLEMENT void nssList_Clear ( nssList *  list,
nssListElementDestructorFunc  destructor 
)

Definition at line 192 of file list.c.

{
    PRCList *link;
    nssListElement *node, *tmp;
    NSSLIST_LOCK_IF(list);
    node = list->head;
    list->head = NULL;
    while (node && list->count > 0) {
       if (destructor) (*destructor)(node->data);
       link = &node->link;
       tmp = (nssListElement *)PR_NEXT_LINK(link);
       PR_REMOVE_LINK(link);
       nss_ZFreeIf(node);
       node = tmp;
       --list->count;
    }
    NSSLIST_UNLOCK_IF(list);
}
NSS_IMPLEMENT nssList* nssList_Clone ( nssList *  list)

Definition at line 340 of file list.c.

{
    nssList *rvList;
    nssListElement *node;
    rvList = nssList_Create(NULL, (list->lock != NULL));
    if (!rvList) {
       return NULL;
    }
    NSSLIST_LOCK_IF(list);
    if (list->count > 0) {
       node = list->head;
       while (PR_TRUE) {
           nssList_Add(rvList, node->data);
           node = (nssListElement *)PR_NEXT_LINK(&node->link);
           if (node == list->head) {
              break;
           }
       }
    }
    NSSLIST_UNLOCK_IF(list);
    return rvList;
}
NSS_IMPLEMENT PRUint32 nssList_Count ( nssList *  list)

Definition at line 311 of file list.c.

{
    return list->count;
}
NSS_IMPLEMENT nssList* nssList_Create ( NSSArena *  arenaOpt,
PRBool  threadSafe 
)

Definition at line 113 of file list.c.

{
    NSSArena *arena;
    nssList *list;
    PRBool i_alloced;
    if (arenaOpt) {
       arena = arenaOpt;
       i_alloced = PR_FALSE;
    } else {
       arena = nssArena_Create();
       i_alloced = PR_TRUE;
    }
    if (!arena) {
       return (nssList *)NULL;
    }
    list = nss_ZNEW(arena, nssList);
    if (!list) {
       if (!arenaOpt) {
           NSSArena_Destroy(arena);
       }
       return (nssList *)NULL;
    }
    if (threadSafe) {
       list->lock = PZ_NewLock(nssILockOther);
       if (!list->lock) {
           if (arenaOpt) {
              nss_ZFreeIf(list);
           } else {
              NSSArena_Destroy(arena);
           }
           return (nssList *)NULL;
       }
    }
    list->arena = arena;
    list->i_alloced_arena = i_alloced;
    list->compareFunc = pointer_compare;
    return list;
}
NSS_IMPLEMENT nssListIterator* nssList_CreateIterator ( nssList *  list)

Definition at line 364 of file list.c.

{
    nssListIterator *rvIterator;
    rvIterator = nss_ZNEW(NULL, nssListIterator);
    if (!rvIterator) {
       return NULL;
    }
    rvIterator->list = nssList_Clone(list);
    if (!rvIterator->list) {
       nss_ZFreeIf(rvIterator);
       return NULL;
    }
    rvIterator->current = rvIterator->list->head;
    if (list->lock) {
       rvIterator->lock = PZ_NewLock(nssILockOther);
       if (!rvIterator->lock) {
           nssList_Destroy(rvIterator->list);
           nss_ZFreeIf(rvIterator);
       }
    }
    return rvIterator;
}
NSS_IMPLEMENT PRStatus nssList_Destroy ( nssList *  list)

Definition at line 156 of file list.c.

{
    if (!list->i_alloced_arena) {
       nssList_Clear(list, NULL);
    }
    if (list->lock) {
       (void)PZ_DestroyLock(list->lock);
    }
    if (list->i_alloced_arena) {
       NSSArena_Destroy(list->arena);
       list = NULL;
    }
    nss_ZFreeIf(list);
    return PR_SUCCESS;
}
NSS_IMPLEMENT void* nssList_Get ( nssList *  list,
void data 
)

Definition at line 301 of file list.c.

{
    nssListElement *node;
    NSSLIST_LOCK_IF(list);
    node = nsslist_get_matching_element(list, data);
    NSSLIST_UNLOCK_IF(list);
    return (node) ? node->data : NULL;
}
static nssListElement* nsslist_get_matching_element ( nssList *  list,
void data 
) [static]

Definition at line 87 of file list.c.

{
    PRCList *link;
    nssListElement *node;
    node = list->head;
    if (!node) {
       return NULL;
    }
    link = &node->link;
    while (node) {
       /* using a callback slows things down when it's just compare ... */
       if (list->compareFunc(node->data, data)) {
           break;
       }
       link = &node->link;
       if (link == PR_LIST_TAIL(&list->head->link)) {
           node = NULL;
           break;
       }
       node = (nssListElement *)PR_NEXT_LINK(&node->link);
    }
    return node;
}

Here is the caller graph for this function:

NSS_IMPLEMENT PRStatus nssList_GetArray ( nssList *  list,
void **  rvArray,
PRUint32  maxElements 
)

Definition at line 317 of file list.c.

{
    nssListElement *node;
    PRUint32 i = 0;
    PR_ASSERT(maxElements > 0);
    node = list->head;
    if (!node) {
       return PR_SUCCESS;
    }
    NSSLIST_LOCK_IF(list);
    while (node) {
       rvArray[i++] = node->data;
       if (i == maxElements) break;
       node = (nssListElement *)PR_NEXT_LINK(&node->link);
       if (node == list->head) {
           break;
       }
    }
    NSSLIST_UNLOCK_IF(list);
    return PR_SUCCESS;
}

Definition at line 186 of file list.c.

{
    return list->compareFunc;
}
NSS_IMPLEMENT PRStatus nssList_Remove ( nssList *  list,
void data 
)

Definition at line 281 of file list.c.

{
    nssListElement *node;
    NSSLIST_LOCK_IF(list);
    node = nsslist_get_matching_element(list, data);
    if (node) {
       if (node == list->head) {
           list->head = (nssListElement *)PR_NEXT_LINK(&node->link);
       }
       PR_REMOVE_LINK(&node->link);
       nss_ZFreeIf(node);
       if (--list->count == 0) {
           list->head = NULL;
       }
    }
    NSSLIST_UNLOCK_IF(list);
    return PR_SUCCESS;
}
NSS_IMPLEMENT void nssList_SetCompareFunction ( nssList *  list,
nssListCompareFunc  compareFunc 
)

Definition at line 173 of file list.c.

{
    list->compareFunc = compareFunc;
}
NSS_IMPLEMENT void nssList_SetSortFunction ( nssList *  list,
nssListSortFunc  sortFunc 
)

Definition at line 179 of file list.c.

{
    /* XXX if list already has elements, sort them */
    list->sortFunc = sortFunc;
}
NSS_IMPLEMENT void nssListIterator_Destroy ( nssListIterator *  iter)

Definition at line 388 of file list.c.

{
    if (iter->lock) {
       (void)PZ_DestroyLock(iter->lock);
    }
    nssList_Destroy(iter->list);
    nss_ZFreeIf(iter);
}
NSS_IMPLEMENT PRStatus nssListIterator_Finish ( nssListIterator *  iter)

Definition at line 431 of file list.c.

{
    iter->current = iter->list->head;
    return (iter->lock) ? PZ_Unlock(iter->lock) : PR_SUCCESS;
}
NSS_IMPLEMENT void* nssListIterator_Next ( nssListIterator *  iter)

Definition at line 409 of file list.c.

{
    nssListElement *node;
    PRCList *link;
    if (iter->list->count == 1 || iter->current == NULL) {
       /* Reached the end of the list.  Don't change the state, force to
        * user to call nssList_Finish to clean up.
        */
       return NULL;
    }
    node = (nssListElement *)PR_NEXT_LINK(&iter->current->link);
    link = &node->link;
    if (link == PR_LIST_TAIL(&iter->list->head->link)) {
       /* Signal the end of the list. */
       iter->current = NULL;
       return node->data;
    }
    iter->current = node;
    return node->data;
}
NSS_IMPLEMENT void* nssListIterator_Start ( nssListIterator *  iter)

Definition at line 398 of file list.c.

{
    NSSLIST_LOCK_IF(iter);
    if (iter->list->count == 0) {
       return NULL;
    }
    iter->current = iter->list->head;
    return iter->current->data;
}
static PRBool pointer_compare ( void a,
void b 
) [static]

Definition at line 81 of file list.c.

{
    return (PRBool)(a == b);
}

Here is the caller graph for this function: