242 lines
6.9 KiB
C
242 lines
6.9 KiB
C
#if !defined(_RTTI_TYPEINFO_H_)
|
|
|
|
#define _RTTI_TYPEINFO_H_ 1
|
|
|
|
#include <stdarg.h>
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <sys/types.h>
|
|
|
|
#define RTTI_MAGIC (0x5254544949545452)
|
|
|
|
#define var void*
|
|
|
|
#define RTTI_SIZE_ROUNDUP(sz) \
|
|
((((sz + sizeof(void*) - 1)) / (sizeof(void*))) * sizeof(void*))
|
|
|
|
#define RTTI_OBJ_HEADER_SIZE RTTI_SIZE_ROUNDUP(sizeof(meta_obj_t))
|
|
|
|
/** Object format
|
|
**
|
|
** +=====================+===================+===================+
|
|
** | <private data> | <object header> | <- public data > |
|
|
** +=====================+===================+===================+
|
|
**
|
|
**/
|
|
#define RTTI_OBJ_TO_DATA(T, obj) ((T*)((obj)->data))
|
|
#define RTTI_DATA_TO_OBJ(v) \
|
|
(((v) == NULL) ? NULL : ((meta_obj_t*)(((char*)v) - RTTI_OBJ_HEADER_SIZE)))
|
|
#define RTTI_OBJ_TO_PRIV(obj) ((obj)->privdata)
|
|
|
|
#define RTTI_GET_METHOD(result, obj, intf, method) \
|
|
do { \
|
|
typeinfo_t* type_ = NULL; \
|
|
\
|
|
(result) = NULL; \
|
|
\
|
|
if ((obj) == NULL) { \
|
|
break; \
|
|
} \
|
|
\
|
|
type_ = obj->type; \
|
|
if (type_ == NULL) { \
|
|
break; \
|
|
} \
|
|
\
|
|
if (type_->interfaces.intf == NULL) { \
|
|
break; \
|
|
} \
|
|
\
|
|
(result) = type_->interfaces.intf->method; \
|
|
} while (0)
|
|
|
|
#define RTTI_OBJ_INVALID(obj) (((obj) == NULL) || ((obj)->magic != RTTI_MAGIC))
|
|
|
|
struct meta_obj_;
|
|
struct typeinfo_;
|
|
|
|
typedef struct meta_obj_ meta_obj_t;
|
|
typedef struct typeinfo_ typeinfo_t;
|
|
|
|
/* calculate the size of data */
|
|
typedef size_t (*datasize_fn_t)(va_list);
|
|
|
|
/* object life cycle */
|
|
typedef int (*obj_init_fn_t)(meta_obj_t*, va_list);
|
|
typedef void (*obj_destroy_fn_t)(meta_obj_t*);
|
|
|
|
/* lock/unlock */
|
|
enum {
|
|
RTTI_LOCK_READ = 0,
|
|
RTTI_LOCK_WRITE
|
|
};
|
|
|
|
typedef int (*lock_fn_t)(meta_obj_t*, uint64_t);
|
|
typedef void (*unlock_fn_t)(meta_obj_t*);
|
|
|
|
typedef struct {
|
|
lock_fn_t lock;
|
|
unlock_fn_t unlock;
|
|
} intf_lock_t;
|
|
|
|
/* convert to string */
|
|
typedef char* (*to_string_fn_t)(meta_obj_t*, va_list);
|
|
|
|
typedef struct {
|
|
to_string_fn_t toString;
|
|
} intf_tostring_t;
|
|
|
|
/* iterator function */
|
|
|
|
#define RTTI_ITER_NO_DATA (0)
|
|
#define RTTI_ITER_OK (1)
|
|
|
|
typedef struct {
|
|
meta_obj_t* obj;
|
|
var data;
|
|
} iterator_t;
|
|
|
|
typedef int (*iter_make_fn_t)(iterator_t*, va_list);
|
|
typedef int (*iter_next_fn_t)(iterator_t*, void**);
|
|
typedef int (*iter_reset_fn_t)(iterator_t*);
|
|
typedef void (*iter_destroy_fn_t)(iterator_t*);
|
|
|
|
typedef struct {
|
|
iter_make_fn_t make;
|
|
iter_next_fn_t next;
|
|
iter_reset_fn_t reset;
|
|
iter_destroy_fn_t destroy;
|
|
} intf_iterator_t;
|
|
|
|
/* reference and deref */
|
|
typedef int32_t (*reference_fn_t)(meta_obj_t*);
|
|
typedef void (*dereference_fn_t)(meta_obj_t*);
|
|
|
|
typedef struct {
|
|
reference_fn_t reference;
|
|
dereference_fn_t dereference;
|
|
} intf_reference_t;
|
|
|
|
/* hash */
|
|
|
|
typedef int32_t (*hash_fn_t)(meta_obj_t*);
|
|
|
|
typedef struct {
|
|
hash_fn_t hash;
|
|
} intf_hash_t;
|
|
|
|
/* length */
|
|
typedef int64_t (*length_fn_t)(meta_obj_t*);
|
|
|
|
typedef struct {
|
|
length_fn_t length;
|
|
} intf_length_t;
|
|
|
|
/* set */
|
|
typedef int (*bit_test_fn_t)(meta_obj_t*, unsigned long);
|
|
typedef int (*bit_set_fn_t)(meta_obj_t*, unsigned long);
|
|
typedef int (*bit_clr_fn_t)(meta_obj_t*, unsigned long);
|
|
typedef int (*bit_clrall_fn_t)(meta_obj_t*);
|
|
|
|
typedef struct {
|
|
bit_test_fn_t test;
|
|
bit_set_fn_t set;
|
|
bit_clr_fn_t clr;
|
|
bit_clrall_fn_t clrall;
|
|
} intf_bitmap_t;
|
|
|
|
/* key to val table */
|
|
|
|
typedef int (*key_add_fn_t)(meta_obj_t*, void*, void*);
|
|
typedef int (*key_del_fn_t)(meta_obj_t*, void*);
|
|
typedef uint64_t (*key_find_fn_t)(meta_obj_t*, void*, void**);
|
|
|
|
typedef struct {
|
|
key_add_fn_t add_key;
|
|
key_del_fn_t del_key;
|
|
key_find_fn_t find_key;
|
|
} intf_kv_t;
|
|
|
|
/* array API */
|
|
|
|
typedef int (*vstore_fn_t)(meta_obj_t*, void*);
|
|
typedef int (*vget_fn_t)(meta_obj_t*, int, void**);
|
|
typedef int (*vput_fn_t)(meta_obj_t*, int, void*);
|
|
typedef int (*vclear_fn_t)(meta_obj_t*, int);
|
|
|
|
typedef struct {
|
|
vstore_fn_t vstore;
|
|
vget_fn_t vget;
|
|
vput_fn_t vput;
|
|
vclear_fn_t vclear;
|
|
} intf_varray_t;
|
|
|
|
typedef struct {
|
|
intf_lock_t* lock;
|
|
intf_tostring_t* toString;
|
|
intf_iterator_t* iter;
|
|
intf_reference_t* reference;
|
|
intf_hash_t* hash;
|
|
intf_length_t* length;
|
|
intf_bitmap_t* bitmap;
|
|
intf_kv_t* kv;
|
|
intf_varray_t* varray;
|
|
} interface_table_t;
|
|
|
|
struct typeinfo_ {
|
|
char* name;
|
|
size_t privateSize;
|
|
datasize_fn_t dataSize;
|
|
obj_init_fn_t init;
|
|
obj_destroy_fn_t destroy;
|
|
interface_table_t interfaces;
|
|
};
|
|
|
|
struct meta_obj_ {
|
|
uint64_t magic;
|
|
typeinfo_t* type;
|
|
void* privdata;
|
|
void* data;
|
|
};
|
|
|
|
extern var makeInstance(typeinfo_t*, ...);
|
|
extern void destroy(var);
|
|
extern void destroy_(var, obj_destroy_fn_t);
|
|
extern int is_rtti_obj(var);
|
|
extern typeinfo_t* typeOf(var);
|
|
extern int instanceOf(var, typeinfo_t*);
|
|
|
|
extern int lock(var, uint64_t);
|
|
extern void unlock(var);
|
|
|
|
extern char* toString(var, ...);
|
|
|
|
extern int iter_make(iterator_t*, var, ...);
|
|
extern int iter_next(iterator_t*, void**);
|
|
extern int iter_reset(iterator_t*);
|
|
extern void iter_destroy(iterator_t*);
|
|
|
|
extern int32_t hash(var);
|
|
|
|
extern int64_t length(var);
|
|
|
|
extern int32_t reference(var);
|
|
extern void dereference(var);
|
|
|
|
extern int bit_test(var, unsigned long);
|
|
extern int bit_set(var, unsigned long);
|
|
extern int bit_clr(var, unsigned long);
|
|
extern int bit_clrall(var);
|
|
|
|
extern int key_add(var, void*, void*);
|
|
extern int key_del(var, void*);
|
|
extern int key_find(var, void*, void**);
|
|
|
|
extern int vstore(var, void*);
|
|
extern int vget(var, int, void**);
|
|
extern int vput(var, int, void*);
|
|
extern int vclear(var, int);
|
|
|
|
#endif
|