Qpid Proton C API  0.37.0
object.h
1 #ifndef PROTON_OBJECT_H
2 #define PROTON_OBJECT_H 1
3 
4 /*
5  *
6  * Licensed to the Apache Software Foundation (ASF) under one
7  * or more contributor license agreements. See the NOTICE file
8  * distributed with this work for additional information
9  * regarding copyright ownership. The ASF licenses this file
10  * to you under the Apache License, Version 2.0 (the
11  * "License"); you may not use this file except in compliance
12  * with the License. You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing,
17  * software distributed under the License is distributed on an
18  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19  * KIND, either express or implied. See the License for the
20  * specific language governing permissions and limitations
21  * under the License.
22  *
23  */
24 
25 #include <proton/cid.h>
26 #include <proton/types.h>
27 #include <stdarg.h>
28 #include <proton/type_compat.h>
29 #include <stddef.h>
30 #include <proton/import_export.h>
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35 
40 typedef const void* pn_handle_t;
41 typedef intptr_t pn_shandle_t;
42 
43 typedef struct pn_class_t pn_class_t;
44 typedef struct pn_string_t pn_string_t;
45 typedef struct pn_list_t pn_list_t;
46 typedef struct pn_map_t pn_map_t;
47 typedef struct pn_hash_t pn_hash_t;
48 typedef void *(*pn_iterator_next_t)(void *state);
49 typedef struct pn_iterator_t pn_iterator_t;
50 typedef struct pn_record_t pn_record_t;
51 
52 struct pn_class_t {
53  const char *name;
54  const pn_cid_t cid;
55  void *(*newinst)(const pn_class_t *, size_t);
56  void (*initialize)(void *);
57  void (*incref)(void *);
58  void (*decref)(void *);
59  int (*refcount)(void *);
60  void (*finalize)(void *);
61  void (*free)(void *);
62  const pn_class_t *(*reify)(void *);
63  uintptr_t (*hashcode)(void *);
64  intptr_t (*compare)(void *, void *);
65  int (*inspect)(void *, pn_string_t *);
66 };
67 
68 /* Hack alert: Declare these as arrays so we can treat the name of the single
69  object as the address */
70 PN_EXTERN extern const pn_class_t PN_OBJECT[];
71 PN_EXTERN extern const pn_class_t PN_VOID[];
72 PN_EXTERN extern const pn_class_t PN_WEAKREF[];
73 
74 #define PN_CLASSCLASS(PREFIX) PREFIX ## __class
75 
76 #define PN_CLASSDEF(PREFIX) \
77 static void PREFIX ## _initialize_cast(void *object) { \
78  PREFIX ## _initialize((PREFIX ## _t *) object); \
79 } \
80  \
81 static void PREFIX ## _finalize_cast(void *object) { \
82  PREFIX ## _finalize((PREFIX ## _t *) object); \
83 } \
84  \
85 static uintptr_t PREFIX ## _hashcode_cast(void *object) { \
86  uintptr_t (*fp)(PREFIX ## _t *) = PREFIX ## _hashcode; \
87  if (fp) { \
88  return fp((PREFIX ## _t *) object); \
89  } else { \
90  return (uintptr_t) object; \
91  } \
92 } \
93  \
94 static intptr_t PREFIX ## _compare_cast(void *a, void *b) { \
95  intptr_t (*fp)(PREFIX ## _t *, PREFIX ## _t *) = PREFIX ## _compare; \
96  if (fp) { \
97  return fp((PREFIX ## _t *) a, (PREFIX ## _t *) b); \
98  } else { \
99  return (intptr_t) a - (intptr_t) b; \
100  } \
101 } \
102  \
103 static int PREFIX ## _inspect_cast(void *object, pn_string_t *str) { \
104  int (*fp)(PREFIX ## _t *, pn_string_t *) = PREFIX ## _inspect; \
105  if (fp) { \
106  return fp((PREFIX ## _t *) object, str); \
107  } else { \
108  return pn_string_addf(str, "%s<%p>", #PREFIX, object); \
109  } \
110 } \
111  \
112 const pn_class_t PN_CLASSCLASS(PREFIX)[] = {{ \
113  #PREFIX, \
114  CID_ ## PREFIX, \
115  pn_object_new, \
116  PREFIX ## _initialize_cast, \
117  pn_object_incref, \
118  pn_object_decref, \
119  pn_object_refcount, \
120  PREFIX ## _finalize_cast, \
121  pn_object_free, \
122  pn_object_reify, \
123  PREFIX ## _hashcode_cast, \
124  PREFIX ## _compare_cast, \
125  PREFIX ## _inspect_cast \
126 }}; \
127  \
128 PREFIX ## _t *PREFIX ## _new(void) { \
129  return (PREFIX ## _t *) pn_class_new(PN_CLASSCLASS(PREFIX), \
130  sizeof(PREFIX ## _t)); \
131 }
132 
133 #define PN_CLASS(PREFIX) { \
134  #PREFIX, \
135  CID_ ## PREFIX, \
136  pn_object_new, \
137  PREFIX ## _initialize, \
138  pn_object_incref, \
139  pn_object_decref, \
140  pn_object_refcount, \
141  PREFIX ## _finalize, \
142  pn_object_free, \
143  pn_object_reify, \
144  PREFIX ## _hashcode, \
145  PREFIX ## _compare, \
146  PREFIX ## _inspect \
147 }
148 
149 #define PN_METACLASS(PREFIX) { \
150  #PREFIX, \
151  CID_ ## PREFIX, \
152  PREFIX ## _new, \
153  PREFIX ## _initialize, \
154  PREFIX ## _incref, \
155  PREFIX ## _decref, \
156  PREFIX ## _refcount, \
157  PREFIX ## _finalize, \
158  PREFIX ## _free, \
159  PREFIX ## _reify, \
160  PREFIX ## _hashcode, \
161  PREFIX ## _compare, \
162  PREFIX ## _inspect \
163 }
164 
165 /* Class to identify a plain C struct in a pn_event_t. No refcounting or memory management. */
166 #define PN_STRUCT_CLASSDEF(PREFIX) \
167 static const pn_class_t *PREFIX ## _reify(void *p); \
168 const pn_class_t PN_CLASSCLASS(PREFIX)[] = {{ \
169  #PREFIX, \
170  CID_ ## PREFIX, \
171  NULL, /*_new*/ \
172  NULL, /*_initialize*/ \
173  pn_void_incref, \
174  pn_void_decref, \
175  pn_void_refcount, \
176  NULL, /* _finalize */ \
177  NULL, /* _free */ \
178  PREFIX ## _reify, \
179  pn_void_hashcode, \
180  pn_void_compare, \
181  pn_void_inspect \
182 }}; \
183 const pn_class_t *PREFIX ## _reify(void *p) { \
184  return PN_CLASSCLASS(PREFIX); \
185 }
186 
187 PN_EXTERN pn_cid_t pn_class_id(const pn_class_t *clazz);
188 PN_EXTERN const char *pn_class_name(const pn_class_t *clazz);
189 PN_EXTERN void *pn_class_new(const pn_class_t *clazz, size_t size);
190 
191 /* pn_incref, pn_decref and pn_refcount are for internal use by the proton
192  library, the should not be called by application code. Application code
193  should use the appropriate pn_*_free function (pn_link_free, pn_session_free
194  etc.) when it is finished with a proton value. Proton values should only be
195  used when handling a pn_event_t that refers to them.
196 */
197 PN_EXTERN void *pn_class_incref(const pn_class_t *clazz, void *object);
198 PN_EXTERN int pn_class_refcount(const pn_class_t *clazz, void *object);
199 PN_EXTERN int pn_class_decref(const pn_class_t *clazz, void *object);
200 
201 PN_EXTERN void pn_class_free(const pn_class_t *clazz, void *object);
202 
203 PN_EXTERN const pn_class_t *pn_class_reify(const pn_class_t *clazz, void *object);
204 PN_EXTERN uintptr_t pn_class_hashcode(const pn_class_t *clazz, void *object);
205 PN_EXTERN intptr_t pn_class_compare(const pn_class_t *clazz, void *a, void *b);
206 PN_EXTERN bool pn_class_equals(const pn_class_t *clazz, void *a, void *b);
207 PN_EXTERN int pn_class_inspect(const pn_class_t *clazz, void *object, pn_string_t *dst);
208 
209 PN_EXTERN void *pn_void_new(const pn_class_t *clazz, size_t size);
210 PN_EXTERN void pn_void_incref(void *object);
211 PN_EXTERN void pn_void_decref(void *object);
212 PN_EXTERN int pn_void_refcount(void *object);
213 PN_EXTERN uintptr_t pn_void_hashcode(void *object);
214 PN_EXTERN intptr_t pn_void_compare(void *a, void *b);
215 PN_EXTERN int pn_void_inspect(void *object, pn_string_t *dst);
216 
217 PN_EXTERN void *pn_object_new(const pn_class_t *clazz, size_t size);
218 PN_EXTERN const pn_class_t *pn_object_reify(void *object);
219 PN_EXTERN void pn_object_incref(void *object);
220 PN_EXTERN int pn_object_refcount(void *object);
221 PN_EXTERN void pn_object_decref(void *object);
222 PN_EXTERN void pn_object_free(void *object);
223 
224 PN_EXTERN void *pn_incref(void *object);
225 PN_EXTERN int pn_decref(void *object);
226 PN_EXTERN int pn_refcount(void *object);
227 PN_EXTERN void pn_free(void *object);
228 PN_EXTERN const pn_class_t *pn_class(void* object);
229 PN_EXTERN uintptr_t pn_hashcode(void *object);
230 PN_EXTERN intptr_t pn_compare(void *a, void *b);
231 PN_EXTERN bool pn_equals(void *a, void *b);
232 PN_EXTERN int pn_inspect(void *object, pn_string_t *dst);
233 
234 #define PN_REFCOUNT (0x1)
235 
236 PN_EXTERN pn_list_t *pn_list(const pn_class_t *clazz, size_t capacity);
237 PN_EXTERN size_t pn_list_size(pn_list_t *list);
238 PN_EXTERN void *pn_list_get(pn_list_t *list, int index);
239 PN_EXTERN void pn_list_set(pn_list_t *list, int index, void *value);
240 PN_EXTERN int pn_list_add(pn_list_t *list, void *value);
241 PN_EXTERN void *pn_list_pop(pn_list_t *list);
242 PN_EXTERN ssize_t pn_list_index(pn_list_t *list, void *value);
243 PN_EXTERN bool pn_list_remove(pn_list_t *list, void *value);
244 PN_EXTERN void pn_list_del(pn_list_t *list, int index, int n);
245 PN_EXTERN void pn_list_clear(pn_list_t *list);
246 PN_EXTERN void pn_list_iterator(pn_list_t *list, pn_iterator_t *iter);
247 PN_EXTERN void pn_list_minpush(pn_list_t *list, void *value);
248 PN_EXTERN void *pn_list_minpop(pn_list_t *list);
249 
250 #define PN_REFCOUNT_KEY (0x2)
251 #define PN_REFCOUNT_VALUE (0x4)
252 
253 PN_EXTERN pn_map_t *pn_map(const pn_class_t *key, const pn_class_t *value,
254  size_t capacity, float load_factor);
255 PN_EXTERN size_t pn_map_size(pn_map_t *map);
256 PN_EXTERN int pn_map_put(pn_map_t *map, void *key, void *value);
257 PN_EXTERN void *pn_map_get(pn_map_t *map, void *key);
258 PN_EXTERN void pn_map_del(pn_map_t *map, void *key);
259 PN_EXTERN pn_handle_t pn_map_head(pn_map_t *map);
260 PN_EXTERN pn_handle_t pn_map_next(pn_map_t *map, pn_handle_t entry);
261 PN_EXTERN void *pn_map_key(pn_map_t *map, pn_handle_t entry);
262 PN_EXTERN void *pn_map_value(pn_map_t *map, pn_handle_t entry);
263 
264 PN_EXTERN pn_hash_t *pn_hash(const pn_class_t *clazz, size_t capacity, float load_factor);
265 PN_EXTERN size_t pn_hash_size(pn_hash_t *hash);
266 PN_EXTERN int pn_hash_put(pn_hash_t *hash, uintptr_t key, void *value);
267 PN_EXTERN void *pn_hash_get(pn_hash_t *hash, uintptr_t key);
268 PN_EXTERN void pn_hash_del(pn_hash_t *hash, uintptr_t key);
269 PN_EXTERN pn_handle_t pn_hash_head(pn_hash_t *hash);
270 PN_EXTERN pn_handle_t pn_hash_next(pn_hash_t *hash, pn_handle_t entry);
271 PN_EXTERN uintptr_t pn_hash_key(pn_hash_t *hash, pn_handle_t entry);
272 PN_EXTERN void *pn_hash_value(pn_hash_t *hash, pn_handle_t entry);
273 
274 PN_EXTERN pn_string_t *pn_string(const char *bytes);
275 PN_EXTERN pn_string_t *pn_stringn(const char *bytes, size_t n);
276 PN_EXTERN const char *pn_string_get(pn_string_t *string);
277 PN_EXTERN size_t pn_string_size(pn_string_t *string);
278 PN_EXTERN int pn_string_set(pn_string_t *string, const char *bytes);
279 PN_EXTERN int pn_string_setn(pn_string_t *string, const char *bytes, size_t n);
280 PN_EXTERN ssize_t pn_string_put(pn_string_t *string, char *dst);
281 PN_EXTERN void pn_string_clear(pn_string_t *string);
282 PN_EXTERN int pn_string_format(pn_string_t *string, const char *format, ...)
283 #ifdef __GNUC__
284  __attribute__ ((format (printf, 2, 3)))
285 #endif
286  ;
287 PN_EXTERN int pn_string_vformat(pn_string_t *string, const char *format, va_list ap);
288 PN_EXTERN int pn_string_addf(pn_string_t *string, const char *format, ...)
289 #ifdef __GNUC__
290  __attribute__ ((format (printf, 2, 3)))
291 #endif
292  ;
293 PN_EXTERN int pn_string_vaddf(pn_string_t *string, const char *format, va_list ap);
294 PN_EXTERN int pn_string_grow(pn_string_t *string, size_t capacity);
295 PN_EXTERN char *pn_string_buffer(pn_string_t *string);
296 PN_EXTERN size_t pn_string_capacity(pn_string_t *string);
297 PN_EXTERN int pn_string_resize(pn_string_t *string, size_t size);
298 PN_EXTERN int pn_string_copy(pn_string_t *string, pn_string_t *src);
299 
300 PN_EXTERN pn_iterator_t *pn_iterator(void);
301 PN_EXTERN void *pn_iterator_start(pn_iterator_t *iterator,
302  pn_iterator_next_t next, size_t size);
303 PN_EXTERN void *pn_iterator_next(pn_iterator_t *iterator);
304 
305 #define PN_LEGCTX ((pn_handle_t) 0)
306 
313 
316 
324 #define PN_HANDLE(name) \
325  static const char _PN_HANDLE_ ## name = 0; \
326  static const pn_handle_t name = ((pn_handle_t) &_PN_HANDLE_ ## name);
327 
328 PN_EXTERN pn_record_t *pn_record(void);
329 PN_EXTERN void pn_record_def(pn_record_t *record, pn_handle_t key, const pn_class_t *clazz);
330 PN_EXTERN bool pn_record_has(pn_record_t *record, pn_handle_t key);
331 PN_EXTERN void *pn_record_get(pn_record_t *record, pn_handle_t key);
332 PN_EXTERN void pn_record_set(pn_record_t *record, pn_handle_t key, void *value);
333 PN_EXTERN void pn_record_clear(pn_record_t *record);
334 
339 #ifdef __cplusplus
340 }
341 #endif
342 
343 #endif /* object.h */
AMQP and API data types.