gwenhywfar 5.12.0
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);
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
99void *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
128uint32_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) {
146 break;
148 default:
149 DBG_ERROR(GWEN_LOGDOMAIN, "Unknown algo %d", map->algo);
150 }
151}
152
153
154
155void 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
204GWEN_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
217void 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 }
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
336void *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
373GWEN_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
418GWEN_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
452GWEN_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
549void 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
569void 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
#define DBG_ERROR(dbg_logger, format,...)
Definition debug.h:97
GWEN_IDMAP_RESULT GWEN_IdMapHex4_FindNext(const GWEN_IDMAP *map, uint32_t *pid)
Definition idmap.c:524
GWEN_IDMAP_RESULT GWEN_IdMap_GetNext(const GWEN_IDMAP *map, uint32_t *pid)
Definition idmap.c:118
GWEN_IDMAP_HEX4_TABLE * GWEN_IdMapHex4__GetNextTable(GWEN_IDMAP_HEX4_TABLE *t, uint32_t *pid, int incr)
Definition idmap.c:452
void GWEN_IdMap_Dump(GWEN_IDMAP *map, FILE *f, int indent)
Definition idmap.c:155
void GWEN_IdMap_Clear(GWEN_IDMAP *map)
Definition idmap.c:136
void * GWEN_IdMap_Find(GWEN_IDMAP *map, uint32_t id)
Definition idmap.c:99
void GWEN_IdMap_free(GWEN_IDMAP *map)
Definition idmap.c:67
GWEN_IDMAP * GWEN_IdMap_new(GWEN_IDMAP_ALGO algo)
Definition idmap.c:45
void GWEN_IdMapHex4_Extend(GWEN_IDMAP *map)
Definition idmap.c:176
GWEN_IDMAP_RESULT GWEN_IdMapHex4_Insert(GWEN_IDMAP *map, uint32_t id, void *ptr)
Definition idmap.c:234
void GWEN_IdMapHex4Map_free(GWEN_IDMAP_HEX4_TABLE *t)
Definition idmap.c:217
GWEN_IDMAP_RESULT GWEN_IdMap_Insert(GWEN_IDMAP *map, uint32_t id, void *ptr)
Definition idmap.c:77
void GWEN_IdMapHex4_Dump(GWEN_IDMAP *map, FILE *f, int indent)
Definition idmap.c:569
void * GWEN_IdMapHex4_Find(GWEN_IDMAP *map, uint32_t id)
Definition idmap.c:336
GWEN_IDMAP_HEX4_TABLE * GWEN_IdMapHex4Map_new(GWEN_IDMAP_HEX4_TABLE *p, int isPtrTable)
Definition idmap.c:204
void GWEN_IdMapHex4_free(GWEN_IDMAP *map)
Definition idmap.c:193
GWEN_IDMAP_RESULT GWEN_IdMap_GetFirst(const GWEN_IDMAP *map, uint32_t *pid)
Definition idmap.c:108
void GWEN_IdMapHex4__Dump(GWEN_IDMAP_HEX4_TABLE *tbl, FILE *f, int indent)
Definition idmap.c:549
GWEN_IDMAP_RESULT GWEN_IdMapHex4_FindFirst(const GWEN_IDMAP *map, uint32_t *pid)
Definition idmap.c:503
GWEN_IDMAP_HEX4_TABLE * GWEN_IdMapHex4__GetFirstTable(GWEN_IDMAP_HEX4_TABLE *t, uint32_t *pid)
Definition idmap.c:418
uint32_t GWEN_IdMap_GetSize(const GWEN_IDMAP *map)
Definition idmap.c:128
GWEN_IDMAP_RESULT GWEN_IdMap_Remove(GWEN_IDMAP *map, uint32_t id)
Definition idmap.c:89
GWEN_IDMAP_HEX4_TABLE * GWEN_IdMapHex4__GetTable(GWEN_IDMAP_HEX4_TABLE *t, uint32_t id)
Definition idmap.c:373
GWEN_IDMAP_RESULT
Definition idmap.h:40
@ GWEN_IdMapResult_Ok
Definition idmap.h:41
@ GWEN_IdMapResult_NotFound
Definition idmap.h:43
struct GWEN_IDMAP GWEN_IDMAP
Definition idmap.h:38
GWEN_IDMAP_ALGO
Definition idmap.h:47
@ GWEN_IdMapAlgo_Unknown
Definition idmap.h:48
@ GWEN_IdMapAlgo_Hex4
Definition idmap.h:49
#define GWEN_LOGDOMAIN
Definition logger.h:35
#define GWEN_FREE_OBJECT(varname)
Definition memory.h:61
#define GWEN_NEW_OBJECT(typ, varname)
Definition memory.h:55