gwenhywfar  4.99.25rc9
pointerlist.c
Go to the documentation of this file.
1 /***************************************************************************
2  begin : Wed Sep 12 2012
3  copyright : (C) 2012 by Martin Preuss
4  email : martin@libchipcard.de
5 
6  ***************************************************************************
7  * *
8  * This library is free software; you can redistribute it and/or *
9  * modify it under the terms of the GNU Lesser General Public *
10  * License as published by the Free Software Foundation; either *
11  * version 2.1 of the License, or (at your option) any later version. *
12  * *
13  * This library is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16  * Lesser General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU Lesser General Public *
19  * License along with this library; if not, write to the Free Software *
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
21  * MA 02111-1307 USA *
22  * *
23  ***************************************************************************/
24 
25 
26 
27 #ifdef HAVE_CONFIG_H
28 # include <config.h>
29 #endif
30 
31 #define DISABLE_DEBUGLOG
32 
33 
34 #include "pointerlist_p.h"
35 #include <gwenhywfar/debug.h>
36 
37 
38 #include <stdlib.h>
39 #include <assert.h>
40 #include <string.h>
41 
42 
43 
44 GWEN_POINTERLIST_TABLE *GWEN_PointerListTable_new(void)
45 {
46  GWEN_POINTERLIST_TABLE *idt;
47 
48  GWEN_NEW_OBJECT(GWEN_POINTERLIST_TABLE, idt);
49  idt->refCount=1;
50 
51  idt->freeEntries=GWEN_POINTERLIST_TABLE_MAXENTRIES;
52  return idt;
53 }
54 
55 
56 
57 void GWEN_PointerListTable_free(GWEN_POINTERLIST_TABLE *idt)
58 {
59  if (idt) {
60  assert(idt->refCount);
61  if (--(idt->refCount)==0) {
62  GWEN_FREE_OBJECT(idt);
63  }
64  }
65 }
66 
67 
68 
69 static inline int GWEN_PointerListTable_AddPtr(GWEN_POINTERLIST_TABLE *idt, void *ptr)
70 {
71  unsigned int i;
72 
73  for (i=0; i<GWEN_POINTERLIST_TABLE_MAXENTRIES; i++) {
74  if (idt->entries[i]==0) {
75  idt->entries[i]=ptr;
76  idt->freeEntries--;
77  return 0;
78  }
79  } /* for */
80  return -1;
81 }
82 
83 
84 
85 static inline int GWEN_PointerListTable_AppendPtr(GWEN_POINTERLIST_TABLE *idt, void *ptr)
86 {
87  if (idt->freeEntries) {
88  unsigned int i;
89 
90  i=GWEN_POINTERLIST_TABLE_MAXENTRIES-idt->freeEntries;
91  idt->entries[i]=ptr;
92  idt->freeEntries--;
93  return 0;
94  }
95  else
96  return -1;
97 }
98 
99 
100 
101 static inline int GWEN_PointerListTable_HasPtr(const GWEN_POINTERLIST_TABLE *idt, void *ptr)
102 {
103  unsigned int i;
104 
105  for (i=0; i<GWEN_POINTERLIST_TABLE_MAXENTRIES; i++) {
106  if (idt->entries[i]==ptr) {
107  return 1;
108  }
109  } /* for */
110  return 0;
111 }
112 
113 
114 
115 static inline int GWEN_PointerListTable_DelPtr(GWEN_POINTERLIST_TABLE *idt, void *ptr)
116 {
117  unsigned int i;
118 
119  for (i=0; i<GWEN_POINTERLIST_TABLE_MAXENTRIES; i++) {
120  if (idt->entries[i]==ptr) {
121  idt->entries[i]=0;
122  idt->freeEntries++;
123  return 0;
124  }
125  } /* for */
126  return -1;
127 }
128 
129 
130 
131 static inline int GWEN_PointerListTable_IsEmpty(const GWEN_POINTERLIST_TABLE *idt)
132 {
133  return GWEN_POINTERLIST_TABLE_MAXENTRIES==idt->freeEntries;
134 }
135 
136 
137 
138 static inline int GWEN_PointerListTable_IsFull(const GWEN_POINTERLIST_TABLE *idt)
139 {
140  return idt->freeEntries==0;
141 }
142 
143 
144 #if 0
145 static inline unsigned int GWEN_PointerListTable_GetCount(const GWEN_POINTERLIST_TABLE *idt)
146 {
147  return GWEN_POINTERLIST_TABLE_MAXENTRIES-idt->freeEntries;
148 }
149 
150 
151 
152 static inline void *GWEN_PointerListTable_GetFirstPtr(const GWEN_POINTERLIST_TABLE *idt, uint64_t *tabIdx)
153 {
154  unsigned int i;
155 
156  for (i=0; i<GWEN_POINTERLIST_TABLE_MAXENTRIES; i++) {
157  if (idt->entries[i]!=0) {
158  *tabIdx=i;
159  return idt->entries[i];
160  }
161  } /* for */
162  return NULL;
163 }
164 
165 
166 
167 static inline void *GWEN_PointerListTable_GetNextPtr(const GWEN_POINTERLIST_TABLE *idt, uint64_t *tabIdx)
168 {
169  unsigned int i;
170 
171  for (i=(*tabIdx)+1; i<GWEN_POINTERLIST_TABLE_MAXENTRIES; i++) {
172  if (idt->entries[i]!=0) {
173  *tabIdx=i;
174  return idt->entries[i];
175  }
176  } /* for */
177  return NULL;
178 }
179 #endif
180 
181 
182 
183 
184 
186 {
187  GWEN_POINTERLIST *idl;
188 
190  idl->refCount=1;
191  idl->tableStep=GWEN_POINTERLIST_DEFAULT_STEP;
192  return idl;
193 }
194 
195 
196 
198 {
199  assert(idl);
200  assert(idl->refCount);
201  idl->refCount++;
202 }
203 
204 
205 
207 {
208  if (idl) {
209  assert(idl->refCount);
210  if (idl->refCount==1) {
212  idl->refCount=0;
213  GWEN_FREE_OBJECT(idl);
214  }
215  else
216  idl->refCount--;
217  }
218 }
219 
220 
221 
222 void GWEN_PointerList_AddTable(GWEN_POINTERLIST *idl, GWEN_POINTERLIST_TABLE *idt)
223 {
224  GWEN_POINTERLIST_TABLE **tablePtr;
225  uint32_t idx;
226 
227  assert(idl);
228 
229  tablePtr=idl->pIdTablePointers;
230  for (idx=0, tablePtr=idl->pIdTablePointers; idx<idl->idTableCount; idx++, tablePtr++) {
231  if (*tablePtr==NULL)
232  break;
233  } /* while */
234 
235  if (idx>=idl->idTableCount) {
236  uint32_t newCount;
237  GWEN_POINTERLIST_TABLE **newPtr;
238 
239  /* resize */
240  newCount=idl->idTableCount+idl->tableStep;
241  newPtr=(GWEN_POINTERLIST_TABLE **)realloc(idl->pIdTablePointers, sizeof(GWEN_POINTERLIST_TABLE *)*newCount);
242  assert(newPtr);
243  /* init new pointers */
244  memset((void *)(newPtr+idl->idTableCount),
245  0,
246  sizeof(GWEN_POINTERLIST_TABLE *)*(newCount-idl->idTableCount));
247  idl->pIdTablePointers=newPtr;
248  idl->pIdTablePointers[idl->idTableCount]=idt;
249  idl->lastTableIdx=idl->idTableCount;
250  idl->idTableCount=newCount;
251  }
252  else {
253  idl->pIdTablePointers[idx]=idt;
254  idl->lastTableIdx=idx;
255  }
256 }
257 
258 
259 
261 {
262  GWEN_POINTERLIST_TABLE *idt=NULL;
263  GWEN_POINTERLIST_TABLE **tablePtr;
264  uint32_t idx;
265 
266  assert(idl);
267 
268  if (idl->pIdTablePointers==NULL) {
269  /* create an initial pointer table which can take up to tableStep pointers */
270  idl->pIdTablePointers=(GWEN_POINTERLIST_TABLE **) malloc(sizeof(GWEN_POINTERLIST_TABLE *)*(idl->tableStep));
271  assert(idl->pIdTablePointers);
272  memset(idl->pIdTablePointers, 0, sizeof(GWEN_POINTERLIST *)*(idl->tableStep));
273  idl->idTableCount=idl->tableStep;
274  }
275 
276  for (idx=0, tablePtr=idl->pIdTablePointers; idx<idl->idTableCount; idx++, tablePtr++) {
277  idt=*tablePtr;
278  if (idt && !GWEN_PointerListTable_IsFull(idt))
279  break;
280  } /* while */
281 
282  if (idx>=idl->idTableCount) {
284  GWEN_PointerList_AddTable(idl, idt);
285  }
286 
288  idl->entryCount++;
289  return 0;
290 }
291 
292 
293 
295 {
296  if (idl->pIdTablePointers) {
297  GWEN_POINTERLIST_TABLE *idt=NULL;
298  GWEN_POINTERLIST_TABLE **tablePtr;
299  uint32_t idx;
300 
301  for (idx=0, tablePtr=idl->pIdTablePointers; idx<idl->idTableCount; idx++, tablePtr++) {
302  idt=*tablePtr;
303  if (idt && !GWEN_PointerListTable_DelPtr(idt, ptr)) {
304  /* found a table which had this id */
306  idl->entryCount--;
307  return 0;
308  }
309  }
310  }
311 
312  return -1;
313 }
314 
315 
316 
317 int GWEN_PointerList_HasPtr(const GWEN_POINTERLIST *idl, void *ptr)
318 {
319  if (idl->pIdTablePointers) {
320  GWEN_POINTERLIST_TABLE *idt=NULL;
321  GWEN_POINTERLIST_TABLE **tablePtr;
322  uint32_t idx;
323 
324  for (idx=0, tablePtr=idl->pIdTablePointers; idx<idl->idTableCount; idx++, tablePtr++) {
325  idt=*tablePtr;
326  if (idt && GWEN_PointerListTable_HasPtr(idt, ptr))
327  return 1;
328  }
329  }
330 
331  return 0;
332 }
333 
334 
335 
337 {
338  GWEN_POINTERLIST_TABLE *idt=NULL;
339  GWEN_POINTERLIST_TABLE **tablePtr;
340  uint32_t idx;
341 
342  for (idx=0, tablePtr=idl->pIdTablePointers; idx<idl->idTableCount; idx++, tablePtr++) {
343  idt=*tablePtr;
344  if (idt && GWEN_PointerListTable_IsEmpty(idt)) {
346  *tablePtr=NULL;
347  }
348  }
349 }
350 
351 
352 
354 {
355  if (idl->pIdTablePointers) {
356  GWEN_POINTERLIST_TABLE *idt=NULL;
357  GWEN_POINTERLIST_TABLE **tablePtr;
358  uint32_t idx;
359 
360  for (idx=0, tablePtr=idl->pIdTablePointers; idx<idl->idTableCount; idx++, tablePtr++) {
361  idt=*tablePtr;
362  if (idt) {
364  *tablePtr=NULL;
365  }
366  }
367  free(idl->pIdTablePointers);
368  idl->pIdTablePointers=NULL;
369  }
370  idl->entryCount=0;
371  idl->nextIdx=0;
372 }
373 
374 
375 
377 {
378  GWEN_POINTERLIST *nidl;
379  uint32_t idx;
380 
381  nidl=GWEN_PointerList_new();
382  nidl->tableStep=idl->tableStep;
383 
384  nidl->idTableCount=idl->idTableCount;
385  nidl->entryCount=idl->entryCount;
386  if (idl->pIdTablePointers) {
387  for (idx=0; idx<idl->idTableCount; idx++) {
388  GWEN_POINTERLIST_TABLE *idt;
389 
390  idt=idl->pIdTablePointers[idx];
391  if (idt && !GWEN_PointerListTable_IsEmpty(idt)) {
392  GWEN_POINTERLIST_TABLE *nidt;
393 
395  memmove(nidt->entries, idt->entries, GWEN_POINTERLIST_TABLE_MAXENTRIES*sizeof(void *));
396  nidt->freeEntries=idt->freeEntries;
397  GWEN_PointerList_AddTable(nidl, nidt);
398  }
399  }
400  }
401 
402  return nidl;
403 }
404 
405 
406 
408 {
409  assert(idl);
410  assert(idl->refCount);
411 
412  return idl->entryCount;
413 }
414 
415 
416 
417 void *GWEN_PointerList_GetFirstPtr(const GWEN_POINTERLIST *idl, uint64_t *pos)
418 {
419  GWEN_POINTERLIST_TABLE *idt=NULL;
420  GWEN_POINTERLIST_TABLE **tablePtr;
421  uint32_t idx;
422  int idIndex=0;
423 
424  *pos=0;
425  for (idx=0, tablePtr=idl->pIdTablePointers; idx<idl->idTableCount; idx++, tablePtr++) {
426  idt=*tablePtr;
427  if (idt && !GWEN_PointerListTable_IsEmpty(idt)) {
428  int i;
429  void *ptr;
430 
431  for (i=0; i<GWEN_POINTERLIST_TABLE_MAXENTRIES; i++) {
432  if (idt->entries[i]!=0) {
433  ptr=idt->entries[i];
434  *pos=idIndex+i+1;
435  return ptr;
436  }
437  }
438  }
439  idIndex+=GWEN_POINTERLIST_TABLE_MAXENTRIES;
440  }
441 
442  return NULL;
443 }
444 
445 
446 
447 void *GWEN_PointerList_GetNextPtr(const GWEN_POINTERLIST *idl, uint64_t *pos)
448 {
449  if (*pos) {
450  GWEN_POINTERLIST_TABLE *idt;
451  uint64_t tableNum=*pos / GWEN_POINTERLIST_TABLE_MAXENTRIES;
452  uint64_t tableIdx=*pos % GWEN_POINTERLIST_TABLE_MAXENTRIES;
453  GWEN_POINTERLIST_TABLE **tablePtr;
454  int idIndex=0;
455  uint32_t idx;
456 
457  if (tableNum>idl->idTableCount) {
458  DBG_ERROR(GWEN_LOGDOMAIN, "Table number out of range");
459  *pos=0;
460  return 0;
461  }
462 
463  idIndex=(tableNum*GWEN_POINTERLIST_TABLE_MAXENTRIES);
464  for (idx=tableNum, tablePtr=idl->pIdTablePointers+tableNum; idx<idl->idTableCount; idx++, tablePtr++) {
465  idt=*tablePtr;
466  if (idt && !GWEN_PointerListTable_IsEmpty(idt)) {
467  int i;
468  void *ptr;
469 
470  if (idx==tableNum) {
471  for (i=tableIdx; i<GWEN_POINTERLIST_TABLE_MAXENTRIES; i++) {
472  if (idt->entries[i]!=0) {
473  ptr=idt->entries[i];
474  *pos=idIndex+i+1;
475  return ptr;
476  }
477  }
478  }
479  else {
480  for (i=0; i<GWEN_POINTERLIST_TABLE_MAXENTRIES; i++) {
481  if (idt->entries[i]!=0) {
482  ptr=idt->entries[i];
483  *pos=idIndex+i+1;
484  return ptr;
485  }
486  }
487  }
488  }
489  idIndex+=GWEN_POINTERLIST_TABLE_MAXENTRIES;
490  }
491  *pos=0;
492  }
493 
494  return NULL;
495 }
496 
497 
498 
499 
501 {
503 
504  assert(idl);
506 
508  it->list=idl;
509 
510  return it;
511 }
512 
513 
514 
516 {
517  if (it) {
518  GWEN_PointerList_free(it->list);
519  GWEN_FREE_OBJECT(it);
520  }
521 }
522 
523 
524 
526 {
527  return GWEN_PointerList_GetFirstPtr(it->list, &(it->nextIndex));
528 }
529 
530 
531 
533 {
534  return GWEN_PointerList_GetNextPtr(it->list, &(it->nextIndex));
535 }
536 
537 
538 
540 {
541  GWEN_POINTERLIST_TABLE *idt=NULL;
542 
543  assert(idl);
544 
545  if (idl->pIdTablePointers==NULL) {
546  /* create an initial pointer table which can take up to tableStep pointers */
547  idl->pIdTablePointers=(GWEN_POINTERLIST_TABLE **) malloc(sizeof(GWEN_POINTERLIST_TABLE *)*(idl->tableStep));
548  assert(idl->pIdTablePointers);
549  memset(idl->pIdTablePointers, 0, sizeof(GWEN_POINTERLIST_TABLE *)*(idl->tableStep));
550  idl->idTableCount=idl->tableStep;
551  }
552 
553  idt=idl->pIdTablePointers[idl->lastTableIdx];
554  if (idt==NULL || GWEN_PointerListTable_IsFull(idt)) {
556  GWEN_PointerList_AddTable(idl, idt);
557  }
558 
560  idl->entryCount++;
561  return 0;
562 }
563 
564 
565 
566 void *GWEN_PointerList_GetPtrAt(const GWEN_POINTERLIST *idl, uint64_t idx)
567 {
568  GWEN_POINTERLIST_TABLE *idt;
569  uint64_t tableNum=idx / GWEN_POINTERLIST_TABLE_MAXENTRIES;
570  uint64_t tableIdx=idx % GWEN_POINTERLIST_TABLE_MAXENTRIES;
571 
572  assert(idl);
573  if (tableNum>idl->idTableCount) {
574  DBG_INFO(GWEN_LOGDOMAIN, "Table index out of range");
575  return 0;
576  }
577 
578  idt=idl->pIdTablePointers[tableNum];
579  if (idt==NULL) {
580  DBG_INFO(GWEN_LOGDOMAIN, "Table index points to an empty table");
581  return 0;
582  }
583 
584  return idt->entries[tableIdx];
585 }
586 
587 
588 
589 
590 
591 
592 
593 
594 
595 
596 
int GWEN_PointerList_AppendPtr(GWEN_POINTERLIST *idl, void *ptr)
Definition: pointerlist.c:539
void GWEN_PointerListTable_free(GWEN_POINTERLIST_TABLE *idt)
Definition: pointerlist.c:57
#define GWEN_FREE_OBJECT(varname)
Definition: memory.h:61
#define NULL
Definition: binreloc.c:297
GWEN_POINTERLIST_ITERATOR * GWEN_PointerList_Iterator_new(GWEN_POINTERLIST *idl)
Definition: pointerlist.c:500
static int GWEN_PointerListTable_HasPtr(const GWEN_POINTERLIST_TABLE *idt, void *ptr)
Definition: pointerlist.c:101
GWEN_POINTERLIST_TABLE * GWEN_PointerListTable_new(void)
Definition: pointerlist.c:44
#define GWEN_LOGDOMAIN
Definition: logger.h:35
void GWEN_PointerList_Clean(GWEN_POINTERLIST *idl)
Definition: pointerlist.c:336
uint64_t GWEN_PointerList_GetEntryCount(const GWEN_POINTERLIST *idl)
Definition: pointerlist.c:407
void GWEN_PointerList_free(GWEN_POINTERLIST *idl)
Definition: pointerlist.c:206
int GWEN_PointerList_AddPtr(GWEN_POINTERLIST *idl, void *ptr)
Definition: pointerlist.c:260
void * GWEN_PointerList_GetPtrAt(const GWEN_POINTERLIST *idl, uint64_t idx)
Definition: pointerlist.c:566
void GWEN_PointerList_AddTable(GWEN_POINTERLIST *idl, GWEN_POINTERLIST_TABLE *idt)
Definition: pointerlist.c:222
void GWEN_PointerList_Attach(GWEN_POINTERLIST *idl)
Definition: pointerlist.c:197
static int GWEN_PointerListTable_IsFull(const GWEN_POINTERLIST_TABLE *idt)
Definition: pointerlist.c:138
int GWEN_PointerList_DelPtr(GWEN_POINTERLIST *idl, void *ptr)
Definition: pointerlist.c:294
#define GWEN_NEW_OBJECT(typ, varname)
Definition: memory.h:55
void * GWEN_PointerList_GetFirstPtr(const GWEN_POINTERLIST *idl, uint64_t *pos)
Definition: pointerlist.c:417
void GWEN_PointerList_Clear(GWEN_POINTERLIST *idl)
Definition: pointerlist.c:353
static int GWEN_PointerListTable_DelPtr(GWEN_POINTERLIST_TABLE *idt, void *ptr)
Definition: pointerlist.c:115
static int GWEN_PointerListTable_AppendPtr(GWEN_POINTERLIST_TABLE *idt, void *ptr)
Definition: pointerlist.c:85
static int GWEN_PointerListTable_AddPtr(GWEN_POINTERLIST_TABLE *idt, void *ptr)
Definition: pointerlist.c:69
int GWEN_PointerList_HasPtr(const GWEN_POINTERLIST *idl, void *ptr)
Definition: pointerlist.c:317
static int GWEN_PointerListTable_IsEmpty(const GWEN_POINTERLIST_TABLE *idt)
Definition: pointerlist.c:131
GWEN_POINTERLIST * GWEN_PointerList_dup(const GWEN_POINTERLIST *idl)
Definition: pointerlist.c:376
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
void * GWEN_PointerList_Iterator_GetFirstId(GWEN_POINTERLIST_ITERATOR *it)
Definition: pointerlist.c:525
void GWEN_PointerList_Iterator_free(GWEN_POINTERLIST_ITERATOR *it)
Definition: pointerlist.c:515
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:178
void * GWEN_PointerList_Iterator_GetNextId(GWEN_POINTERLIST_ITERATOR *it)
Definition: pointerlist.c:532
struct GWEN_POINTERLIST GWEN_POINTERLIST
Definition: pointerlist.h:36
GWEN_POINTERLIST * GWEN_PointerList_new(void)
Definition: pointerlist.c:185
struct GWEN_POINTERLIST_ITERATOR GWEN_POINTERLIST_ITERATOR
Definition: pointerlist.h:37
void * GWEN_PointerList_GetNextPtr(const GWEN_POINTERLIST *idl, uint64_t *pos)
Definition: pointerlist.c:447