Projekt

Allgemein

Profil

Herunterladen (13,4 KB) Statistiken
| Zweig: | Markierung: | Revision:
/***************************************************************************
begin : Wed Sep 12 2012
copyright : (C) 2012 by Martin Preuss
email : martin@libchipcard.de

***************************************************************************
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Lesser General Public *
* License as published by the Free Software Foundation; either *
* version 2.1 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
* MA 02111-1307 USA *
* *
***************************************************************************/



#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#define DISABLE_DEBUGLOG


#include "pointerlist_p.h"
#include <gwenhywfar/debug.h>


#include <stdlib.h>
#include <assert.h>
#include <string.h>



GWEN_POINTERLIST_TABLE *GWEN_PointerListTable_new(void) {
GWEN_POINTERLIST_TABLE *idt;

GWEN_NEW_OBJECT(GWEN_POINTERLIST_TABLE, idt);
idt->refCount=1;

idt->freeEntries=GWEN_POINTERLIST_TABLE_MAXENTRIES;
return idt;
}



void GWEN_PointerListTable_free(GWEN_POINTERLIST_TABLE *idt) {
if (idt) {
assert(idt->refCount);
if (--(idt->refCount)==0) {
GWEN_FREE_OBJECT(idt);
}
}
}



static inline int GWEN_PointerListTable_AddPtr(GWEN_POINTERLIST_TABLE *idt, void *ptr) {
unsigned int i;

for (i=0; i<GWEN_POINTERLIST_TABLE_MAXENTRIES; i++) {
if (idt->entries[i]==0) {
idt->entries[i]=ptr;
idt->freeEntries--;
return 0;
}
} /* for */
return -1;
}



static inline int GWEN_PointerListTable_AppendPtr(GWEN_POINTERLIST_TABLE *idt, void *ptr) {
if (idt->freeEntries) {
unsigned int i;

i=GWEN_POINTERLIST_TABLE_MAXENTRIES-idt->freeEntries;
idt->entries[i]=ptr;
idt->freeEntries--;
return 0;
}
else
return -1;
}



static inline int GWEN_PointerListTable_HasPtr(const GWEN_POINTERLIST_TABLE *idt, void *ptr) {
unsigned int i;

for (i=0; i<GWEN_POINTERLIST_TABLE_MAXENTRIES; i++) {
if (idt->entries[i]==ptr) {
return 1;
}
} /* for */
return 0;
}



static inline int GWEN_PointerListTable_DelPtr(GWEN_POINTERLIST_TABLE *idt, void *ptr) {
unsigned int i;

for (i=0; i<GWEN_POINTERLIST_TABLE_MAXENTRIES; i++) {
if (idt->entries[i]==ptr) {
idt->entries[i]=0;
idt->freeEntries++;
return 0;
}
} /* for */
return -1;
}



static inline int GWEN_PointerListTable_IsEmpty(const GWEN_POINTERLIST_TABLE *idt) {
return GWEN_POINTERLIST_TABLE_MAXENTRIES==idt->freeEntries;
}



static inline int GWEN_PointerListTable_IsFull(const GWEN_POINTERLIST_TABLE *idt) {
return idt->freeEntries==0;
}


#if 0
static inline unsigned int GWEN_PointerListTable_GetCount(const GWEN_POINTERLIST_TABLE *idt) {
return GWEN_POINTERLIST_TABLE_MAXENTRIES-idt->freeEntries;
}



static inline void *GWEN_PointerListTable_GetFirstPtr(const GWEN_POINTERLIST_TABLE *idt, uint64_t *tabIdx) {
unsigned int i;

for (i=0; i<GWEN_POINTERLIST_TABLE_MAXENTRIES; i++) {
if (idt->entries[i]!=0) {
*tabIdx=i;
return idt->entries[i];
}
} /* for */
return NULL;
}



static inline void *GWEN_PointerListTable_GetNextPtr(const GWEN_POINTERLIST_TABLE *idt, uint64_t *tabIdx) {
unsigned int i;

for (i=(*tabIdx)+1; i<GWEN_POINTERLIST_TABLE_MAXENTRIES; i++) {
if (idt->entries[i]!=0) {
*tabIdx=i;
return idt->entries[i];
}
} /* for */
return NULL;
}
#endif





