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