gwenhywfar  5.10.1
idmap.c
Go to the documentation of this file.
1 /***************************************************************************
2  $RCSfile$
3  -------------------
4  cvs : $Id: idlist.c 705 2005-02-23 02:16:57Z aquamaniac $
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 #ifdef HAVE_CONFIG_H
29 # include <config.h>
30 #endif
31 
32 
33 #include "idmap_p.h"
34 
35 #include <gwenhywfar/misc.h>
36 #include <gwenhywfar/debug.h>
37 
38 
39 #include <stdlib.h>
40 #include <assert.h>
41 #include <string.h>
42 
43 
44 
46 {
47  GWEN_IDMAP *map;
48 
50  map->algo=algo;
51  switch (algo) {
54  break;
56  default:
57  DBG_ERROR(GWEN_LOGDOMAIN, "Unknown algo %d", algo);
58  GWEN_IdMap_free(map);
59  return 0;
60  }
61 
62  return map;
63 }
64 
65 
66 
68 {
69  assert(map);
70  if (map->freeDataFn)
71  map->freeDataFn(map);
72  GWEN_FREE_OBJECT(map);
73 }
74 
75 
76 
78  uint32_t id,
79  void *ptr)
80 {
81  assert(map);
82  assert(ptr);
83  assert(map->setPairFn);
84  return map->setPairFn(map, id, ptr);
85 }
86 
87 
88 
90  uint32_t id)
91 {
92  assert(map);
93  assert(map->setPairFn);
94  return map->setPairFn(map, id, 0);
95 }
96 
97 
98 
99 void *GWEN_IdMap_Find(GWEN_IDMAP *map, uint32_t id)
100 {
101  assert(map);
102  assert(map->getPairFn);
103  return map->getPairFn(map, id);
104 }
105 
106 
107 
109  uint32_t *pid)
110 {
111  assert(map);
112  assert(map->findFirstFn);
113  return map->findFirstFn(map, pid);
114 }
115 
116 
117 
119  uint32_t *pid)
120 {
121  assert(map);
122  assert(map->findNextFn);
123  return map->findNextFn(map, pid);
124 }
125 
126 
127 
128 uint32_t GWEN_IdMap_GetSize(const GWEN_IDMAP *map)
129 {
130  assert(map);
131  return map->count;
132 }
133 
134 
135 
137 {
138  assert(map);
139  if (map->freeDataFn)
140  map->freeDataFn(map);
141  map->algoData=0;
142 
143  switch (map->algo) {
144  case GWEN_IdMapAlgo_Hex4:
146  break;
148  default:
149  DBG_ERROR(GWEN_LOGDOMAIN, "Unknown algo %d", map->algo);
150  }
151 }
152 
153 
154 
155 void GWEN_IdMap_Dump(GWEN_IDMAP *map, FILE *f, int indent)
156 {
157  assert(map);
158  if (map->dumpFn)
159  map->dumpFn(map, f, indent);
160  else {
161  DBG_ERROR(GWEN_LOGDOMAIN, "No dump fn");
162  }
163 }
164 
165 
166 
167 
168 
169 /* _________________________________________________________________________
170  * AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
171  * Algo: HEX4
172  * YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
173  */
174 
175 
177 {
178  GWEN_IDMAP_HEX4 *xmap;
179 
180  GWEN_NEW_OBJECT(GWEN_IDMAP_HEX4, xmap);
181  xmap->table=GWEN_IdMapHex4Map_new(0, 0);
182  map->algoData=(void *)xmap;
183  map->setPairFn=GWEN_IdMapHex4_Insert;
184  map->getPairFn=GWEN_IdMapHex4_Find;
185  map->findFirstFn=GWEN_IdMapHex4_FindFirst;
186  map->findNextFn=GWEN_IdMapHex4_FindNext;
187  map->freeDataFn=GWEN_IdMapHex4_free;
188  map->dumpFn=GWEN_IdMapHex4_Dump;
189 }
190 
191 
192 
194 {
195  GWEN_IDMAP_HEX4 *xmap;
196 
197  xmap=(GWEN_IDMAP_HEX4 *)map->algoData;
198  GWEN_IdMapHex4Map_free(xmap->table);
199  GWEN_FREE_OBJECT(xmap);
200 }
201 
202 
203 
204 GWEN_IDMAP_HEX4_TABLE *GWEN_IdMapHex4Map_new(GWEN_IDMAP_HEX4_TABLE *p,
205  int isPtrTable)
206 {
207  GWEN_IDMAP_HEX4_TABLE *t;
208 
209  GWEN_NEW_OBJECT(GWEN_IDMAP_HEX4_TABLE, t);
210  t->parent=p;
211  t->isPtrTable=isPtrTable;
212  return t;
213 }
214 
215 
216 
217 void GWEN_IdMapHex4Map_free(GWEN_IDMAP_HEX4_TABLE *t)
218 {
219  if (t) {
220  if (!(t->isPtrTable)) {
221  int i;
222 
223  for (i=0; i<16; i++) {
224  if (t->ptrs[i])
225  GWEN_IdMapHex4Map_free(t->ptrs[i]);
226  }
227  }
228  GWEN_FREE_OBJECT(t);
229  }
230 }
231 
232 
233 
235  uint32_t id,
236  void *ptr)
237 {
238  GWEN_IDMAP_HEX4 *xmap;
239  void **p;
240  GWEN_IDMAP_HEX4_TABLE *t;
241 
242  xmap=(GWEN_IDMAP_HEX4 *)map->algoData;
243 
244  t=xmap->table;
245  p=&(t->ptrs[(id>>28) & 0xf]);
246  if (!*p) {
247  if (ptr==0)
249  *p=(void *)GWEN_IdMapHex4Map_new(t, 0);
250  }
251  t=(GWEN_IDMAP_HEX4_TABLE *) *p;
252 
253  p=&(t->ptrs[(id>>24) & 0xf]);
254  if (!*p) {
255  if (ptr==0)
257  *p=(void *)GWEN_IdMapHex4Map_new(t, 0);
258  }
259  t=(GWEN_IDMAP_HEX4_TABLE *) *p;
260 
261  p=&(t->ptrs[(id>>20) & 0xf]);
262  if (!*p) {
263  if (ptr==0)
265  *p=(void *)GWEN_IdMapHex4Map_new(t, 0);
266  }
267  t=(GWEN_IDMAP_HEX4_TABLE *) *p;
268 
269  p=&(t->ptrs[(id>>16) & 0xf]);
270  if (!*p) {
271  if (ptr==0)
273  *p=(void *)GWEN_IdMapHex4Map_new(t, 0);
274  }
275  t=(GWEN_IDMAP_HEX4_TABLE *) *p;
276 
277  p=&(t->ptrs[(id>>12) & 0xf]);
278  if (!*p) {
279  if (ptr==0)
281  *p=(void *)GWEN_IdMapHex4Map_new(t, 0);
282  }
283  t=(GWEN_IDMAP_HEX4_TABLE *) *p;
284 
285  p=&(t->ptrs[(id>>8) & 0xf]);
286  if (!*p) {
287  if (ptr==0)
289  *p=(void *)GWEN_IdMapHex4Map_new(t, 0);
290  }
291  t=(GWEN_IDMAP_HEX4_TABLE *) *p;
292 
293  p=&(t->ptrs[(id>>4) & 0xf]);
294  if (!*p) {
295  if (ptr==0)
297  *p=(void *)GWEN_IdMapHex4Map_new(t, 1);
298  }
299  t=(GWEN_IDMAP_HEX4_TABLE *) *p;
300 
301  p=&(t->ptrs[id & 0xf]);
302  *p=ptr;
303 
304  if (ptr==0) {
305  assert(map->count);
306  map->count--;
307  /* do some cleanup */
308  for (;;) {
309  GWEN_IDMAP_HEX4_TABLE *parent;
310  int i;
311 
312  parent=t->parent;
313  id>>=4;
314  if (parent==0)
315  break;
316  for (i=0; i<16; i++) {
317  if (t->ptrs[i]!=0)
318  break;
319  }
320  if (i<16)
321  break;
322  /* DBG_ERROR(0, "Deleting table %x", id); */
324  parent->ptrs[id & 0xf]=0;
325  t=parent;
326  }
327  }
328  else
329  map->count++;
330 
331  return GWEN_IdMapResult_Ok;
332 }
333 
334 
335 
336 void *GWEN_IdMapHex4_Find(GWEN_IDMAP *map, uint32_t id)
337 {
338  GWEN_IDMAP_HEX4 *xmap;
339  GWEN_IDMAP_HEX4_TABLE *t;
340 
341  xmap=(GWEN_IDMAP_HEX4 *)map->algoData;
342 
343  t=xmap->table;
344  if (!t)
345  return 0;
346  t=(GWEN_IDMAP_HEX4_TABLE *)(t->ptrs[(id>>28)&0xf]);
347  if (!t)
348  return 0;
349  t=(GWEN_IDMAP_HEX4_TABLE *)(t->ptrs[(id>>24)&0xf]);
350  if (!t)
351  return 0;
352  t=(GWEN_IDMAP_HEX4_TABLE *)(t->ptrs[(id>>20)&0xf]);
353  if (!t)
354  return 0;
355  t=(GWEN_IDMAP_HEX4_TABLE *)(t->ptrs[(id>>16)&0xf]);
356  if (!t)
357  return 0;
358  t=(GWEN_IDMAP_HEX4_TABLE *)(t->ptrs[(id>>12)&0xf]);
359  if (!t)
360  return 0;
361  t=(GWEN_IDMAP_HEX4_TABLE *)(t->ptrs[(id>>8)&0xf]);
362  if (!t)
363  return 0;
364  t=(GWEN_IDMAP_HEX4_TABLE *)(t->ptrs[(id>>4)&0xf]);
365  if (!t)
366  return 0;
367 
368  return (t->ptrs[id & 0xf]);
369 }
370 
371 
372 
373 GWEN_IDMAP_HEX4_TABLE *GWEN_IdMapHex4__GetTable(GWEN_IDMAP_HEX4_TABLE *t,
374  uint32_t id)
375 {
376  void **p;
377 
378  p=&(t->ptrs[(id>>28) & 0xf]);
379  if (!*p)
380  return 0;
381  t=(GWEN_IDMAP_HEX4_TABLE *) *p;
382 
383  p=&(t->ptrs[(id>>24) & 0xf]);
384  if (!*p)
385  return 0;
386  t=(GWEN_IDMAP_HEX4_TABLE *) *p;
387 
388  p=&(t->ptrs[(id>>20) & 0xf]);
389  if (!*p)
390  return 0;
391  t=(GWEN_IDMAP_HEX4_TABLE *) *p;
392 
393  p=&(t->ptrs[(id>>16) & 0xf]);
394  if (!*p)
395  return 0;
396  t=(GWEN_IDMAP_HEX4_TABLE *) *p;
397 
398  p=&(t->ptrs[(id>>12) & 0xf]);
399  if (!*p)
400  return 0;
401  t=(GWEN_IDMAP_HEX4_TABLE *) *p;
402 
403  p=&(t->ptrs[(id>>8) & 0xf]);
404  if (!*p)
405  return 0;
406  t=(GWEN_IDMAP_HEX4_TABLE *) *p;
407 
408  p=&(t->ptrs[(id>>4) & 0xf]);
409  if (!*p)
410  return 0;
411  t=(GWEN_IDMAP_HEX4_TABLE *) *p;
412 
413  return t;
414 }
415 
416 
417 
418 GWEN_IDMAP_HEX4_TABLE *GWEN_IdMapHex4__GetFirstTable(GWEN_IDMAP_HEX4_TABLE *t,
419  uint32_t *pid)
420 {
421  uint32_t id;
422  int i;
423 
424  /* id=*pid; */
425  id=0;
426  for (i=0; i<16; i++) {
427  if (t->ptrs[i]) {
428  uint32_t lid;
429 
430  lid=(id<<4) | i;
431  if (t->isPtrTable) {
432  *pid=lid;
433  return t;
434  }
435  else {
436  GWEN_IDMAP_HEX4_TABLE *dt;
437 
438  dt=GWEN_IdMapHex4__GetFirstTable((GWEN_IDMAP_HEX4_TABLE *)(t->ptrs[i]),
439  &lid);
440  if (dt) {
441  *pid=lid;
442  return dt;
443  }
444  }
445  }
446  }
447  return 0;
448 }
449 
450 
451 
452 GWEN_IDMAP_HEX4_TABLE *GWEN_IdMapHex4__GetNextTable(GWEN_IDMAP_HEX4_TABLE *t,
453  uint32_t *pid,
454  int incr)
455 {
456  uint32_t id;
457 
458  id=*pid;
459  while (t) {
460  int i;
461 
462  if (incr) {
463  while (t && (id & 0xf)==0xf) {
464  t=t->parent;
465  id>>=4;
466  }
467  if (!t)
468  return 0;
469  id++;
470  }
471 
472  for (i=id & 0xf; i<16; i++) {
473  if (t->ptrs[i]) {
474  uint32_t lid;
475 
476  lid=((id & 0xfffffff0) | i);
477  if (t->isPtrTable) {
478  *pid=lid;
479  return t;
480  }
481  else {
482  GWEN_IDMAP_HEX4_TABLE *dt;
483 
484  lid=lid<<4;
485  dt=GWEN_IdMapHex4__GetNextTable((GWEN_IDMAP_HEX4_TABLE *)(t->ptrs[i]),
486  &lid, 0);
487  if (dt) {
488  *pid=lid;
489  return dt;
490  }
491  }
492  }
493  }
494 
495  id>>=4;
496  t=t->parent;
497  }
498  return 0;
499 }
500 
501 
502 
504  uint32_t *pid)
505 {
506 
507  GWEN_IDMAP_HEX4_TABLE *t;
508  GWEN_IDMAP_HEX4 *xmap;
509  uint32_t id;
510 
511  xmap=(GWEN_IDMAP_HEX4 *)map->algoData;
512 
513  t=GWEN_IdMapHex4__GetFirstTable(xmap->table, &id);
514  if (t) {
515  *pid=id;
516  return GWEN_IdMapResult_Ok;
517  }
518 
520 }
521 
522 
523 
525  uint32_t *pid)
526 {
527  GWEN_IDMAP_HEX4_TABLE *t;
528  GWEN_IDMAP_HEX4 *xmap;
529  uint32_t id;
530 
531  xmap=(GWEN_IDMAP_HEX4 *)map->algoData;
532 
533  id=*pid;
534 
535  t=GWEN_IdMapHex4__GetTable(xmap->table, id);
536  assert(t);
537 
538  t=GWEN_IdMapHex4__GetNextTable(t, &id, 1);
539  if (t) {
540  *pid=id;
541  return GWEN_IdMapResult_Ok;
542  }
543 
545 }
546 
547 
548 
549 void GWEN_IdMapHex4__Dump(GWEN_IDMAP_HEX4_TABLE *tbl, FILE *f, int indent)
550 {
551  int i;
552 
553  for (i=0; i<16; i++) {
554  int j;
555 
556  if (tbl->ptrs[i]) {
557  for (j=0; j<indent; j++)
558  fprintf(f, " ");
559  fprintf(f, "Id: %01x Ptr: %p\n",
560  i, tbl->ptrs[i]);
561  if (!(tbl->isPtrTable))
562  GWEN_IdMapHex4__Dump(tbl->ptrs[i], f, indent+2);
563  }
564  }
565 }
566 
567 
568 
569 void GWEN_IdMapHex4_Dump(GWEN_IDMAP *map, FILE *f, int indent)
570 {
571  GWEN_IDMAP_HEX4 *xmap;
572 
573  xmap=(GWEN_IDMAP_HEX4 *)map->algoData;
574  GWEN_IdMapHex4__Dump(xmap->table, f, indent);
575 }
576 
577 
578 
579 
580 
581 
void GWEN_IdMap_Clear(GWEN_IDMAP *map)
Definition: idmap.c:136
GWEN_IDMAP_RESULT GWEN_IdMap_Remove(GWEN_IDMAP *map, uint32_t id)
Definition: idmap.c:89
GWEN_IDMAP_RESULT
Definition: idmap.h:40
uint32_t GWEN_IdMap_GetSize(const GWEN_IDMAP *map)
Definition: idmap.c:128
GWEN_IDMAP_HEX4_TABLE * GWEN_IdMapHex4__GetNextTable(GWEN_IDMAP_HEX4_TABLE *t, uint32_t *pid, int incr)
Definition: idmap.c:452
struct GWEN_IDMAP GWEN_IDMAP
Definition: idmap.h:38
GWEN_IDMAP_HEX4_TABLE * GWEN_IdMapHex4__GetFirstTable(GWEN_IDMAP_HEX4_TABLE *t, uint32_t *pid)
Definition: idmap.c:418
void GWEN_IdMap_free(GWEN_IDMAP *map)
Definition: idmap.c:67
GWEN_IDMAP_RESULT GWEN_IdMap_GetNext(const GWEN_IDMAP *map, uint32_t *pid)
Definition: idmap.c:118
#define GWEN_FREE_OBJECT(varname)
Definition: memory.h:61
GWEN_IDMAP_RESULT GWEN_IdMap_GetFirst(const GWEN_IDMAP *map, uint32_t *pid)
Definition: idmap.c:108
void GWEN_IdMap_Dump(GWEN_IDMAP *map, FILE *f, int indent)
Definition: idmap.c:155
GWEN_IDMAP * GWEN_IdMap_new(GWEN_IDMAP_ALGO algo)
Definition: idmap.c:45
#define GWEN_LOGDOMAIN
Definition: logger.h:35
GWEN_IDMAP_HEX4_TABLE * GWEN_IdMapHex4Map_new(GWEN_IDMAP_HEX4_TABLE *p, int isPtrTable)
Definition: idmap.c:204
void * GWEN_IdMapHex4_Find(GWEN_IDMAP *map, uint32_t id)
Definition: idmap.c:336
GWEN_IDMAP_RESULT GWEN_IdMapHex4_FindNext(const GWEN_IDMAP *map, uint32_t *pid)
Definition: idmap.c:524
#define GWEN_NEW_OBJECT(typ, varname)
Definition: memory.h:55
void GWEN_IdMapHex4_free(GWEN_IDMAP *map)
Definition: idmap.c:193
GWEN_IDMAP_ALGO
Definition: idmap.h:47
GWEN_IDMAP_RESULT GWEN_IdMap_Insert(GWEN_IDMAP *map, uint32_t id, void *ptr)
Definition: idmap.c:77
#define DBG_ERROR(dbg_logger, format, args...)
Definition: debug.h:97
void * GWEN_IdMap_Find(GWEN_IDMAP *map, uint32_t id)
Definition: idmap.c:99
GWEN_IDMAP_RESULT GWEN_IdMapHex4_Insert(GWEN_IDMAP *map, uint32_t id, void *ptr)
Definition: idmap.c:234
GWEN_IDMAP_HEX4_TABLE * GWEN_IdMapHex4__GetTable(GWEN_IDMAP_HEX4_TABLE *t, uint32_t id)
Definition: idmap.c:373
GWEN_IDMAP_RESULT GWEN_IdMapHex4_FindFirst(const GWEN_IDMAP *map, uint32_t *pid)
Definition: idmap.c:503
void GWEN_IdMapHex4__Dump(GWEN_IDMAP_HEX4_TABLE *tbl, FILE *f, int indent)
Definition: idmap.c:549
void GWEN_IdMapHex4_Extend(GWEN_IDMAP *map)
Definition: idmap.c:176
void GWEN_IdMapHex4Map_free(GWEN_IDMAP_HEX4_TABLE *t)
Definition: idmap.c:217
void GWEN_IdMapHex4_Dump(GWEN_IDMAP *map, FILE *f, int indent)
Definition: idmap.c:569