GWEN_POINTERLIST *GWEN_PointerList_new(void) {
GWEN_POINTERLIST *idl;

GWEN_NEW_OBJECT(GWEN_POINTERLIST, idl);
idl->refCount=1;
idl->tableStep=GWEN_POINTERLIST_DEFAULT_STEP;
return idl;
}



void GWEN_PointerList_Attach(GWEN_POINTERLIST *idl) {
assert(idl);
assert(idl->refCount);
idl->refCount++;
}



void GWEN_PointerList_free(GWEN_POINTERLIST *idl) {
if (idl) {
assert(idl->refCount);
if (idl->refCount==1) {
GWEN_PointerList_Clear(idl);
idl->refCount=0;
GWEN_FREE_OBJECT(idl);
}
else
idl->refCount--;
}
}



void GWEN_PointerList_AddTable(GWEN_POINTERLIST *idl, GWEN_POINTERLIST_TABLE *idt) {
GWEN_POINTERLIST_TABLE **tablePtr;
int idx;

assert(idl);

tablePtr=idl->pIdTablePointers;
for (idx=0, tablePtr=idl->pIdTablePointers; idx<idl->idTableCount; idx++, tablePtr++) {
if (*tablePtr==NULL)
break;
} /* while */

if (idx>=idl->idTableCount) {
uint32_t newCount;
GWEN_POINTERLIST_TABLE **newPtr;

/* resize */
newCount=idl->idTableCount+idl->tableStep;
newPtr=(GWEN_POINTERLIST_TABLE **)realloc(idl->pIdTablePointers, sizeof(GWEN_POINTERLIST_TABLE*)*newCount);
assert(newPtr);
/* init new pointers */
memset((void*)(newPtr+idl->idTableCount),
0,
sizeof(GWEN_POINTERLIST_TABLE*)*(newCount-idl->idTableCount));
idl->pIdTablePointers=newPtr;
idl->pIdTablePointers[idl->idTableCount]=idt;
idl->lastTableIdx=idl->idTableCount;
idl->idTableCount=newCount;
}
else {
idl->pIdTablePointers[idx]=idt;
idl->lastTableIdx=idx;
}
}



int GWEN_PointerList_AddPtr(GWEN_POINTERLIST *idl, void *ptr) {
GWEN_POINTERLIST_TABLE *idt=NULL;
GWEN_POINTERLIST_TABLE **tablePtr;
int idx;

assert(idl);

if (idl->pIdTablePointers==NULL) {
/* create an initial pointer table which can take up to tableStep pointers */
idl->pIdTablePointers=(GWEN_POINTERLIST_TABLE **) malloc(sizeof(GWEN_POINTERLIST_TABLE*)*(idl->tableStep));
assert(idl->pIdTablePointers);
memset(idl->pIdTablePointers, 0, sizeof(GWEN_POINTERLIST*)*(idl->tableStep));
idl->idTableCount=idl->tableStep;
}

for (idx=0, tablePtr=idl->pIdTablePointers; idx<idl->idTableCount; idx++, tablePtr++) {
idt=*tablePtr;
if (idt && !GWEN_PointerListTable_IsFull(idt))
break;
} /* while */

if (idx>=idl->idTableCount) {
idt=GWEN_PointerListTable_new();
GWEN_PointerList_AddTable(idl, idt);
}

GWEN_PointerListTable_AddPtr(idt, ptr);
idl->entryCount++;
return 0;
}



int GWEN_PointerList_DelPtr(GWEN_POINTERLIST *idl, void *ptr) {
if (idl->pIdTablePointers) {
GWEN_POINTERLIST_TABLE *idt=NULL;
GWEN_POINTERLIST_TABLE **tablePtr;
int idx;

for (idx=0, tablePtr=idl->pIdTablePointers; idx<idl->idTableCount; idx++, tablePtr++) {
idt=*tablePtr;
if (idt && !GWEN_PointerListTable_DelPtr(idt, ptr)) {
/* found a table which had this id */
GWEN_PointerList_Clean(idl);
idl->entryCount--;
return 0;
}
}
}

return -1;
}



