00001 #ifndef PROTON_OBJECT_H
00002 #define PROTON_OBJECT_H 1
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <proton/cid.h>
00026 #include <proton/types.h>
00027 #include <stdarg.h>
00028 #include <proton/type_compat.h>
00029 #include <stddef.h>
00030 #include <proton/import_export.h>
00031
00032 #ifdef __cplusplus
00033 extern "C" {
00034 #endif
00035
00036 typedef uintptr_t pn_handle_t;
00037 typedef intptr_t pn_shandle_t;
00038
00039 typedef struct pn_class_t pn_class_t;
00040 typedef struct pn_string_t pn_string_t;
00041 typedef struct pn_list_t pn_list_t;
00042 typedef struct pn_map_t pn_map_t;
00043 typedef struct pn_hash_t pn_hash_t;
00044 typedef void *(*pn_iterator_next_t)(void *state);
00045 typedef struct pn_iterator_t pn_iterator_t;
00046 typedef struct pn_record_t pn_record_t;
00047
00048 struct pn_class_t {
00049 const char *name;
00050 const pn_cid_t cid;
00051 void *(*newinst)(const pn_class_t *, size_t);
00052 void (*initialize)(void *);
00053 void (*incref)(void *);
00054 void (*decref)(void *);
00055 int (*refcount)(void *);
00056 void (*finalize)(void *);
00057 void (*free)(void *);
00058 const pn_class_t *(*reify)(void *);
00059 uintptr_t (*hashcode)(void *);
00060 intptr_t (*compare)(void *, void *);
00061 int (*inspect)(void *, pn_string_t *);
00062 };
00063
00064 PN_EXTERN extern const pn_class_t *PN_OBJECT;
00065 PN_EXTERN extern const pn_class_t *PN_VOID;
00066 PN_EXTERN extern const pn_class_t *PN_WEAKREF;
00067
00068 #define PN_CLASSDEF(PREFIX) \
00069 static void PREFIX ## _initialize_cast(void *object) { \
00070 PREFIX ## _initialize((PREFIX ## _t *) object); \
00071 } \
00072 \
00073 static void PREFIX ## _finalize_cast(void *object) { \
00074 PREFIX ## _finalize((PREFIX ## _t *) object); \
00075 } \
00076 \
00077 static uintptr_t PREFIX ## _hashcode_cast(void *object) { \
00078 uintptr_t (*fp)(PREFIX ## _t *) = PREFIX ## _hashcode; \
00079 if (fp) { \
00080 return fp((PREFIX ## _t *) object); \
00081 } else { \
00082 return (uintptr_t) object; \
00083 } \
00084 } \
00085 \
00086 static intptr_t PREFIX ## _compare_cast(void *a, void *b) { \
00087 intptr_t (*fp)(PREFIX ## _t *, PREFIX ## _t *) = PREFIX ## _compare; \
00088 if (fp) { \
00089 return fp((PREFIX ## _t *) a, (PREFIX ## _t *) b); \
00090 } else { \
00091 return (intptr_t) a - (intptr_t) b; \
00092 } \
00093 } \
00094 \
00095 static int PREFIX ## _inspect_cast(void *object, pn_string_t *str) { \
00096 int (*fp)(PREFIX ## _t *, pn_string_t *) = PREFIX ## _inspect; \
00097 if (fp) { \
00098 return fp((PREFIX ## _t *) object, str); \
00099 } else { \
00100 return pn_string_addf(str, "%s<%p>", #PREFIX, object); \
00101 } \
00102 } \
00103 \
00104 const pn_class_t *PREFIX ## __class(void) { \
00105 static const pn_class_t clazz = { \
00106 #PREFIX, \
00107 CID_ ## PREFIX, \
00108 pn_object_new, \
00109 PREFIX ## _initialize_cast, \
00110 pn_object_incref, \
00111 pn_object_decref, \
00112 pn_object_refcount, \
00113 PREFIX ## _finalize_cast, \
00114 pn_object_free, \
00115 pn_object_reify, \
00116 PREFIX ## _hashcode_cast, \
00117 PREFIX ## _compare_cast, \
00118 PREFIX ## _inspect_cast \
00119 }; \
00120 return &clazz; \
00121 } \
00122 \
00123 PREFIX ## _t *PREFIX ## _new(void) { \
00124 return (PREFIX ## _t *) pn_class_new(PREFIX ## __class(), \
00125 sizeof(PREFIX ## _t)); \
00126 }
00127
00128 #define PN_CLASS(PREFIX) { \
00129 #PREFIX, \
00130 CID_ ## PREFIX, \
00131 pn_object_new, \
00132 PREFIX ## _initialize, \
00133 pn_object_incref, \
00134 pn_object_decref, \
00135 pn_object_refcount, \
00136 PREFIX ## _finalize, \
00137 pn_object_free, \
00138 pn_object_reify, \
00139 PREFIX ## _hashcode, \
00140 PREFIX ## _compare, \
00141 PREFIX ## _inspect \
00142 }
00143
00144 #define PN_METACLASS(PREFIX) { \
00145 #PREFIX, \
00146 CID_ ## PREFIX, \
00147 PREFIX ## _new, \
00148 PREFIX ## _initialize, \
00149 PREFIX ## _incref, \
00150 PREFIX ## _decref, \
00151 PREFIX ## _refcount, \
00152 PREFIX ## _finalize, \
00153 PREFIX ## _free, \
00154 PREFIX ## _reify, \
00155 PREFIX ## _hashcode, \
00156 PREFIX ## _compare, \
00157 PREFIX ## _inspect \
00158 }
00159
00160 PN_EXTERN pn_cid_t pn_class_id(const pn_class_t *clazz);
00161 PN_EXTERN const char *pn_class_name(const pn_class_t *clazz);
00162 PN_EXTERN void *pn_class_new(const pn_class_t *clazz, size_t size);
00163 PN_EXTERN void *pn_class_incref(const pn_class_t *clazz, void *object);
00164 PN_EXTERN int pn_class_refcount(const pn_class_t *clazz, void *object);
00165 PN_EXTERN int pn_class_decref(const pn_class_t *clazz, void *object);
00166 PN_EXTERN void pn_class_free(const pn_class_t *clazz, void *object);
00167 PN_EXTERN const pn_class_t *pn_class_reify(const pn_class_t *clazz, void *object);
00168 PN_EXTERN uintptr_t pn_class_hashcode(const pn_class_t *clazz, void *object);
00169 PN_EXTERN intptr_t pn_class_compare(const pn_class_t *clazz, void *a, void *b);
00170 PN_EXTERN bool pn_class_equals(const pn_class_t *clazz, void *a, void *b);
00171 PN_EXTERN int pn_class_inspect(const pn_class_t *clazz, void *object, pn_string_t *dst);
00172
00173 PN_EXTERN uintptr_t pn_void_hashcode(void *object);
00174 PN_EXTERN intptr_t pn_void_compare(void *a, void *b);
00175 PN_EXTERN int pn_void_inspect(void *object, pn_string_t *dst);
00176
00177 PN_EXTERN void *pn_object_new(const pn_class_t *clazz, size_t size);
00178 PN_EXTERN const pn_class_t *pn_object_reify(void *object);
00179 PN_EXTERN void pn_object_incref(void *object);
00180 PN_EXTERN int pn_object_refcount(void *object);
00181 PN_EXTERN void pn_object_decref(void *object);
00182 PN_EXTERN void pn_object_free(void *object);
00183
00184 PN_EXTERN void *pn_incref(void *object);
00185 PN_EXTERN int pn_decref(void *object);
00186 PN_EXTERN int pn_refcount(void *object);
00187 PN_EXTERN void pn_free(void *object);
00188 PN_EXTERN const pn_class_t *pn_class(void* object);
00189 PN_EXTERN uintptr_t pn_hashcode(void *object);
00190 PN_EXTERN intptr_t pn_compare(void *a, void *b);
00191 PN_EXTERN bool pn_equals(void *a, void *b);
00192 PN_EXTERN int pn_inspect(void *object, pn_string_t *dst);
00193
00194 #define PN_REFCOUNT (0x1)
00195
00196 PN_EXTERN pn_list_t *pn_list(const pn_class_t *clazz, size_t capacity);
00197 PN_EXTERN size_t pn_list_size(pn_list_t *list);
00198 PN_EXTERN void *pn_list_get(pn_list_t *list, int index);
00199 PN_EXTERN void pn_list_set(pn_list_t *list, int index, void *value);
00200 PN_EXTERN int pn_list_add(pn_list_t *list, void *value);
00201 PN_EXTERN void *pn_list_pop(pn_list_t *list);
00202 PN_EXTERN ssize_t pn_list_index(pn_list_t *list, void *value);
00203 PN_EXTERN bool pn_list_remove(pn_list_t *list, void *value);
00204 PN_EXTERN void pn_list_del(pn_list_t *list, int index, int n);
00205 PN_EXTERN void pn_list_clear(pn_list_t *list);
00206 PN_EXTERN void pn_list_iterator(pn_list_t *list, pn_iterator_t *iter);
00207 PN_EXTERN void pn_list_minpush(pn_list_t *list, void *value);
00208 PN_EXTERN void *pn_list_minpop(pn_list_t *list);
00209
00210 #define PN_REFCOUNT_KEY (0x2)
00211 #define PN_REFCOUNT_VALUE (0x4)
00212
00213 PN_EXTERN pn_map_t *pn_map(const pn_class_t *key, const pn_class_t *value,
00214 size_t capacity, float load_factor);
00215 PN_EXTERN size_t pn_map_size(pn_map_t *map);
00216 PN_EXTERN int pn_map_put(pn_map_t *map, void *key, void *value);
00217 PN_EXTERN void *pn_map_get(pn_map_t *map, void *key);
00218 PN_EXTERN void pn_map_del(pn_map_t *map, void *key);
00219 PN_EXTERN pn_handle_t pn_map_head(pn_map_t *map);
00220 PN_EXTERN pn_handle_t pn_map_next(pn_map_t *map, pn_handle_t entry);
00221 PN_EXTERN void *pn_map_key(pn_map_t *map, pn_handle_t entry);
00222 PN_EXTERN void *pn_map_value(pn_map_t *map, pn_handle_t entry);
00223
00224 PN_EXTERN pn_hash_t *pn_hash(const pn_class_t *clazz, size_t capacity, float load_factor);
00225 PN_EXTERN size_t pn_hash_size(pn_hash_t *hash);
00226 PN_EXTERN int pn_hash_put(pn_hash_t *hash, uintptr_t key, void *value);
00227 PN_EXTERN void *pn_hash_get(pn_hash_t *hash, uintptr_t key);
00228 PN_EXTERN void pn_hash_del(pn_hash_t *hash, uintptr_t key);
00229 PN_EXTERN pn_handle_t pn_hash_head(pn_hash_t *hash);
00230 PN_EXTERN pn_handle_t pn_hash_next(pn_hash_t *hash, pn_handle_t entry);
00231 PN_EXTERN uintptr_t pn_hash_key(pn_hash_t *hash, pn_handle_t entry);
00232 PN_EXTERN void *pn_hash_value(pn_hash_t *hash, pn_handle_t entry);
00233
00234 PN_EXTERN pn_string_t *pn_string(const char *bytes);
00235 PN_EXTERN pn_string_t *pn_stringn(const char *bytes, size_t n);
00236 PN_EXTERN const char *pn_string_get(pn_string_t *string);
00237 PN_EXTERN size_t pn_string_size(pn_string_t *string);
00238 PN_EXTERN int pn_string_set(pn_string_t *string, const char *bytes);
00239 PN_EXTERN int pn_string_setn(pn_string_t *string, const char *bytes, size_t n);
00240 PN_EXTERN ssize_t pn_string_put(pn_string_t *string, char *dst);
00241 PN_EXTERN void pn_string_clear(pn_string_t *string);
00242 PN_EXTERN int pn_string_format(pn_string_t *string, const char *format, ...)
00243 #ifdef __GNUC__
00244 __attribute__ ((format (printf, 2, 3)))
00245 #endif
00246 ;
00247 PN_EXTERN int pn_string_vformat(pn_string_t *string, const char *format, va_list ap);
00248 PN_EXTERN int pn_string_addf(pn_string_t *string, const char *format, ...)
00249 #ifdef __GNUC__
00250 __attribute__ ((format (printf, 2, 3)))
00251 #endif
00252 ;
00253 PN_EXTERN int pn_string_vaddf(pn_string_t *string, const char *format, va_list ap);
00254 PN_EXTERN int pn_string_grow(pn_string_t *string, size_t capacity);
00255 PN_EXTERN char *pn_string_buffer(pn_string_t *string);
00256 PN_EXTERN size_t pn_string_capacity(pn_string_t *string);
00257 PN_EXTERN int pn_string_resize(pn_string_t *string, size_t size);
00258 PN_EXTERN int pn_string_copy(pn_string_t *string, pn_string_t *src);
00259
00260 PN_EXTERN pn_iterator_t *pn_iterator(void);
00261 PN_EXTERN void *pn_iterator_start(pn_iterator_t *iterator,
00262 pn_iterator_next_t next, size_t size);
00263 PN_EXTERN void *pn_iterator_next(pn_iterator_t *iterator);
00264
00265 #define PN_LEGCTX ((pn_handle_t) 0)
00266
00267 #define PN_HANDLE(name) \
00268 static char *_PN_HANDLE_ ## name = 0; \
00269 static pn_handle_t name = ((pn_handle_t) &_PN_HANDLE_ ## name);
00270
00271 PN_EXTERN pn_record_t *pn_record(void);
00272 PN_EXTERN void pn_record_def(pn_record_t *record, pn_handle_t key, const pn_class_t *clazz);
00273 PN_EXTERN bool pn_record_has(pn_record_t *record, pn_handle_t key);
00274 PN_EXTERN void *pn_record_get(pn_record_t *record, pn_handle_t key);
00275 PN_EXTERN void pn_record_set(pn_record_t *record, pn_handle_t key, void *value);
00276 PN_EXTERN void pn_record_clear(pn_record_t *record);
00277
00278 #ifdef __cplusplus
00279 }
00280 #endif
00281
00282 #endif