Server 0.0.1
HTTP/REST server implementation

include/class/class.h

Go to the documentation of this file.
00001 
00027 #ifndef __CLASS_CLASS_H__
00028 #define __CLASS_CLASS_H__
00029 
00030 #include <stdarg.h>
00031 #include <sys/types.h>
00032 #include <string.h>
00033 #include <assert.h>
00034 
00035 #include "class/interface.h"
00036 
00037 #ifndef _ISOC99_SOURCE
00038 #define _ISOC99_SOURCE
00039 #endif
00040 
00041 #define CLASS_MAGIC    0xFEFE
00042 
00043 #define CLASS(name)                      \
00044         struct c_##name;                     \
00045         typedef struct c_##name * name;      \
00046         extern struct class * const _##name; \
00047         struct c_##name
00048 
00049 #define EXTENDS(parent) \
00050         const char _[sizeof(struct c_##parent)]
00051 
00052 #define _NULL   NULL
00053 #define CREATE_CLASS(name,_parent,...)              \
00054         static struct class c_##name;                   \
00055         static class_ptr _classInit##name##_(void) {    \
00056                 c_##name.parent = _##_parent;               \
00057                 c_##name.init   = NULL;                     \
00058                 return &c_##name;                           \
00059         }                                               \
00060         static struct class c_##name = {                \
00061                 CLASS_MAGIC,                                \
00062                 NULL,                                       \
00063                 sizeof(struct c_##name),                    \
00064                 _classInit##name##_,                        \
00065                 INIT_IFACE_IMPL(__VA_ARGS__)                \
00066         }; struct class * const _##name = &c_##name
00067 
00068 #define INIT_CLASS(class)                       ((class)->init? (class)->init() : (class))
00069 #define GET_CLASS(object)                       (INIT_CLASS(*(class_ptr *)((void*)(object) - sizeof(void*))))
00070 #define IFACE_GET(class,iface)          (interfaceGet(&((class)->impl),(iface)))
00071 #define HAS_PARENT(class)                       (NULL != ((class)->parent) &&  INIT_CLASS((class)->parent))
00072 
00073 #define IS_OBJECT(obj)                          ((GET_CLASS((obj)))->magic == CLASS_MAGIC)
00074 #define INSTANCE_OF(class,obj)          ((GET_CLASS((obj))) == _##class)
00075 
00080 #define _CALL(_class,_iface,method,...)                                         \
00081         do {                                                                        \
00082                 class_ptr class = _class;                                               \
00083                 iface = (struct i_##_iface *)IFACE_GET(class, &i_##_iface);             \
00084                 while ((NULL == iface || NULL == iface->method) && HAS_PARENT(class)) { \
00085                         class = class->parent;                                              \
00086                         iface = (struct i_##_iface *)IFACE_GET(class, &i_##_iface);         \
00087                 }                                                                       \
00088                 assert(NULL != iface->method);                                          \
00089         } while(0)
00090 
00091 #define CALL(object,_iface,method,...)                           \
00092         do {                                                         \
00093                 struct i_##_iface * iface;                               \
00094                 _CALL(GET_CLASS(object), _iface, method, ##__VA_ARGS__); \
00095                 iface->method(object, ##__VA_ARGS__);                    \
00096         } while(0)
00097 
00098 #define RETCALL(object,_iface,method,ret,...)                    \
00099         do {                                                         \
00100                 struct i_##_iface * iface;                               \
00101                 _CALL(GET_CLASS(object), _iface, method, ##__VA_ARGS__); \
00102                 ret = iface->method(object, ##__VA_ARGS__);              \
00103         } while(0)
00104 
00105 #define PARENTCALL(object,_iface,method,...)                    \
00106         do {                                                        \
00107                 struct i_##_iface * iface;                              \
00108                 class_ptr pc_class = GET_CLASS((object));               \
00109                 assert(HAS_PARENT(pc_class));                           \
00110                 _CALL(pc_class->parent, _iface, method, ##__VA_ARGS__); \
00111                 iface->method(object, ##__VA_ARGS__);                   \
00112         } while(0)
00113 
00114 
00115 struct class;
00116 typedef struct class * class_ptr;
00117 typedef class_ptr (* fptr_classInit)(void);
00118 struct class {
00119         const int         magic;
00120         class_ptr         parent;
00121         size_t            object_size;
00122         fptr_classInit    init;
00123         struct iface_impl impl;
00124 };
00125 
00126 #endif // __CLASS_CLASS_H__
00127 
00128 // vim: set ts=4 sw=4:
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines