gwenhywfar  4.99.25rc9
idlist.c
Go to the documentation of this file.
1 /***************************************************************************
2  $RCSfile$
3  -------------------
4  cvs : $Id$
5  begin : Mon Mar 01 2004
6  copyright : (C) 2004 by Martin Preuss
7  email : martin@libchipcard.de
8 
9  ***************************************************************************
10  * *
11  * This library is free software; you can redistribute it and/or *
12  * modify it under the terms of the GNU Lesser General Public *
13  * License as published by the Free Software Foundation; either *
14  * version 2.1 of the License, or (at your option) any later version. *
15  * *
16  * This library is distributed in the hope that it will be useful, *
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
19  * Lesser General Public License for more details. *
20  * *
21  * You should have received a copy of the GNU Lesser General Public *
22  * License along with this library; if not, write to the Free Software *
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
24  * MA 02111-1307 USA *
25  * *
26  ***************************************************************************/
27 
28 
29 
30 #ifdef HAVE_CONFIG_H
31 # include <config.h>
32 #endif
33 
34 
35 #include "idlist_p.h"
36 #include <gwenhywfar/debug.h>
37 
38 
39 #include <stdlib.h>
40 #include <assert.h>
41 #include <string.h>
42 
43 
44 GWEN_LIST_FUNCTIONS(GWEN_IDTABLE, GWEN_IdTable)
45 /* No trailing semicolon here because this is a macro call */
46 
47 
48 
49 GWEN_IDTABLE *GWEN_IdTable_new(void)
50 {
51  GWEN_IDTABLE *idt;
52 
53  GWEN_NEW_OBJECT(GWEN_IDTABLE, idt);
54  GWEN_LIST_INIT(GWEN_IDTABLE, idt);
55 
56  idt->freeEntries=GWEN_IDTABLE_MAXENTRIES;
57  return idt;
58 }
59 
60 
61 
62 void GWEN_IdTable_free(GWEN_IDTABLE *idt)
63 {
64  if (idt) {
65  GWEN_LIST_FINI(GWEN_IDTABLE, idt);
66  GWEN_FREE_OBJECT(idt);
67  }
68 }
69 
70 
71 
72 int GWEN_IdTable_AddId(GWEN_IDTABLE *idt, uint32_t id)
73 {
74  unsigned int i;
75 
76  assert(idt);
77  assert(id);
78 
79  for (i=0; i<GWEN_IDTABLE_MAXENTRIES; i++) {
80  if (idt->entries[i]==0) {
81  idt->entries[i]=id;
82  idt->freeEntries--;
83  return 0;
84  }
85  } /* for */
86  return -1;
87 }
88 
89 
90 
91 int GWEN_IdTable_HasId(const GWEN_IDTABLE *idt, uint32_t id)
92 {
93  unsigned int i;
94 
95  assert(idt);
96  assert(id);
97 
98  for (i=0; i<GWEN_IDTABLE_MAXENTRIES; i++) {
99  if (idt->entries[i]==id) {
100  return 1;
101  }
102  } /* for */
103  return 0;
104 }
105 
106 
107 
108 int GWEN_IdTable_DelId(GWEN_IDTABLE *idt, uint32_t id)
109 {
110  unsigned int i;
111 
112  assert(idt);
113  assert(id);
114 
115  for (i=0; i<GWEN_IDTABLE_MAXENTRIES; i++) {
116  if (idt->entries[i]==id) {
117  idt->entries[i]=0;
118  idt->freeEntries++;
119  return 0;
120  }
121  } /* for */
122  return -1;
123 }
124 
125 
126 
127 int GWEN_IdTable_IsEmpty(const GWEN_IDTABLE *idt)
128 {
129  assert(idt);
130  return GWEN_IDTABLE_MAXENTRIES==idt->freeEntries;
131 }
132 
133 
134 
135 int GWEN_IdTable_IsFull(const GWEN_IDTABLE *idt)
136 {
137  assert(idt);
138  return idt->freeEntries==0;
139 }
140 
141 
142 
143 unsigned int GWEN_IdTable_GetCount(const GWEN_IDTABLE *idt)
144 {
145  assert(idt);
146  return GWEN_IDTABLE_MAXENTRIES-idt->freeEntries;
147 }
148 
149 
150 
151 uint32_t GWEN_IdTable_GetFirstId(GWEN_IDTABLE *idt)
152 {
153  unsigned int i;
154 
155  assert(idt);
156  idt->current=0;
157  for (i=0; i<GWEN_IDTABLE_MAXENTRIES; i++) {
158  if (idt->entries[i]!=0) {
159  idt->current=i;
160  return idt->entries[i];
161  }
162  } /* for */
163  return 0;
164 }
165 
166 
167 
168 uint32_t GWEN_IdTable_GetNextId(GWEN_IDTABLE *idt)
169 {
170  unsigned int i;
171 
172  assert(idt);
173 
174  for (i=idt->current+1; i<GWEN_IDTABLE_MAXENTRIES; i++) {
175  if (idt->entries[i]!=0) {
176  idt->current=i;
177  return idt->entries[i];
178  }
179  } /* for */
180  idt->current=GWEN_IDTABLE_MAXENTRIES;
181  return 0;
182 }
183 
184 
185 
186 uint32_t GWEN_IdTable_GetFirstId2(const GWEN_IDTABLE *idt,
187  uint32_t *tabIdx)
188 {
189  unsigned int i;
190 
191  assert(idt);
192  for (i=0; i<GWEN_IDTABLE_MAXENTRIES; i++) {
193  if (idt->entries[i]!=0) {
194  *tabIdx=i;
195  return idt->entries[i];
196  }
197  } /* for */
198  return 0;
199 }
200 
201 
202 
203 uint32_t GWEN_IdTable_GetNextId2(const GWEN_IDTABLE *idt,
204  uint32_t *tabIdx)
205 {
206  unsigned int i;
207 
208  assert(idt);
209 
210  for (i=(*tabIdx)+1; i<GWEN_IDTABLE_MAXENTRIES; i++) {
211  if (idt->entries[i]!=0) {
212  *tabIdx=i;
213  return idt->entries[i];
214  }
215  } /* for */
216  return 0;
217 }
218 
219 
220 
221 
222 
223 
225 {
226  GWEN_IDLIST *idl;
227 
229  idl->idTables=GWEN_IdTable_List_new();
230  return idl;
231 }
232 
233 
234 
236 {
237  if (idl) {
238  GWEN_IdTable_List_free(idl->idTables);
239  GWEN_FREE_OBJECT(idl);
240  }
241 }
242 
243 
244 
245 int GWEN_IdList_AddId(GWEN_IDLIST *idl, uint32_t id)
246 {
247  GWEN_IDTABLE *idt;
248 
249  assert(idl);
250 
251  idl->current=0;
252  idt=GWEN_IdTable_List_First(idl->idTables);
253  /* find free table */
254  while (idt) {
255  if (!GWEN_IdTable_IsFull(idt))
256  break;
257  idt=GWEN_IdTable_List_Next(idt);
258  } /* while */
259 
260  if (!idt) {
261  idt=GWEN_IdTable_new();
262  GWEN_IdTable_List_Add(idt, idl->idTables);;
263  }
264 
265  GWEN_IdTable_AddId(idt, id);
266  idl->entryCount++;
267  return 0;
268 }
269 
270 
271 
272 int GWEN_IdList_DelId(GWEN_IDLIST *idl, uint32_t id)
273 {
274  GWEN_IDTABLE *idt;
275 
276  assert(idl);
277 
278  idl->current=0;
279  idt=GWEN_IdTable_List_First(idl->idTables);
280  /* find table */
281  while (idt) {
282  if (!GWEN_IdTable_DelId(idt, id)) {
283  /* found a table which had this id */
284  GWEN_IdList_Clean(idl);
285  idl->entryCount--;
286  return 0;
287  }
288  idt=GWEN_IdTable_List_Next(idt);
289  } /* while */
290  return -1;
291 }
292 
293 
294 
295 int GWEN_IdList_HasId(const GWEN_IDLIST *idl, uint32_t id)
296 {
297  GWEN_IDTABLE *idt;
298 
299  assert(idl);
300 
301  idt=GWEN_IdTable_List_First(idl->idTables);
302  /* find free table */
303  while (idt) {
304  if (GWEN_IdTable_HasId(idt, id))
305  return 1;
306  idt=GWEN_IdTable_List_Next(idt);
307  } /* while */
308  return 0;
309 }
310 
311 
312 
314 {
315  GWEN_IDTABLE *idt;
316 
317  assert(idl);
318  idl->current=0;
319  idt=GWEN_IdTable_List_First(idl->idTables);
320  /* find free table */
321  while (idt) {
322  GWEN_IDTABLE *next;
323 
324  next=GWEN_IdTable_List_Next(idt);
325  if (GWEN_IdTable_IsEmpty(idt)) {
326  GWEN_IdTable_List_Del(idt);
327  GWEN_IdTable_free(idt);
328  }
329  idt=next;
330  } /* while */
331 }
332 
333 
334 
336 {
337  GWEN_IDTABLE *idt;
338 
339  assert(idl);
340 
341  idt=GWEN_IdTable_List_First(idl->idTables);
342  /* find free table */
343  while (idt) {
344  GWEN_IDTABLE *next;
345  uint32_t id;
346 
347  next=GWEN_IdTable_List_Next(idt);
348  id=GWEN_IdTable_GetFirstId(idt);
349  if (id) {
350  idl->current=idt;
351  return id;
352  }
353  idt=next;
354  } /* while */
355 
356  return 0;
357 }
358 
359 
360 
362 {
363  GWEN_IDTABLE *idt;
364  uint32_t id;
365 
366  assert(idl);
367 
368  idt=idl->current;
369  if (idt) {
370  id=GWEN_IdTable_GetNextId(idt);
371  if (id) {
372  idl->current=idt;
373  return id;
374  }
375  }
376  else {
377  idl->current=0;
378  return 0;
379  }
380 
381  idt=GWEN_IdTable_List_Next(idt);
382  while (idt) {
383  id=GWEN_IdTable_GetFirstId(idt);
384  if (id) {
385  idl->current=idt;
386  return id;
387  }
388  idt=GWEN_IdTable_List_Next(idt);
389  } /* while */
390 
391  idl->current=0;
392  return 0;
393 }
394 
395 
396 
398 {
399  GWEN_IDTABLE *idt;
400  unsigned int cnt;
401  uint32_t *ptr;
402  unsigned int i;
403 
404  assert(idl);
405 
406  /* count ids */
407  idt=GWEN_IdTable_List_First(idl->idTables);
408  cnt=0;
409  while (idt) {
410  GWEN_IDTABLE *next;
411 
412  next=GWEN_IdTable_List_Next(idt);
413  cnt+=GWEN_IdTable_GetCount(idt);
414  idt=next;
415  } /* while */
416 
417  if (!cnt)
418  return 0;
419 
420  /* move ids to a temporary list */
421  ptr=(uint32_t *)malloc(sizeof(uint32_t)*cnt);
422  assert(ptr);
423 
424  for (i=0; i<cnt; i++) {
425  uint32_t id;
426 
427  if (i==0)
428  id=GWEN_IdList_GetFirstId(idl);
429  else
430  id=GWEN_IdList_GetNextId(idl);
431  assert(id);
432  ptr[i]=id;
433  } /* for */
434 
435  GWEN_IdTable_List_Clear(idl->idTables);
436  idl->current=0;
437 
438  /* sort temporary list */
439  while (1) {
440  int rpl;
441 
442  rpl=0;
443  for (i=0; i<(cnt-1); i++) {
444  if (ptr[i]>ptr[i+1]) {
445  uint32_t id;
446 
447  id=ptr[i];
448  ptr[i]=ptr[i+1];
449  ptr[i+1]=id;
450  rpl=1;
451  }
452  } /* for */
453  if (!rpl)
454  break;
455  } /* while */
456 
457  /* move back from temporary list */
458  for (i=0; i<cnt; i++) {
459  GWEN_IdList_AddId(idl, ptr[i]);
460  }
461  free(ptr);
462 
463  return 0;
464 }
465 
466 
467 
469 {
470  assert(idl);
471  GWEN_IdTable_List_Clear(idl->idTables);
472  idl->entryCount=0;
473  idl->current=0;
474 }
475 
476 
477 
479 {
480  GWEN_IDLIST *nidl;
481  GWEN_IDTABLE *idt;
482 
483  assert(idl);
484  nidl=GWEN_IdList_new();
485 
486  idt=GWEN_IdTable_List_First(idl->idTables);
487  while (idt) {
488  if (idt->freeEntries!=GWEN_IDTABLE_MAXENTRIES) {
489  int i;
490 
491  for (i=0; i<GWEN_IDTABLE_MAXENTRIES; i++) {
492  if (idt->entries[i]!=0)
493  GWEN_IdList_AddId(nidl, idt->entries[i]);
494  }
495  }
496  idt=GWEN_IdTable_List_Next(idt);
497  }
498 
499  return nidl;
500 }
501 
502 
503 
505  uint32_t *pos)
506 {
507  GWEN_IDTABLE *idt;
508  int tabNum=0;
509 
510  assert(idl);
511 
512  idt=GWEN_IdTable_List_First(idl->idTables);
513  /* find free table */
514  while (idt) {
515  GWEN_IDTABLE *next;
516  uint32_t id;
517  uint32_t tabIdx;
518 
519  next=GWEN_IdTable_List_Next(idt);
520  id=GWEN_IdTable_GetFirstId2(idt, &tabIdx);
521  if (id) {
522  *pos=(tabNum*GWEN_IDTABLE_MAXENTRIES)+tabIdx;
523  return id;
524  }
525  tabNum++;
526  idt=next;
527  } /* while */
528 
529  return 0;
530 }
531 
532 
533 
535  uint32_t *pos)
536 {
537  GWEN_IDTABLE *idt;
538  int i;
539  int tabNum;
540  uint32_t tabIdx;
541 
542  assert(idl);
543  tabNum=(*pos)/GWEN_IDTABLE_MAXENTRIES;
544  tabIdx=(*pos)%GWEN_IDTABLE_MAXENTRIES;
545 
546  /* seek table */
547  i=tabNum;
548  idt=GWEN_IdTable_List_First(idl->idTables);
549  while (i--)
550  idt=GWEN_IdTable_List_Next(idt);
551  assert(idt);
552 
553  while (idt) {
554  GWEN_IDTABLE *next;
555  uint32_t id;
556 
557  next=GWEN_IdTable_List_Next(idt);
558  id=GWEN_IdTable_GetNextId2(idt, &tabIdx);
559  if (id) {
560  *pos=(tabNum*GWEN_IDTABLE_MAXENTRIES)+tabIdx;
561  return id;
562  }
563  tabNum++;
564  idt=next;
565  } /* while */
566 
567  return 0;
568 }
569 
570 
571 
572 
573 
574 
575 
576 
577 
578 
579 
void GWEN_IdList_Clean(GWEN_IDLIST *idl)
Definition: idlist.c:313
GWEN_IDLIST * GWEN_IdList_new(void)
Definition: idlist.c:224
int GWEN_IdTable_IsEmpty(const GWEN_IDTABLE *idt)
Definition: idlist.c:127
void GWEN_IdList_free(GWEN_IDLIST *idl)
Definition: idlist.c:235
uint32_t GWEN_IdList_GetNextId(GWEN_IDLIST *idl)
Definition: idlist.c:361
void GWEN_IdTable_free(GWEN_IDTABLE *idt)
Definition: idlist.c:62
#define GWEN_FREE_OBJECT(varname)
Definition: memory.h:61
int GWEN_IdList_HasId(const GWEN_IDLIST *idl, uint32_t id)
Definition: idlist.c:295
uint32_t GWEN_IdTable_GetNextId2(const GWEN_IDTABLE *idt, uint32_t *tabIdx)
Definition: idlist.c:203
GWEN_IDTABLE * GWEN_IdTable_new(void)
Definition: idlist.c:49
uint32_t GWEN_IdTable_GetFirstId2(const GWEN_IDTABLE *idt, uint32_t *tabIdx)
Definition: idlist.c:186
uint32_t GWEN_IdTable_GetNextId(GWEN_IDTABLE *idt)
Definition: idlist.c:168
void GWEN_IdList_Clear(GWEN_IDLIST *idl)
Definition: idlist.c:468
int GWEN_IdTable_AddId(GWEN_IDTABLE *idt, uint32_t id)
Definition: idlist.c:72
#define GWEN_NEW_OBJECT(typ, varname)
Definition: memory.h:55
uint32_t GWEN_IdTable_GetFirstId(GWEN_IDTABLE *idt)
Definition: idlist.c:151
int GWEN_IdTable_DelId(GWEN_IDTABLE *idt, uint32_t id)
Definition: idlist.c:108
struct GWEN_IDLIST GWEN_IDLIST
Definition: idlist.h:39
GWEN_IDLIST * GWEN_IdList_dup(const GWEN_IDLIST *idl)
Definition: idlist.c:478
int GWEN_IdList_DelId(GWEN_IDLIST *idl, uint32_t id)
Definition: idlist.c:272
uint32_t GWEN_IdList_GetNextId2(const GWEN_IDLIST *idl, uint32_t *pos)
Definition: idlist.c:534
uint32_t GWEN_IdList_GetFirstId2(const GWEN_IDLIST *idl, uint32_t *pos)
Definition: idlist.c:504
unsigned int GWEN_IdTable_GetCount(const GWEN_IDTABLE *idt)
Definition: idlist.c:143
#define GWEN_LIST_INIT(t, element)
Definition: list1.h:465
int GWEN_IdList_Sort(GWEN_IDLIST *idl)
Definition: idlist.c:397
uint32_t GWEN_IdList_GetFirstId(GWEN_IDLIST *idl)
Definition: idlist.c:335
#define GWEN_LIST_FUNCTIONS(t, pr)
Definition: list1.h:366
#define GWEN_LIST_FINI(t, element)
Definition: list1.h:474
int GWEN_IdTable_IsFull(const GWEN_IDTABLE *idt)
Definition: idlist.c:135
int GWEN_IdList_AddId(GWEN_IDLIST *idl, uint32_t id)
Definition: idlist.c:245
int GWEN_IdTable_HasId(const GWEN_IDTABLE *idt, uint32_t id)
Definition: idlist.c:91