int GWEN_PointerList_HasPtr(const GWEN_POINTERLIST *idl, void *ptr) {
if (idl->pIdTablePointers) {
GWEN_POINTERLIST_TABLE *idt=NULL;
GWEN_POINTERLIST_TABLE **tablePtr;
int idx;

for (idx=0, tablePtr=idl->pIdTablePointers; idx<idl->idTableCount; idx++, tablePtr++) {
idt=*tablePtr;
if (idt && GWEN_PointerListTable_HasPtr(idt, ptr))
return 1;
}
}

return 0;
}



void GWEN_PointerList_Clean(GWEN_POINTERLIST *idl) {
GWEN_POINTERLIST_TABLE *idt=NULL;
GWEN_POINTERLIST_TABLE **tablePtr;
int idx;

for (idx=0, tablePtr=idl->pIdTablePointers; idx<idl->idTableCount; idx++, tablePtr++) {
idt=*tablePtr;
if (idt && GWEN_PointerListTable_IsEmpty(idt)) {
GWEN_PointerListTable_free(idt);
*tablePtr=NULL;
}
}
}



void GWEN_PointerList_Clear(GWEN_POINTERLIST *idl) {
if (idl->pIdTablePointers) {
GWEN_POINTERLIST_TABLE *idt=NULL;
GWEN_POINTERLIST_TABLE **tablePtr;
int idx;

for (idx=0, tablePtr=idl->pIdTablePointers; idx<idl->idTableCount; idx++, tablePtr++) {
idt=*tablePtr;
if (idt) {
GWEN_PointerListTable_free(idt);
*tablePtr=NULL;
}
}
free(idl->pIdTablePointers);
idl->pIdTablePointers=NULL;
}
idl->entryCount=0;
idl->nextIdx=0;
}



GWEN_POINTERLIST *GWEN_PointerList_dup(const GWEN_POINTERLIST *idl) {
GWEN_POINTERLIST *nidl;
int idx;

nidl=GWEN_PointerList_new();
nidl->tableStep=idl->tableStep;

nidl->idTableCount=idl->idTableCount;
nidl->entryCount=idl->entryCount;
if (idl->pIdTablePointers) {
for (idx=0; idx<idl->idTableCount; idx++) {
GWEN_POINTERLIST_TABLE *idt;

idt=idl->pIdTablePointers[idx];
if (idt && !GWEN_PointerListTable_IsEmpty(idt)) {
GWEN_POINTERLIST_TABLE *nidt;

nidt=GWEN_PointerListTable_new();
memmove(nidt->entries, idt->entries, GWEN_POINTERLIST_TABLE_MAXENTRIES*sizeof(void*));
nidt->freeEntries=idt->freeEntries;
GWEN_PointerList_AddTable(nidl, nidt);
}
}
}

return nidl;
}



uint64_t GWEN_PointerList_GetEntryCount(const GWEN_POINTERLIST *idl) {
assert(idl);
assert(idl->refCount);

return idl->entryCount;
}



void *GWEN_PointerList_GetFirstPtr(const GWEN_POINTERLIST *idl, uint64_t *pos) {
GWEN_POINTERLIST_TABLE *idt=NULL;
GWEN_POINTERLIST_TABLE **tablePtr;
int idx;
int idIndex=0;

*pos=0;
for (idx=0, tablePtr=idl->pIdTablePointers; idx<idl->idTableCount; idx++, tablePtr++) {
idt=*tablePtr;
if (idt && !GWEN_PointerListTable_IsEmpty(idt)) {
int i;
void *ptr;

for (i=0; i<GWEN_POINTERLIST_TABLE_MAXENTRIES; i++) {
if (idt->entries[i]!=0) {
ptr=idt->entries[i];
*pos=idIndex+i+1;
return ptr;
}
}
}
idIndex+=GWEN_POINTERLIST_TABLE_MAXENTRIES;
}

return NULL;
}



