?? rvobjlist.c
字號:
/***********************************************************************
Filename : rvobjlist.c
Description: utility for building lists of objects (structures)
************************************************************************
Copyright (c) 2001,2002 RADVISION Inc. and RADVISION Ltd.
************************************************************************
NOTICE:
This document contains information that is confidential and proprietary
to RADVISION Inc. and RADVISION Ltd.. No part of this document may be
reproduced in any form whatsoever without written prior approval by
RADVISION Inc. or RADVISION Ltd..
RADVISION Inc. and RADVISION Ltd. reserve the right to revise this
publication and make changes without obligation to notify any person of
such revisions or changes.
***********************************************************************/
#include "rvobjlist.h"
/* Basic list utility for structures. User is responsible for locking */
/* if list is to be shared. */
/* The template object is never touched and is simply used to find the */
/* location of the RvObjListElement structure (elementptr) within it. */
/* It is possible to put the Element structure outside of the the object */
/* and have a negative offset between the two. */
RvObjList *RvObjListConstruct(RvObjList *objlist, void *itemtemp, RvObjListElement *elementptr)
{
#if defined(RV_NULLCHECK)
if((objlist == NULL) || (itemtemp == NULL) || (elementptr == NULL))
return NULL;
#endif
/* List is circular with achor having NULL obj */
objlist->anchor.prev = &objlist->anchor;
objlist->anchor.next = &objlist->anchor;
objlist->anchor.obj = NULL;
objlist->count = 0;
objlist->offset = (RvInt8 *)elementptr - (RvInt8 *)itemtemp;
return objlist;
}
RvSize_t RvObjListSize(RvObjList *objlist)
{
#if defined(RV_NULLCHECK)
if(objlist == NULL)
return 0;
#endif
return(objlist->count);
}
/* If curitem is NULL than item is put at start of list */
void *RvObjListInsertAfter(RvObjList *objlist, void *curitem, void *newitem)
{
RvObjListElement *curelem, *newelem;
#if defined(RV_NULLCHECK)
if((objlist == NULL) || (newitem == NULL))
return NULL;
#endif
objlist->count += 1;
#if defined(RV_RANGECHECK)
if(objlist->count == 0) {
/* We wrapped, which means we can't add anything */
objlist->count -= 1;
return NULL;
}
#endif
if(curitem != NULL) {
curelem = (RvObjListElement *)((RvInt8 *)curitem + objlist->offset);
} else curelem = &objlist->anchor; /* put at start of list */
newelem = (RvObjListElement *)((RvInt8 *)newitem + objlist->offset);
newelem->obj = newitem;
newelem->prev = curelem;
newelem->next = curelem->next;
curelem->next = newelem;
newelem->next->prev = newelem;
return newitem;
}
/* If curitem is NULL than item is put at end of list */
void *RvObjListInsertBefore(RvObjList *objlist, void *curitem, void *newitem)
{
RvObjListElement *curelem, *newelem;
#if defined(RV_NULLCHECK)
if((objlist == NULL) || (newitem == NULL))
return NULL;
#endif
objlist->count += RvUintConst(1);
#if defined(RV_RANGECHECK)
if(objlist->count == 0) {
/* We wrapped, which means we can't add anything */
objlist->count -= 1;
return NULL;
}
#endif
if(curitem != NULL) {
curelem = (RvObjListElement *)((RvInt8 *)curitem + objlist->offset);
} else curelem = &objlist->anchor; /* put at end of list */
newelem = (RvObjListElement *)((RvInt8 *)newitem + objlist->offset);
newelem->obj = newitem;
newelem->next = curelem;
newelem->prev = curelem->prev;
curelem->prev = newelem;
newelem->prev->next = newelem;
return newitem;
}
/* Gets next item (if curitem is NULL than get first item) */
void *RvObjListGetNext(RvObjList *objlist, void *curitem, RvBool removeitem)
{
RvObjListElement *elem;
void *item;
#if defined(RV_NULLCHECK)
if(objlist == NULL)
return NULL;
#endif
if(curitem != NULL) {
elem = (RvObjListElement *)((RvInt8 *)curitem + objlist->offset);
elem = elem->next;
} else elem = objlist->anchor.next; /* Get first item */
item = elem->obj;
if((removeitem == RV_OBJLIST_REMOVE) && (item != NULL)) {
/* Only remove the item if requested and its not the anchor */
elem->prev->next = elem->next;
elem->next->prev = elem->prev;
objlist->count -= 1;
}
return item;
}
/* Gets previous item (if curitem is NULL than get last item) */
void *RvObjListGetPrevious(RvObjList *objlist, void *curitem, RvBool removeitem)
{
RvObjListElement *elem;
void *item;
#if defined(RV_NULLCHECK)
if(objlist == NULL)
return NULL;
#endif
if(curitem != NULL) {
elem = (RvObjListElement *)((RvInt8 *)curitem + objlist->offset);
elem = elem->prev;
} else elem = objlist->anchor.prev; /* Get last item */
item = elem->obj;
if((removeitem == RV_OBJLIST_REMOVE) && (item != NULL)) {
/* Only remove the item if requested and its not the anchor */
elem->prev->next = elem->next;
elem->next->prev = elem->prev;
objlist->count -= 1;
}
return item;
}
void *RvObjListRemoveItem(RvObjList *objlist, void *item)
{
RvObjListElement *elem;
#if defined(RV_NULLCHECK)
if((objlist == NULL) || (item == NULL))
return NULL;
#endif
elem = (RvObjListElement *)((RvInt8 *)item + objlist->offset);
elem->prev->next = elem->next;
elem->next->prev = elem->prev;
objlist->count -= 1;
return item;
}
#if defined(RV_TEST_CODE)
#include "rvstdio.h"
typedef struct {
RvInt32 dummy1;
RvInt64 dummy2;
RvObjListElement listElem;
RvChar dummy3[80];
RvInt index;
} RvObjListTestStruct;
#define RV_OBJLIST_NUMTESTOBJ 1000
static RvObjListTestStruct RvObjTestData[RV_OBJLIST_NUMTESTOBJ];
void RvObjListTest(void)
{
RvInt i;
RvObjList list, *cresult;
void *result;
RvPrintf("Starting test of rvobjlist.\n");
for(i = 0; i < RV_OBJLIST_NUMTESTOBJ; i++)
RvObjTestData[i].index = i;
RvPrintf("RvObjListConstruct: ");
cresult = RvObjListConstruct(&list, &RvObjTestData[0], &RvObjTestData[0].listElem);
if(cresult != NULL) {
RvPrintf("OK\n");
} else RvPrintf("ERROR\n");
RvPrintf("Adding %d items to list (alternating begin/end): ", RV_OBJLIST_NUMTESTOBJ);
result = NULL;
for(i = 0; i < RV_OBJLIST_NUMTESTOBJ; i++) {
if(i % 2) {
result = RvObjListInsertAfter(&list, NULL, &RvObjTestData[i]); /* Front */
} else result = RvObjListInsertBefore(&list, NULL, &RvObjTestData[i]); /* End */
if(result == NULL) {
RvPrintf("ERROR\n");
break;
}
}
if(result != NULL)
RvPrintf("OK\n");
RvPrintf("RvObjListSize = %u\n", RvObjListSize(&list));
RvPrintf("Removing %d items from end of list: ", (RV_OBJLIST_NUMTESTOBJ / 2));
for(i = 0; i < (RV_OBJLIST_NUMTESTOBJ / 2); i++) {
result = RvObjListGetPrevious(&list, NULL, RV_OBJLIST_REMOVE);
if(result == NULL) {
RvPrintf("ERROR\n");
break;
}
}
if(result != NULL)
RvPrintf("OK\n");
RvPrintf("Removing %d items from beginning of list: ", (RV_OBJLIST_NUMTESTOBJ / 2));
for(i = (RV_OBJLIST_NUMTESTOBJ / 2); i < RV_OBJLIST_NUMTESTOBJ; i++) {
result = RvObjListGetNext(&list, NULL, RV_OBJLIST_REMOVE);
if(result == NULL) {
RvPrintf("ERROR\n");
break;
}
}
if(result != NULL)
RvPrintf("OK\n");
RvPrintf("RvObjListSize = %u\n", RvObjListSize(&list));
RvPrintf("Trying to remove one more from beginning of list: ");
result = RvObjListGetNext(&list, NULL, RV_OBJLIST_REMOVE);
if(result == NULL) {
RvPrintf("OK\n");
} else RvPrintf("ERROR\n");
RvPrintf("Trying to remove one more from end of list: ");
result = RvObjListGetPrevious(&list, NULL, RV_OBJLIST_REMOVE);
if(result == NULL) {
RvPrintf("OK\n");
} else RvPrintf("ERROR\n");
RvPrintf("RvObjListSize = %u\n", RvObjListSize(&list));
RvPrintf("Destructing list.\n");
RvObjListDestruct(&list);
}
#endif /* RV_TEST_CODE */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -