1 /***************************************************************************
2     begin       : Mon Mar 01 2004
3     copyright   : (C) 2004-2010 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 #ifndef GWENHYWFAR_IDMAP_H
26 #define GWENHYWFAR_IDMAP_H
27 
28 
29 #include <gwenhywfar/types.h>
30 
31 #include <stdio.h>
32 
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
36 
37 
38 typedef struct GWEN_IDMAP GWEN_IDMAP;
39 
40 typedef enum {
41   GWEN_IdMapResult_Ok=0,
42   GWEN_IdMapResult_NoFit,
43   GWEN_IdMapResult_NotFound
44 } GWEN_IDMAP_RESULT;
45 
46 
47 typedef enum {
48   GWEN_IdMapAlgo_Unknown=0,
49   GWEN_IdMapAlgo_Hex4
50 } GWEN_IDMAP_ALGO;
51 
52 
53 /** @name Macros for Typesafe ID maps
54  *
55  */
56 /*@{*/
57 #ifndef GWEN_DUMMY_EMPTY_ARG
58 /** Necessary for MSVC compiler because it does not accept a left-out
59     macro argument. */
60 # define GWEN_DUMMY_EMPTY_ARG
61 #endif
62 
63 
64 #define GWEN_IDMAP_FUNCTION_LIB_DEFS(t, pr, decl) \
65   typedef GWEN_IDMAP t##_IDMAP;                                       \
66                                                                       \
67   decl t##_IDMAP *pr##_IdMap_new(GWEN_IDMAP_ALGO algo);               \
68   decl void pr##_IdMap_free(t##_IDMAP *l);                            \
69   decl void pr##_IdMap_freeAll(t##_IDMAP *l);                         \
70   decl void pr##_IdMap_FreeItems(t##_IDMAP *l);                       \
71   decl GWEN_IDMAP_RESULT pr##_IdMap_Insert(t##_IDMAP *l,              \
72                                            uint32_t id,       \
73                                            t* ptr);                   \
74   decl GWEN_IDMAP_RESULT pr##_IdMap_Remove(t##_IDMAP *l,              \
75                                            uint32_t id);      \
76   decl t* pr##_IdMap_Find(t##_IDMAP *l, uint32_t id);         \
77   decl GWEN_IDMAP_RESULT pr##_IdMap_GetFirst(const t##_IDMAP *map,    \
78                                               uint32_t *pid); \
79   decl GWEN_IDMAP_RESULT pr##_IdMap_GetNext(const t##_IDMAP *map,     \
80                                              uint32_t *pid);  \
81   decl uint32_t pr##_IdMap_GetSize(const GWEN_IDMAP *map);    \
82   decl void pr##_IdMap_Clear(GWEN_IDMAP *l);
83 
84 
85 #define GWEN_IDMAP_FUNCTION_DEFS(t, pr) \
86   GWEN_IDMAP_FUNCTION_LIB_DEFS(t, pr, GWEN_DUMMY_EMPTY_ARG)
87 
88 
89 #define GWEN_IDMAP_FUNCTIONS(t, pr) \
90   t##_IDMAP *pr##_IdMap_new(GWEN_IDMAP_ALGO algo) {                  \
91     return (t##_IDMAP*)GWEN_IdMap_new(algo);                         \
92   }                                                                  \
93                                                                      \
94   void pr##_IdMap_free(t##_IDMAP *l) {                               \
95     GWEN_IdMap_free((GWEN_IDMAP*)l);                                 \
96   }                                                                  \
97                                                                      \
98   void pr##_IdMap_freeAll(t##_IDMAP *l) {                            \
99     GWEN_IDMAP_RESULT res;                                           \
100     uint32_t id;                                             \
101                                  \
102     res=pr##_IdMap_GetFirst(l, &id);                                 \
103     while(res==GWEN_IdMapResult_Ok) {                                \
104       uint32_t nextId;                                       \
105       t *ptr;                                                        \
106                      \
107       nextId=id;                 \
108       res=pr##_IdMap_GetNext(l, &nextId);                            \
109       ptr=pr##_IdMap_Find(l, id);                                    \
110       if (ptr)                                                       \
111   pr##_free(ptr);                                              \
112       id=nextId;                                                     \
113     }                                                                \
114     pr##_IdMap_free(l);                                              \
115   }                                                                  \
116                                                                      \
117   void pr##_IdMap_FreeItems(t##_IDMAP *l) {                          \
118     GWEN_IDMAP_RESULT res;                                           \
119     uint32_t id;                                             \
120                                  \
121     res=pr##_IdMap_GetFirst(l, &id);                                 \
122     while(res==GWEN_IdMapResult_Ok) {                                \
123       uint32_t nextId;                                       \
124       t *ptr;                                                        \
125                                                                      \
126       nextId=id;                                                     \
127       res=pr##_IdMap_GetNext(l, &nextId);                            \
128       ptr=pr##_IdMap_Find(l, id);                                    \
129       if (ptr)                                                       \
130   pr##_free(ptr);                                              \
131       pr##_IdMap_Remove(l, id);                    \
132       id=nextId;                                                     \
133     }                                                                \
134   }                                                                  \
135                                                                      \
136   GWEN_IDMAP_RESULT pr##_IdMap_Insert(t##_IDMAP *l,                  \
137                                       uint32_t id,           \
138                                       t* ptr) {                      \
139     return GWEN_IdMap_Insert((GWEN_IDMAP*)l, id, (void*) ptr);       \
140   }                                                                  \
141                                                                      \
142   GWEN_IDMAP_RESULT pr##_IdMap_Remove(t##_IDMAP *l,                  \
143                                       uint32_t id){          \
144     return GWEN_IdMap_Remove((GWEN_IDMAP*)l, id);                    \
145   }                                                                  \
146 \
147   t* pr##_IdMap_Find(t##_IDMAP *l, uint32_t id) {            \
148     return GWEN_IdMap_Find((GWEN_IDMAP*)l, id);                      \
149   }                                                                  \
150                                                                      \
151   GWEN_IDMAP_RESULT pr##_IdMap_GetFirst(const t##_IDMAP *l,          \
152                                         uint32_t *pid) {     \
153     return GWEN_IdMap_GetFirst((const GWEN_IDMAP*)l, pid);           \
154   }                                                                  \
155                                                                      \
156   GWEN_IDMAP_RESULT pr##_IdMap_GetNext(const t##_IDMAP *l,           \
157                                        uint32_t *pid) {      \
158     return GWEN_IdMap_GetNext((const GWEN_IDMAP*)l, pid);            \
159   }                                                                  \
160                                                                      \
161   uint32_t pr##_IdMap_GetSize(const GWEN_IDMAP *l) {         \
162     return GWEN_IdMap_GetSize((const GWEN_IDMAP*)l);                 \
163   }                                                                  \
164                                                                      \
165   void pr##_IdMap_Clear(GWEN_IDMAP *l) {                             \
166     GWEN_IdMap_Clear((GWEN_IDMAP*)l);                                \
167   }
168 /*@}*/
169 
170 
171 
172 GWENHYWFAR_API
173 GWEN_IDMAP *GWEN_IdMap_new(GWEN_IDMAP_ALGO algo);
174 
175 GWENHYWFAR_API
176 void GWEN_IdMap_free(GWEN_IDMAP *map);
177 
178 GWENHYWFAR_API
179 GWEN_IDMAP_RESULT GWEN_IdMap_Insert(GWEN_IDMAP *map,
180                                     uint32_t id,
181                                     void *ptr);
182 
183 GWENHYWFAR_API
184 GWEN_IDMAP_RESULT GWEN_IdMap_Remove(GWEN_IDMAP *map,
185                                     uint32_t id);
186 
187 GWENHYWFAR_API
188 void *GWEN_IdMap_Find(GWEN_IDMAP *map, uint32_t id);
189 
190 
191 /**
192  * Return the first id in the map.
193  * @param map map to browse
194  * @param pid pointer to a variable to receive the first id in the map.
195  *   Upon return this variable will be updated to the first id in the map if
196  *   the result is @ref GWEN_IdMapResult_Ok.
197  */
198 GWENHYWFAR_API
199 GWEN_IDMAP_RESULT GWEN_IdMap_GetFirst(const GWEN_IDMAP *map,
200                                       uint32_t *pid);
201 
202 /**
203  * Return the next id in the map.
204  * @param map map to browse
205  * @param pid pointer to the id retrieved via @ref GWEN_IdMap_GetFirst.
206  *   Upon return this variable will be updated to the next id in the map if
207  *   the result is @ref GWEN_IdMapResult_Ok.
208  */
209 GWENHYWFAR_API
210 GWEN_IDMAP_RESULT GWEN_IdMap_GetNext(const GWEN_IDMAP *map,
211                                      uint32_t *pid);
212 
213 GWENHYWFAR_API
214 uint32_t GWEN_IdMap_GetSize(const GWEN_IDMAP *map);
215 
216 GWENHYWFAR_API
217 void GWEN_IdMap_Clear(GWEN_IDMAP *map);
218 
219 
220 GWENHYWFAR_API
221 void GWEN_IdMap_Dump(GWEN_IDMAP *map, FILE *f, int indent);
222 
223 
224 #ifdef __cplusplus
225 }
226 #endif
227 
228 
229 #endif
230 
231