1 /***************************************************************************
2  $RCSfile$
3                              -------------------
4     cvs         : $Id$
5     begin       : Sun Dec 05 2003
6     copyright   : (C) 2003 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 #ifndef GWENHYWFAR_INHERIT_H
29 #define GWENHYWFAR_INHERIT_H
30 
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34 typedef struct GWEN_INHERITDATA GWEN_INHERITDATA;
35 #ifdef __cplusplus
36 }
37 #endif
38 
39 
40 #include <gwenhywfar/misc.h>
41 #include <gwenhywfar/gwenhywfarapi.h>
42 
43 
44 #ifdef __cplusplus
45 extern "C" {
46 #endif
47 
48 
49 /** @defgroup GWEN_MACRO_INHERIT Macros For Typesafe Inheritance
50  *
51  */
52 /*@{*/
53 typedef void GWENHYWFAR_CB(*GWEN_INHERIT_FREEDATAFN)(void *baseData,
54                                                      void *data);
55 
56 GWEN_LIST_FUNCTION_LIB_DEFS(GWEN_INHERITDATA, GWEN_InheritData, GWENHYWFAR_API)
57 /* No trailing semicolon because this is a macro call */
58 
59 GWENHYWFAR_API
60 GWEN_INHERITDATA *GWEN_InheritData_new(const char *t,
61                                        uint32_t id,
62                                        void *data,
63                                        void *baseData,
64                                        GWEN_INHERIT_FREEDATAFN fn);
65 GWENHYWFAR_API
66 void GWEN_InheritData_free(GWEN_INHERITDATA *d);
67 
68 GWENHYWFAR_API
69 void GWEN_InheritData_freeData(GWEN_INHERITDATA *d);
70 
71 GWENHYWFAR_API
72 void GWEN_InheritData_freeAllData(GWEN_INHERITDATA *d);
73 
74 GWENHYWFAR_API
75 void GWEN_InheritData_clear(GWEN_INHERITDATA *d);
76 
77 GWENHYWFAR_API
78 const char *GWEN_InheritData_GetTypeName(const GWEN_INHERITDATA *d);
79 
80 GWENHYWFAR_API
81 uint32_t GWEN_InheritData_GetId(const GWEN_INHERITDATA *d);
82 
83 GWENHYWFAR_API
84 void *GWEN_InheritData_GetData(const GWEN_INHERITDATA *d);
85 
86 GWENHYWFAR_API
87 GWEN_INHERIT_FREEDATAFN
88 GWEN_InheritData_GetFreeDataFn(const GWEN_INHERITDATA *d);
89 
90 GWENHYWFAR_API
91 uint32_t GWEN_Inherit_MakeId(const char *typeName);
92 
93 GWENHYWFAR_API
94 void *GWEN_Inherit_FindData(GWEN_INHERITDATA_LIST *l,
95                             uint32_t id,
96                             int wantCreate);
97 
98 GWENHYWFAR_API
99 GWEN_INHERITDATA *GWEN_Inherit_FindEntry(GWEN_INHERITDATA_LIST *l,
100                                          uint32_t id,
101                                          int wantCreate);
102 
103 /** @name Macros To Be Used In Inherited Classes - Header Files
104  *
105  */
106 /*@{*/
107 /**
108  * Use this macro inside the struct which you want to make inheritable.
109  * This macro defines some new elements for the struct for administration
110  * of inheritance.
111  */
112 #define GWEN_INHERIT_ELEMENT(t) \
113   GWEN_INHERITDATA_LIST *INHERIT__list;
114 
115 /**
116  * Use this macro in the header file of the base class. This defines
117  * the prototypes of some inheritance functions. This macro should
118  * be used in libraries with the __declspec(dllexport) as the @c
119  * decl argument.
120  *
121  * You should not care about these functions here, since you should not use
122  * them directly. Please use @ref GWEN_INHERIT_GETDATA and
123  * @ref GWEN_INHERIT_SETDATA instead.
124  */
125 #define GWEN_INHERIT_FUNCTION_LIB_DEFS(t, decl) \
126   decl void t##__INHERIT_SETDATA(t *element, \
127                                  const char *typeName,\
128                                  uint32_t id,\
129                                  void *data,\
130                                  GWEN_INHERIT_FREEDATAFN f);\
131   decl int t##__INHERIT_ISOFTYPE(const t *element, uint32_t id);\
132   decl GWEN_INHERITDATA_LIST *t##__INHERIT_GETLIST(const t *element);\
133   decl void t##__INHERIT_UNLINK(t *element, \
134                                 const char *typeName,\
135                                 uint32_t id);
136 
137 /**
138  * Use this macro in the header file of the base class. This defines
139  * the prototypes of some inheritance functions. This macro should
140  * be used in applications, not in libraries. In libraries please
141  * use the macro @ref GWEN_INHERIT_FUNCTION_LIB_DEFS.
142  *
143  * You should not care about these functions here, since you should not use
144  * them directly. Please use @ref GWEN_INHERIT_GETDATA and
145  * @ref GWEN_INHERIT_SETDATA instead.
146  */
147 #define GWEN_INHERIT_FUNCTION_DEFS(t) \
148   GWEN_INHERIT_FUNCTION_LIB_DEFS(t, GWEN_DUMMY_EMPTY_ARG)
149 
150 /*@}*/
151 
152 
153 /** @name Macros To Be Used In Inherited Classes - C Files
154  *
155  */
156 /*@{*/
157 /**
158  * Use this macro in the C file of the base class. It defines the
159  * implementations of the inheritance functions. This macro MUST be
160  * placed after the include statement which includes the classes header
161  * file.
162  */
163 #define GWEN_INHERIT_FUNCTIONS(t) \
164   GWEN_INHERITDATA_LIST *t##__INHERIT_GETLIST(const t *element) {\
165   assert(element);\
166   return element->INHERIT__list;\
167   }\
168   \
169   void t##__INHERIT_SETDATA(t *element, \
170                             const char *typeName,\
171                             uint32_t id,\
172                             void *data,\
173                             GWEN_INHERIT_FREEDATAFN f) {\
174   GWEN_INHERITDATA *d;\
175   void *p;\
176     \
177     assert(element);\
178     assert(element->INHERIT__list);\
179     \
180     p=GWEN_Inherit_FindData(element->INHERIT__list, id, 1);\
181     if (p) {\
182       fprintf(stderr,\
183               "ERROR: Type \"%s\" already inherits base type\n",\
184               typeName);\
185       abort();\
186     }\
187     d=GWEN_InheritData_new(typeName, id, data, (void*)element, f);\
188     GWEN_InheritData_List_Insert(d, element->INHERIT__list);\
189   }\
190   \
191   int t##__INHERIT_ISOFTYPE(const t *element, uint32_t id) {\
192     assert(element);\
193     assert(element->INHERIT__list);\
194   \
195     return (GWEN_Inherit_FindData(element->INHERIT__list, id, 1)!=0);\
196   }\
197   \
198   void t##__INHERIT_UNLINK(t *element, \
199                            const char *typeName,\
200                            uint32_t id) {\
201     GWEN_INHERITDATA *d;\
202     \
203     assert(element);\
204     assert(element->INHERIT__list);\
205     \
206     d=GWEN_Inherit_FindEntry(element->INHERIT__list, id, 1);\
207     if (!d) {\
208       fprintf(stderr, \
209               "ERROR: Type \"%s\" does not inherit base type\n",\
210               typeName);\
211       abort();\
212     }\
213     GWEN_InheritData_clear(d);\
214     GWEN_InheritData_List_Del(d);\
215     GWEN_InheritData_free(d);\
216   }
217 
218 /**
219  * Use this macro in your C file in constructor functions for the base
220  * class. This macro initializes the elements defined by the macro
221  * @ref GWEN_INHERIT_ELEMENT.
222  */
223 #define GWEN_INHERIT_INIT(t, element) {\
224     assert(element);\
225     element->INHERIT__list=GWEN_InheritData_List_new();\
226   }
227 
228 
229 /**
230  * Use this macro in your C file in destructor functions for the base
231  * class. This macro deinitializes the elements defined by the macro
232  * @ref GWEN_INHERIT_ELEMENT. This should be the first instruction in that
233  * function, because it also gives inheriting classes the opportunity to
234  * free their own data associated with the given element. It causes the
235  * least problems if inheriting classes free their data before the base
236  * class does.
237  */
238 #define GWEN_INHERIT_FINI(t, element) {\
239     GWEN_INHERITDATA *inherit__data;\
240     \
241     assert(element);\
242     assert(element->INHERIT__list);\
243     \
244     while( (inherit__data=GWEN_InheritData_List_First(element->INHERIT__list)) ) {\
245       GWEN_InheritData_freeData(inherit__data); \
246       GWEN_InheritData_List_Del(inherit__data); \
247       GWEN_InheritData_free(inherit__data); \
248     } \
249     GWEN_InheritData_List_free(element->INHERIT__list);\
250   }
251 
252 /*@}*/
253 
254 /** @name Macros To Be Used In Inheriting Classes
255  *
256  */
257 /*@{*/
258 /**
259  * Use this in the C file of inheriting classes. It initializes a global
260  * variable with a hash of the inheriting type name. This is used to speed
261  * up inheritance functions. This variable will be filled with a value
262  * upon the first invocation of the macro @ref GWEN_INHERIT_SETDATA.
263  */
264 #define GWEN_INHERIT(bt, t) \
265   uint32_t t##__INHERIT_ID=0;
266 
267 /**
268  * This macros returns the private data of an inheriting class associated
269  * with an element of its base class.
270  */
271 #define GWEN_INHERIT_GETDATA(bt, t, element) \
272   ((t*)GWEN_Inherit_FindData(bt##__INHERIT_GETLIST(element),t##__INHERIT_ID,0))
273 
274 /**
275  * This macro sets the private data of an inheriting class associated
276  * with an element of its base class. The last argument is a pointer to a
277  * function which frees the associated data. That function will be called
278  * when the element of the base class given is freed or new data is to be
279  * associated with the element.
280  * The prototype of that function is this:
281  * @code
282  * typedef void (*function)(void *baseData, void *data);
283  * @endcode
284  * Please note that the argument to that function is a pointer to the
285  * base type element. If you want to get the private data associated with
286  * the base type element (and you probably do) you must call
287  * @ref GWEN_INHERIT_GETDATA.
288  * Every time the macro @ref GWEN_INHERIT_SETDATA is used the previously
289  * associated data will be freed by calling the function whose prototype
290  * you've just learned.
291  */
292 #define GWEN_INHERIT_SETDATA(bt, t, element, data, fn) {\
293     if (!t##__INHERIT_ID)\
294       t##__INHERIT_ID=GWEN_Inherit_MakeId(__STRING(t));\
295     bt##__INHERIT_SETDATA(element, __STRING(t), t##__INHERIT_ID, data, fn);\
296   }
297 
298 /**
299  * This macro checks whether the given element is of the given type.
300  * @return !=0 if the pointer is of the expected type, 0 otherwise
301  * @param bt base type
302  * @param t derived type
303  * @param element pointer which is to be checked
304  */
305 #define GWEN_INHERIT_ISOFTYPE(bt, t, element) \
306   ((bt##__INHERIT_ISOFTYPE(element,\
307                            ((t##__INHERIT_ID==0)?\
308                             ((t##__INHERIT_ID=GWEN_Inherit_MakeId(__STRING(t)))):\
309                             t##__INHERIT_ID)))?1:0)
310 
311 /**
312  * This macro gives up the inheritance for the given type. After this
313  * macro has been executed there is no link left between the type and
314  * its base type.
315  * @param bt base type
316  * @param t derived type
317  */
318 #define GWEN_INHERIT_UNLINK(bt, t, element) {\
319     if (!t##__INHERIT_ID)\
320       t##__INHERIT_ID=GWEN_Inherit_MakeId(__STRING(t));\
321     bt##__INHERIT_UNLINK(element, __STRING(t), t##__INHERIT_ID);\
322   }
323 
324 /*@}*/
325 
326 /*@}*/ /* defgroup */
327 
328 
329 #ifdef __cplusplus
330 }
331 #endif
332 
333 
334 
335 #endif /* GWENHYWFAR_INHERIT_P_H */
336 
337 
338 
339