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 void* 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
00065
00066 PN_EXTERN extern const pn_class_t PN_OBJECT[];
00067 PN_EXTERN extern const pn_class_t PN_VOID[];
00068 PN_EXTERN extern const pn_class_t PN_WEAKREF[];
00069
00070 #define PN_CLASSDEF(PREFIX) \
00071 static void PREFIX ## _initialize_cast(void *object) { \
00072 PREFIX ## _initialize((PREFIX ## _t *) object); \
00073 } \
00074 \
00075 static void PREFIX ## _finalize_cast(void *object) { \
00076 PREFIX ## _finalize((PREFIX ## _t *) object); \
00077 } \
00078 \
00079 static uintptr_t PREFIX ## _hashcode_cast(void *object) { \
00080 uintptr_t (*fp)(PREFIX ## _t *) = PREFIX ## _hashcode; \
00081 if (fp) { \
00082 return fp((PREFIX ## _t *) object); \
00083 } else { \
00084 return (uintptr_t) object; \
00085 } \
00086 } \
00087 \
00088 static intptr_t PREFIX ## _compare_cast(void *a, void *b) { \
00089 intptr_t (*fp)(PREFIX ## _t *, PREFIX ## _t *) = PREFIX ## _compare; \
00090 if (fp) { \
00091 return fp((PREFIX ## _t *) a, (PREFIX ## _t *) b); \
00092 } else { \
00093 return (intptr_t) a - (intptr_t) b; \
00094 } \
00095 } \
00096 \
00097 static int PREFIX ## _inspect_cast(void *object, pn_string_t *str) { \
00098 int (*fp)(PREFIX ## _t *, pn_string_t *) = PREFIX ## _inspect; \
00099 if (fp) { \
00100 return fp((PREFIX ## _t *) object, str); \
00101 } else { \
00102 return pn_string_addf(str, "%s<%p>", #PREFIX, object); \
00103 } \
00104 } \
00105 \
00106 const pn_class_t *PREFIX ## __class(void) { \
00107 static const pn_class_t clazz = { \
00108 #PREFIX, \
00109 CID_ ## PREFIX, \
00110 pn_object_new, \
00111 PREFIX ## _initialize_cast, \
00112 pn_object_incref, \
00113 pn_object_decref, \
00114 pn_object_refcount, \
00115 PREFIX ## _finalize_cast, \
00116 pn_object_free, \
00117 pn_object_reify, \
00118 PREFIX ## _hashcode_cast, \
00119 PREFIX ## _compare_cast, \
00120 PREFIX ## _inspect_cast \
00121 }; \
00122 return &clazz; \
00123 } \
00124 \
00125 PREFIX ## _t *PREFIX ## _new(void) { \
00126 return (PREFIX ## _t *) pn_class_new(PREFIX ## __class(), \
00127 sizeof(PREFIX ## _t)); \
00128 }
00129
00130 #define PN_CLASS(PREFIX) { \
00131 #PREFIX, \
00132 CID_ ## PREFIX, \
00133 pn_object_new, \
00134 PREFIX ## _initialize, \
00135 pn_object_incref, \
00136 pn_object_decref, \
00137 pn_object_refcount, \
00138 PREFIX ## _finalize, \
00139 pn_object_free, \
00140 pn_object_reify, \
00141 PREFIX ## _hashcode, \
00142 PREFIX ## _compare, \
00143 PREFIX ## _inspect \
00144 }
00145
00146 #define PN_METACLASS(PREFIX) { \
00147 #PREFIX, \
00148 CID_ ## PREFIX, \
00149 PREFIX ## _new, \
00150 PREFIX ## _initialize, \
00151 PREFIX ## _incref, \
00152 PREFIX ## _decref, \
00153 PREFIX ## _refcount, \
00154 PREFIX ## _finalize, \
00155 PREFIX ## _free, \
00156 PREFIX ## _reify, \
00157 PREFIX ## _hashcode, \
00158 PREFIX ## _compare, \
00159 PREFIX ## _inspect \
00160 }
00161
00162 PN_EXTERN pn_cid_t pn_class_id(const pn_class_t *clazz);
00163 PN_EXTERN const char *pn_class_name(const pn_class_t *clazz);
00164 PN_EXTERN void *pn_class_new(const pn_class_t *clazz, size_t size);
00165 PN_EXTERN void *pn_class_incref(const pn_class_t *clazz, void *object);
00166 PN_EXTERN int pn_class_refcount(const pn_class_t *clazz, void *object);
00167 PN_EXTERN int pn_class_decref(const pn_class_t *clazz, void *object);
00168 PN_EXTERN void pn_class_free(const pn_class_t *clazz, void *object);
00169 PN_EXTERN const pn_class_t *pn_class_reify(const pn_class_t *clazz, void *object);
00170 PN_EXTERN uintptr_t pn_class_hashcode(const pn_class_t *clazz, void *object);
00171 PN_EXTERN intptr_t pn_class_compare(const pn_class_t *clazz, void *a, void *b);
00172 PN_EXTERN bool pn_class_equals(const pn_class_t *clazz, void *a, void *b);
00173 PN_EXTERN int pn_class_inspect(const pn_class_t *clazz, void *object, pn_string_t *dst);
00174
00175 PN_EXTERN uintptr_t pn_void_hashcode(void *object);
00176 PN_EXTERN intptr_t pn_void_compare(void *a, void *b);
00177 PN_EXTERN int pn_void_inspect(void *object, pn_string_t *dst);
00178
00179 PN_EXTERN void *pn_object_new(const pn_class_t *clazz, size_t size);
00180 PN_EXTERN const pn_class_t *pn_object_reify(void *object);
00181 PN_EXTERN void pn_object_incref(void *object);
00182 PN_EXTERN int pn_object_refcount(void *object);
00183 PN_EXTERN void pn_object_decref(void *object);
00184 PN_EXTERN void pn_object_free(void *object);
00185
00186 PN_EXTERN void *pn_incref(void *object);
00187 PN_EXTERN int pn_decref(void *object);
00188 PN_EXTERN int pn_refcount(void *object);
00189 PN_EXTERN void pn_free(void *object);
00190 PN_EXTERN const pn_class_t *pn_class(void* object);
00191 PN_EXTERN uintptr_t pn_hashcode(void *object);
00192 PN_EXTERN intptr_t pn_compare(void *a, void *b);
00193 PN_EXTERN bool pn_equals(void *a, void *b);
00194 PN_EXTERN int pn_inspect(void *object, pn_string_t *dst);
00195
00196 #define PN_REFCOUNT (0x1)
00197
00198 PN_EXTERN pn_list_t *pn_list(const pn_class_t *clazz, size_t capacity);
00199 PN_EXTERN size_t pn_list_size(pn_list_t *list);
00200 PN_EXTERN void *pn_list_get(pn_list_t *list, int index);
00201 PN_EXTERN void pn_list_set(pn_list_t *list, int index, void *value);
00202 PN_EXTERN int pn_list_add(pn_list_t *list, void *value);
00203 PN_EXTERN void *pn_list_pop(pn_list_t *list);
00204 PN_EXTERN ssize_t pn_list_index(pn_list_t *list, void *value);
00205 PN_EXTERN bool pn_list_remove(pn_list_t *list, void *value);
00206 PN_EXTERN void pn_list_del(pn_list_t *list, int index, int n);
00207 PN_EXTERN void pn_list_clear(pn_list_t *list);
00208 PN_EXTERN void pn_list_iterator(pn_list_t *list, pn_iterator_t *iter);
00209 PN_EXTERN void pn_list_minpush(pn_list_t *list, void *value);
00210 PN_EXTERN void *pn_list_minpop(pn_list_t *list);
00211
00212 #define PN_REFCOUNT_KEY (0x2)
00213 #define PN_REFCOUNT_VALUE (0x4)
00214
00215 PN_EXTERN pn_map_t *pn_map(const pn_class_t *key, const pn_class_t *value,
00216 size_t capacity, float load_factor);
00217 PN_EXTERN size_t pn_map_size(pn_map_t *map);
00218 PN_EXTERN int pn_map_put(pn_map_t *map, void *key, void *value);
00219 PN_EXTERN void *pn_map_get(pn_map_t *map, void *key);
00220 PN_EXTERN void pn_map_del(pn_map_t *map, void *key);
00221 PN_EXTERN pn_handle_t pn_map_head(pn_map_t *map);
00222 PN_EXTERN pn_handle_t pn_map_next(pn_map_t *map, pn_handle_t entry);
00223 PN_EXTERN void *pn_map_key(pn_map_t *map, pn_handle_t entry);
00224 PN_EXTERN void *pn_map_value(pn_map_t *map, pn_handle_t entry);
00225
00226 PN_EXTERN pn_hash_t *pn_hash(const pn_class_t *clazz, size_t capacity, float load_factor);
00227 PN_EXTERN size_t pn_hash_size(pn_hash_t *hash);
00228 PN_EXTERN int pn_hash_put(pn_hash_t *hash, uintptr_t key, void *value);
00229 PN_EXTERN void *pn_hash_get(pn_hash_t *hash, uintptr_t key);
00230 PN_EXTERN void pn_hash_del(pn_hash_t *hash, uintptr_t key);
00231 PN_EXTERN pn_handle_t pn_hash_head(pn_hash_t *hash);
00232 PN_EXTERN pn_handle_t pn_hash_next(pn_hash_t *hash, pn_handle_t entry);
00233 PN_EXTERN uintptr_t pn_hash_key(pn_hash_t *hash, pn_handle_t entry);
00234 PN_EXTERN void *pn_hash_value(pn_hash_t *hash, pn_handle_t entry);
00235
00236 PN_EXTERN pn_string_t *pn_string(const char *bytes);
00237 PN_EXTERN pn_string_t *pn_stringn(const char *bytes, size_t n);
00238 PN_EXTERN const char *pn_string_get(pn_string_t *string);
00239 PN_EXTERN size_t pn_string_size(pn_string_t *string);
00240 PN_EXTERN int pn_string_set(pn_string_t *string, const char *bytes);
00241 PN_EXTERN int pn_string_setn(pn_string_t *string, const char *bytes, size_t n);
00242 PN_EXTERN ssize_t pn_string_put(pn_string_t *string, char *dst);
00243 PN_EXTERN void pn_string_clear(pn_string_t *string);
00244 PN_EXTERN int pn_string_format(pn_string_t *string, const char *format, ...)
00245 #ifdef __GNUC__
00246 __attribute__ ((format (printf, 2, 3)))
00247 #endif
00248 ;
00249 PN_EXTERN int pn_string_vformat(pn_string_t *string, const char *format, va_list ap);
00250 PN_EXTERN int pn_string_addf(pn_string_t *string, const char *format, ...)
00251 #ifdef __GNUC__
00252 __attribute__ ((format (printf, 2, 3)))
00253 #endif
00254 ;
00255 PN_EXTERN int pn_string_vaddf(pn_string_t *string, const char *format, va_list ap);
00256 PN_EXTERN int pn_string_grow(pn_string_t *string, size_t capacity);
00257 PN_EXTERN char *pn_string_buffer(pn_string_t *string);
00258 PN_EXTERN size_t pn_string_capacity(pn_string_t *string);
00259 PN_EXTERN int pn_string_resize(pn_string_t *string, size_t size);
00260 PN_EXTERN int pn_string_copy(pn_string_t *string, pn_string_t *src);
00261
00262 PN_EXTERN pn_iterator_t *pn_iterator(void);
00263 PN_EXTERN void *pn_iterator_start(pn_iterator_t *iterator,
00264 pn_iterator_next_t next, size_t size);
00265 PN_EXTERN void *pn_iterator_next(pn_iterator_t *iterator);
00266
00267 #define PN_LEGCTX ((pn_handle_t) 0)
00268
00269
00270
00271
00272
00273
00274
00275 pn_handle_t get_my_thing(void);
00276
00277
00278 PN_HANDLE(MY_THING);
00279 pn_handle_t get_my_thing(void) { return MY_THING; }
00280
00281 Note that the name "MY_THING" is not exported and is not required to be
00282 unique except in the .c file. The linker will guarantee that the *address* of
00283 MY_THING, as returned by get_my_thing() *is* unique across the entire linked
00284 executable.
00285 */
00286 #define PN_HANDLE(name) \
00287 static const char _PN_HANDLE_ ## name = 0; \
00288 static const pn_handle_t name = ((pn_handle_t) &_PN_HANDLE_ ## name);
00289
00290 PN_EXTERN pn_record_t *pn_record(void);
00291 PN_EXTERN void pn_record_def(pn_record_t *record, pn_handle_t key, const pn_class_t *clazz);
00292 PN_EXTERN bool pn_record_has(pn_record_t *record, pn_handle_t key);
00293 PN_EXTERN void *pn_record_get(pn_record_t *record, pn_handle_t key);
00294 PN_EXTERN void pn_record_set(pn_record_t *record, pn_handle_t key, void *value);
00295 PN_EXTERN void pn_record_clear(pn_record_t *record);
00296
00297 #ifdef __cplusplus
00298 }
00299 #endif
00300
00301 #endif