void *GWEN_PointerList_GetNextPtr(const GWEN_POINTERLIST *idl, uint64_t *pos) {
if (*pos) {
GWEN_POINTERLIST_TABLE *idt;
uint64_t tableNum=*pos / GWEN_POINTERLIST_TABLE_MAXENTRIES;
uint64_t tableIdx=*pos % GWEN_POINTERLIST_TABLE_MAXENTRIES;
GWEN_POINTERLIST_TABLE **tablePtr;
int idIndex=0;
int idx;

if (tableNum>idl->idTableCount) {
DBG_ERROR(GWEN_LOGDOMAIN, "Table number out of range");
*pos=0;
return 0;
}

idIndex=(tableNum*GWEN_POINTERLIST_TABLE_MAXENTRIES);
for (idx=tableNum, tablePtr=idl->pIdTablePointers+tableNum; idx<idl->idTableCount; idx++, tablePtr++) {
idt=*tablePtr;
if (idt && !GWEN_PointerListTable_IsEmpty(idt)) {
int i;
void *ptr;

if (idx==tableNum) {
for (i=tableIdx; i<GWEN_POINTERLIST_TABLE_MAXENTRIES; i++) {
if (idt->entries[i]!=0) {
ptr=idt->entries[i];
*pos=idIndex+i+1;
return ptr;
}
}
}
else {
for (i=0; i<GWEN_POINTERLIST_TABLE_MAXENTRIES; i++) {
if (idt->entries[i]!=0) {
ptr=idt->entries[i];
*pos=idIndex+i+1;
return ptr;
}
}
}
}
idIndex+=GWEN_POINTERLIST_TABLE_MAXENTRIES;
}
*pos=0;
}

return NULL;
}




GWEN_POINTERLIST_ITERATOR *GWEN_PointerList_Iterator_new(GWEN_POINTERLIST *idl) {
GWEN_POINTERLIST_ITERATOR *it;

assert(idl);
GWEN_NEW_OBJECT(GWEN_POINTERLIST_ITERATOR, it);

GWEN_PointerList_Attach(idl);
it->list=idl;

return it;
}



void GWEN_PointerList_Iterator_free(GWEN_POINTERLIST_ITERATOR *it) {
if (it) {
GWEN_PointerList_free(it->list);
GWEN_FREE_OBJECT(it);
}
}



void *GWEN_PointerList_Iterator_GetFirstId(GWEN_POINTERLIST_ITERATOR *it) {
return GWEN_PointerList_GetFirstPtr(it->list, &(it->nextIndex));
}



void *GWEN_PointerList_Iterator_GetNextId(GWEN_POINTERLIST_ITERATOR *it) {
return GWEN_PointerList_GetNextPtr(it->list, &(it->nextIndex));
}



int GWEN_PointerList_AppendPtr(GWEN_POINTERLIST *idl, void *ptr) {
GWEN_POINTERLIST_TABLE *idt=NULL;

assert(idl);

if (idl->pIdTablePointers==NULL) {
/* create an initial pointer table which can take up to tableStep pointers */
idl->pIdTablePointers=(GWEN_POINTERLIST_TABLE **) malloc(sizeof(GWEN_POINTERLIST_TABLE*)*(idl->tableStep));
assert(idl->pIdTablePointers);
memset(idl->pIdTablePointers, 0, sizeof(GWEN_POINTERLIST_TABLE*)*(idl->tableStep));
idl->idTableCount=idl->tableStep;
}

idt=idl->pIdTablePointers[idl->lastTableIdx];
if (idt==NULL || GWEN_PointerListTable_IsFull(idt)) {
idt=GWEN_PointerListTable_new();
GWEN_PointerList_AddTable(idl, idt);
}

GWEN_PointerListTable_AppendPtr(idt, ptr);
idl->entryCount++;
return 0;
}



void *GWEN_PointerList_GetPtrAt(const GWEN_POINTERLIST *idl, uint64_t idx) {
GWEN_POINTERLIST_TABLE *idt;
uint64_t tableNum=idx / GWEN_POINTERLIST_TABLE_MAXENTRIES;
uint64_t tableIdx=idx % GWEN_POINTERLIST_TABLE_MAXENTRIES;

assert(idl);
if (tableNum>idl->idTableCount) {
DBG_INFO(GWEN_LOGDOMAIN, "Table index out of range");
return 0;
}

idt=idl->pIdTablePointers[tableNum];
if (idt==NULL) {
DBG_INFO(GWEN_LOGDOMAIN, "Table index points to an empty table");
return 0;
}

return idt->entries[tableIdx];
}











(82-82/99)