1 /* 2 belle-sip - SIP (RFC3261) library. 3 Copyright (C) 2010 Belledonne Communications SARL 4 5 This program is free software: you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation, either version 2 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 #ifndef belle_sip_object_h 20 #define belle_sip_object_h 21 22 #include "belle-sip/defs.h" 23 #include "belle-sip/utils.h" 24 #include "belle-sip/list.h" 25 26 /* 27 * typedefs, macros and functions for object definition and manipulation. 28 */ 29 30 #define BELLE_SIP_DEFAULT_BUFSIZE_HINT 0 31 32 #define BELLE_SIP_TYPE_ID(_type) _type##_id 33 34 typedef unsigned int belle_sip_type_id_t; 35 36 #define BELLE_SIP_DECLARE_TYPES_BEGIN(namezpace,unique_namespace_id) \ 37 enum namezpace##type_ids{\ 38 namezpace##type_id_first=unique_namespace_id, 39 40 #define BELLE_SIP_DECLARE_TYPES_END }; 41 42 #define BELLE_SIP_OBJECT_VPTR_NAME(object_type) object_type##_vptr 43 44 #define BELLE_SIP_OBJECT_GET_VPTR_FUNC(object_type) object_type##_vptr_get 45 46 #define BELLE_SIP_OBJECT_VPTR_TYPE(object_type) object_type##_vptr_t 47 48 #define BELLE_SIP_DECLARE_VPTR(object_type) \ 49 typedef belle_sip_object_vptr_t BELLE_SIP_OBJECT_VPTR_TYPE(object_type);\ 50 BELLESIP_EXPORT BELLE_SIP_OBJECT_VPTR_TYPE(object_type) * BELLE_SIP_OBJECT_GET_VPTR_FUNC(object_type)(void); 51 52 #define BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN(object_type, parent_type) \ 53 typedef struct object_type##_vptr_struct BELLE_SIP_OBJECT_VPTR_TYPE(object_type);\ 54 BELLESIP_EXPORT BELLE_SIP_OBJECT_VPTR_TYPE(object_type) * BELLE_SIP_OBJECT_GET_VPTR_FUNC(object_type)(void); \ 55 struct object_type##_vptr_struct{\ 56 BELLE_SIP_OBJECT_VPTR_TYPE(parent_type) base; 57 58 #define BELLE_SIP_DECLARE_VPTR_NO_EXPORT(object_type) \ 59 typedef belle_sip_object_vptr_t BELLE_SIP_OBJECT_VPTR_TYPE(object_type);\ 60 BELLE_SIP_OBJECT_VPTR_TYPE(object_type) * BELLE_SIP_OBJECT_GET_VPTR_FUNC(object_type)(void); 61 62 #define BELLE_SIP_DECLARE_CUSTOM_VPTR_BEGIN_NO_EXPORT(object_type, parent_type) \ 63 typedef struct object_type##_vptr_struct BELLE_SIP_OBJECT_VPTR_TYPE(object_type);\ 64 BELLE_SIP_OBJECT_VPTR_TYPE(object_type) * BELLE_SIP_OBJECT_GET_VPTR_FUNC(object_type)(void); \ 65 struct object_type##_vptr_struct{\ 66 BELLE_SIP_OBJECT_VPTR_TYPE(parent_type) base; 67 68 #define BELLE_SIP_DECLARE_CUSTOM_VPTR_END }; 69 70 #define BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_BEGIN(object_type) \ 71 extern BELLE_SIP_OBJECT_VPTR_TYPE(object_type) BELLE_SIP_OBJECT_VPTR_NAME(object_type);\ 72 BELLE_SIP_OBJECT_VPTR_TYPE(object_type) * BELLE_SIP_OBJECT_GET_VPTR_FUNC(object_type)(void){\ 73 return &BELLE_SIP_OBJECT_VPTR_NAME(object_type); \ 74 }\ 75 BELLE_SIP_OBJECT_VPTR_TYPE(object_type) BELLE_SIP_OBJECT_VPTR_NAME(object_type)={ 76 77 #define BELLE_SIP_INSTANCIATE_CUSTOM_VPTR_END }; 78 79 #define BELLE_SIP_VPTR_INIT(object_type,parent_type,unowned) \ 80 BELLE_SIP_TYPE_ID(object_type), \ 81 sizeof(object_type), \ 82 #object_type,\ 83 unowned,\ 84 (belle_sip_object_get_vptr_t)BELLE_SIP_OBJECT_GET_VPTR_FUNC(parent_type), \ 85 (belle_sip_interface_desc_t**)object_type##interfaces_table 86 87 88 #define BELLE_SIP_INSTANCIATE_VPTR(object_type,parent_type,destroy,clone,marshal,unowned) \ 89 static BELLE_SIP_OBJECT_VPTR_TYPE(object_type) BELLE_SIP_OBJECT_VPTR_NAME(object_type)={ \ 90 BELLE_SIP_VPTR_INIT(object_type,parent_type,unowned), \ 91 (belle_sip_object_destroy_t)destroy, \ 92 (belle_sip_object_clone_t)clone, \ 93 (belle_sip_object_marshal_t)marshal,\ 94 BELLE_SIP_DEFAULT_BUFSIZE_HINT\ 95 }; \ 96 BELLE_SIP_OBJECT_VPTR_TYPE(object_type) * BELLE_SIP_OBJECT_GET_VPTR_FUNC(object_type)(void){\ 97 return &BELLE_SIP_OBJECT_VPTR_NAME(object_type); \ 98 } 99 100 /** 101 * belle_sip_object_t is the base object. 102 * It is the base class for all belle sip non trivial objects. 103 * It owns a reference count which allows to trigger the destruction of the object when the last 104 * user of it calls belle_sip_object_unref(). 105 * 106 * It contains a generic data store that allows users to store named data in it and retrieve them afterwards. 107 * 108 * About object lifecycle<br> 109 * In belle-sip, objects can be, depending on their types, initially owned, that there are created with a ref count of 1, or 110 * initially unowned, that is with reference count of 0. Such objets are also referred as "floating object". They are automatically destroyed 111 * by the main loop iteration, so a floating object can be seen as a temporary object, until someones calls belle_sip_object_ref() on it. 112 * 113 * In order to know whether a kind of object is initially owned or initially unowned, you can use the test program tester/belle_sip_object_describe. 114 * This tool gives the hierarchy and properties of the object type whose name is supplied in argument. For example: 115 * 116 * <pre>./tester/belle_sip_object_describe belle_sip_request_t</pre> 117 * 118 * The object memory management depends slightly on whether an object type is created initially owned or not. 119 * In order not to be lost and make memory fault or leaks, consider the following rules: 120 * 121 * When an object is of type initially unowned: 122 * * call belle_sip_object_ref() on it only if you need a pointer to this object to be used outside the scope of the current function. 123 * * call belle_sip_object_unref() on it only if you previously called belle_sip_object_ref(). 124 * 125 * When an object is of type initially owned: 126 * * you can safely store its pointer. 127 * * use belle_sip_object_unref() when you no longer need it. 128 * 129 * Also, keep in mind that most objects of belle-sip are initially unowned, especially 130 * * all objects who are usually required to be used inside another object (for example: an URI is part of a from header, a contact header is part of a message) 131 * * all objects whose lifecyle is maintained by the stack: transactions, dialogs. 132 * 133 * On the contrary, top level objects whose lifecyle belongs only to the application are initially owned: 134 * * belle_sip_provider_t, belle_sip_stack_t, belle_sip_source_t. 135 * 136 * Internally, belle-sip objects containing pointers to other objects must take a reference count on the other objects they hold; and leave this reference 137 * when they no longer need it. This rule must be strictly followed by developers doing things inside belle-sip. 138 **/ 139 typedef struct _belle_sip_object belle_sip_object_t; 140 141 142 typedef void (*belle_sip_object_destroy_t)(belle_sip_object_t*); 143 typedef void (*belle_sip_object_clone_t)(belle_sip_object_t* obj, const belle_sip_object_t *orig); 144 typedef belle_sip_error_code (*belle_sip_object_marshal_t)(belle_sip_object_t* obj, char* buff, size_t buff_size, size_t *offset); 145 typedef struct _belle_sip_object_vptr *(*belle_sip_object_get_vptr_t)(void); 146 147 struct _belle_sip_object_vptr{ 148 belle_sip_type_id_t id; 149 size_t size; /*the size of the object - not the vptr size*/ 150 const char *type_name; 151 int initially_unowned; 152 belle_sip_object_get_vptr_t get_parent; 153 struct belle_sip_interface_desc **interfaces; /*NULL terminated table of */ 154 belle_sip_object_destroy_t destroy; 155 belle_sip_object_clone_t clone; 156 belle_sip_object_marshal_t marshal; 157 int tostring_bufsize_hint; /*optimization: you can suggest here the typical size for a to_string() result.*/ 158 }; 159 160 typedef struct _belle_sip_object_vptr belle_sip_object_vptr_t; 161 162 struct _belle_sip_object{ 163 belle_sip_object_vptr_t *vptr; 164 int ref; 165 char* name; 166 struct weak_ref *weak_refs; 167 struct belle_sip_object_pool *pool; 168 belle_sip_list_t *pool_iterator; 169 belle_sip_list_t *data_store; 170 }; 171 172 173 BELLE_SIP_BEGIN_DECLS 174 175 176 BELLESIP_EXPORT belle_sip_object_t * _belle_sip_object_new(size_t objsize, belle_sip_object_vptr_t *vptr); 177 178 #define belle_sip_object_new(_type) (_type*)_belle_sip_object_new(sizeof(_type),(belle_sip_object_vptr_t*)BELLE_SIP_OBJECT_GET_VPTR_FUNC(_type)()) 179 180 181 /** 182 * Activates checks on object marshalling. 183 * Useful for debug purposes. 184 * @param enable TRUE to enable, FALSE to disable. 185 **/ 186 BELLESIP_EXPORT void belle_sip_object_enable_marshal_check(int enable); 187 188 /** 189 * Activates an object leak detector. When enabled, belle-sip will reference all created objects. 190 * At program termination, application can check if objects remain alive using belle_sip_object_get_object_count() and dump them with 191 * belle_sip_object_dump_active_objects(). 192 * @warning this must not be used in multi-threaded programs (when multiple threads can access belle-sip at the same time) 193 * Useful for debug purposes. 194 * @param enable TRUE to enable, FALSE to disable. 195 **/ 196 BELLESIP_EXPORT void belle_sip_object_enable_leak_detector(int enable); 197 198 BELLESIP_EXPORT int belle_sip_object_get_object_count(void); 199 200 BELLESIP_EXPORT void belle_sip_object_flush_active_objects(void); 201 202 BELLESIP_EXPORT void belle_sip_object_dump_active_objects(void); 203 204 /** 205 * Suspend leak detector from this point. If the leak detector wasn't activated, this function does nothing. 206 * This can be useful to make object allocation that have to remain active beyond the scope of a test. 207 **/ 208 BELLESIP_EXPORT void belle_sip_object_inhibit_leak_detector(int yes); 209 210 int belle_sip_object_is_unowed(const belle_sip_object_t *obj); 211 212 /** 213 * Increments reference counter, which prevents the object from being destroyed. 214 * If the object is initially unowed, this acquires the first reference. 215 * 216 **/ 217 BELLESIP_EXPORT belle_sip_object_t * belle_sip_object_ref(void *obj); 218 219 /** 220 * Decrements the reference counter. When it drops to zero, the object is destroyed. 221 **/ 222 BELLESIP_EXPORT void belle_sip_object_unref(void *obj); 223 224 225 typedef void (*belle_sip_object_destroy_notify_t)(void *userpointer, belle_sip_object_t *obj_being_destroyed); 226 /** 227 * Add a weak reference to object. 228 * When object will be destroyed, then the destroy_notify callback will be called. 229 * This allows another object to be informed when object is destroyed, and then possibly 230 * cleanups pointer it holds to this object. 231 **/ 232 BELLESIP_EXPORT belle_sip_object_t *belle_sip_object_weak_ref(void *obj, belle_sip_object_destroy_notify_t destroy_notify, void *userpointer); 233 234 /** 235 * Remove a weak reference to object. 236 **/ 237 BELLESIP_EXPORT void belle_sip_object_weak_unref(void *obj, belle_sip_object_destroy_notify_t destroy_notify, void *userpointer); 238 239 /** 240 * Set object name. 241 **/ 242 BELLESIP_EXPORT void belle_sip_object_set_name(belle_sip_object_t *obj,const char* name); 243 244 /** 245 * Get object name. 246 **/ 247 BELLESIP_EXPORT const char* belle_sip_object_get_name(belle_sip_object_t *obj); 248 249 /*copy the content of ref object to new object, for the part they have in common in their inheritence diagram*/ 250 void _belle_sip_object_copy(belle_sip_object_t *newobj, const belle_sip_object_t *ref); 251 252 /** 253 * Clone an object. 254 * 255 * This clone function makes a deep copy of all object internal structure, so that the new object and the reference object have no dependencies at all. 256 * 257 **/ 258 BELLESIP_EXPORT belle_sip_object_t *belle_sip_object_clone(const belle_sip_object_t *obj); 259 260 /** 261 * Same as #belle_sip_object_clone but with ref count set to 1 262 * 263 **/ 264 belle_sip_object_t *belle_sip_object_clone_and_ref(const belle_sip_object_t *obj); 265 266 267 typedef void (*belle_sip_data_destroy)(void* data); 268 typedef void* (*belle_sip_data_clone)(const char* name, void* data); 269 270 /** 271 * Add an entry to the object's embedded data store, with the key name specified. 272 * The destroy function is used when the data is cleaned. 273 * 274 * If an entry already exists, the existing data will be cleaned by calling its destroy function and the new data will be placed instead. 275 * 276 * Returns -1 in case of error, 0 in case the insertion was successful, and 1 if existing data was present. 277 **/ 278 BELLESIP_EXPORT int belle_sip_object_data_set( belle_sip_object_t *obj, const char* name, void* data, belle_sip_data_destroy destroy_func ); 279 280 /** 281 * Retrieve data that has been stored in the object data store. 282 **/ 283 BELLESIP_EXPORT void* belle_sip_object_data_get( belle_sip_object_t *obj, const char* name ); 284 285 /** 286 * Return 1 if the key exists in the data store, 0 otherwise 287 **/ 288 BELLESIP_EXPORT int belle_sip_object_data_exists( const belle_sip_object_t *obj, const char* name ); 289 290 /** 291 * Destroys the named data associated by the name provided. 292 * 293 * Returns 0 for success, -1 for error 294 **/ 295 BELLESIP_EXPORT int belle_sip_object_data_remove( belle_sip_object_t *obj, const char* name); 296 297 /** 298 * Retrieve the data from the data store and removes it from the data store, without calling the destructor. 299 * This transfers ownership of the data to the caller, which will be in charge of releasing it. 300 **/ 301 BELLESIP_EXPORT void* belle_sip_object_data_grab( belle_sip_object_t* obj, const char* name); 302 303 /** 304 * Clears all data in the object's storage, invoking the destroy_func when possible 305 **/ 306 BELLESIP_EXPORT void belle_sip_object_data_clear( belle_sip_object_t* obj ); 307 308 /** 309 * clones the object's data store to another one, using the provided clone function to clone individual data items. 310 * 311 * The destination data store will be cleaned before pushing the source data into it. 312 * For a merge, use #belle_sip_object_data_merge. 313 * This is equivalent to the following code: 314 * { 315 * belle_sip_object_data_clear(dst); 316 * belle_sip_object_data_merge(src, dst, clone_func); 317 * } 318 * 319 * Note that providing NULL as a cloning function will simply assign the src object's data to the dst object. 320 * 321 **/ 322 BELLESIP_EXPORT void belle_sip_object_data_clone( const belle_sip_object_t* src, belle_sip_object_t* dst, belle_sip_data_clone clone_func); 323 324 /** 325 * Merge the source data store into the destination data store. 326 * 327 * Same function as #belle_sip_object_data_clone, except the destination data store is not cleared before inserting the source data. 328 * This overwrites common keys, and keeps existing keys. 329 */ 330 BELLESIP_EXPORT void belle_sip_object_data_merge( const belle_sip_object_t* src, belle_sip_object_t* dst, belle_sip_data_clone clone_func); 331 332 /** 333 * Apply a function for each entry in the data store 334 */ 335 BELLESIP_EXPORT void belle_sip_object_data_foreach( const belle_sip_object_t* obj, void (*apply_func)(const char* key, void* data, void* userdata), void* userdata); 336 /** 337 * Returns a string describing the inheritance diagram and implemented interfaces of object obj. 338 **/ 339 char *belle_sip_object_describe(void *obj); 340 341 /** 342 * Returns a string describing the inheritance diagram and implemented interfaces of an object given its type name. 343 **/ 344 BELLESIP_EXPORT char *belle_sip_object_describe_type_from_name(const char *name); 345 346 BELLESIP_EXPORT void *belle_sip_object_cast(belle_sip_object_t *obj, belle_sip_type_id_t id, const char *castname, const char *file, int fileno); 347 348 /** 349 * Returns a newly allocated string representing the object. 350 * WHen the object is a sip header, uri or message, this is the textual representation of the header, uri or message. 351 * This function internally calls belle_sip_object_marshal(). 352 **/ 353 BELLESIP_EXPORT char* belle_sip_object_to_string(void* obj); 354 355 /** 356 * Writes a string representation of the object into the supplied buffer. 357 * Same as belle_sip_object_to_string(), but without allocating space for the output string. 358 **/ 359 BELLESIP_EXPORT belle_sip_error_code belle_sip_object_marshal(belle_sip_object_t* obj, char* buff, size_t buff_size, size_t *offset); 360 361 /* use BELLE_SIP_OBJECT_IS_INSTANCE_OF macro(), this function is for use by the macro only*/ 362 BELLESIP_EXPORT int _belle_sip_object_is_instance_of(belle_sip_object_t * obj,belle_sip_type_id_t id); 363 364 BELLE_SIP_END_DECLS 365 366 #define BELLE_SIP_CAST(obj,_type) ((_type*)belle_sip_object_cast((belle_sip_object_t *)(obj), _type##_id, #_type, __FILE__, __LINE__)) 367 368 #define BELLE_SIP_OBJECT(obj) BELLE_SIP_CAST(obj,belle_sip_object_t) 369 #define BELLE_SIP_OBJECT_IS_INSTANCE_OF(obj,_type) _belle_sip_object_is_instance_of((belle_sip_object_t*)obj,_type##_id) 370 371 #define BELLE_SIP_OBJECT_VPTR(obj,object_type) ((BELLE_SIP_OBJECT_VPTR_TYPE(object_type)*)(((belle_sip_object_t*)obj)->vptr)) 372 373 /*deprecated*/ 374 #define BELLE_SIP_IS_INSTANCE_OF(obj,_type) BELLE_SIP_OBJECT_IS_INSTANCE_OF(obj,_type) 375 376 #define belle_sip_object_describe_type(type) \ 377 belle_sip_object_describe_type_from_name(#type) 378 379 /* 380 * typedefs, macros and functions for interface definition and manipulation. 381 */ 382 383 #define BELLE_SIP_INTERFACE_ID(_interface) _interface##_id 384 385 typedef unsigned int belle_sip_interface_id_t; 386 387 BELLE_SIP_BEGIN_DECLS 388 389 BELLESIP_EXPORT void *belle_sip_object_interface_cast(belle_sip_object_t *obj, belle_sip_interface_id_t id, const char *castname, const char *file, int fileno); 390 391 int belle_sip_object_implements(belle_sip_object_t *obj, belle_sip_interface_id_t id); 392 393 BELLE_SIP_END_DECLS 394 395 396 #define BELLE_SIP_INTERFACE_METHODS_TYPE(interface_name) methods_##interface_name 397 398 #define BELLE_SIP_INTERFACE_CAST(obj,_iface) ((_iface*)belle_sip_object_interface_cast((belle_sip_object_t*)(obj),_iface##_id,#_iface,__FILE__,__LINE__)) 399 400 #define BELLE_SIP_IMPLEMENTS(obj,_iface) belle_sip_object_implements((belle_sip_object_t*)obj,_iface##_id) 401 402 403 typedef struct belle_sip_interface_desc{ 404 belle_sip_interface_id_t id; 405 const char *ifname; 406 }belle_sip_interface_desc_t; 407 408 #define BELLE_SIP_DECLARE_INTERFACE_BEGIN(interface_name) \ 409 typedef struct struct##interface_name interface_name;\ 410 typedef struct struct_methods_##interface_name BELLE_SIP_INTERFACE_METHODS_TYPE(interface_name);\ 411 struct struct_methods_##interface_name {\ 412 belle_sip_interface_desc_t desc;\ 413 414 415 #define BELLE_SIP_DECLARE_INTERFACE_END }; 416 417 #define BELLE_SIP_IMPLEMENT_INTERFACE_BEGIN(object_type,interface_name) \ 418 static BELLE_SIP_INTERFACE_METHODS_TYPE(interface_name) methods_##object_type##_##interface_name={\ 419 { BELLE_SIP_INTERFACE_ID(interface_name),\ 420 #interface_name }, 421 422 #define BELLE_SIP_IMPLEMENT_INTERFACE_END }; 423 424 #define BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(object_type)\ 425 static belle_sip_interface_desc_t * object_type##interfaces_table[]={\ 426 NULL \ 427 } 428 429 #define BELLE_SIP_DECLARE_IMPLEMENTED_INTERFACES_1(object_type,iface1) \ 430 static belle_sip_interface_desc_t * object_type##interfaces_table[]={\ 431 (belle_sip_interface_desc_t*)&methods_##object_type##_##iface1, \ 432 NULL \ 433 } 434 435 #define BELLE_SIP_DECLARE_IMPLEMENTED_INTERFACES_2(object_type,iface1,iface2) \ 436 static belle_sip_interface_desc_t * object_type##interfaces_table[]={\ 437 (belle_sip_interface_desc_t*)&methods_##object_type##_##iface1, \ 438 (belle_sip_interface_desc_t*)&methods_##object_type##_##iface2, \ 439 NULL \ 440 } 441 442 443 /** 444 * Object holding unowned objects - used as a kind of garbage collector for temporary objects. 445 **/ 446 typedef struct belle_sip_object_pool belle_sip_object_pool_t; 447 448 BELLE_SIP_BEGIN_DECLS 449 450 /** 451 * Push a new object pool for use for creation of new objects. 452 * When no longer needed, this pool can be destroyed with belle_sip_object_unref(). 453 **/ 454 BELLESIP_EXPORT belle_sip_object_pool_t * belle_sip_object_pool_push(void); 455 456 belle_sip_object_pool_t * belle_sip_object_pool_get_current(void); 457 int belle_sip_object_pool_cleanable(belle_sip_object_pool_t *pool); 458 void belle_sip_object_pool_clean(belle_sip_object_pool_t *obj); 459 460 BELLE_SIP_DECLARE_VPTR(belle_sip_object_t) 461 462 BELLE_SIP_END_DECLS 463 464 /** 465 * Adding a new type in belle-sip in 5 steps 466 * ========================================= 467 * 468 * Let's suppose you want to add an object called belle_sip_something_t 469 * 1) Declare the type in the enum in belle-sip.h: 470 * BELLE_SIP_TYPE_ID(belle_sip_something_t) 471 * 2) Declare the api of the new object in .h, including a typedef and a cast macro: 472 * typedef struct belle_sip_something belle_sip_something_t; 473 * #define BELLE_SIP_SOMETHING(obj) BELLE_SIP_CAST(obj,belle_sip_something_t) 474 * 475 * belle_sip_something_t *belle_sip_something_create(int arg1, int arg2); 476 * void belle_sip_something_do_cooking(belle_sip_something_t *obj); 477 * Do not add any destructor, belle_sip_object_unref() does it for all objects. 478 * 479 * 3) in the c file contaning the object's implementation, define the internal structure for your object. 480 * The first field of the struct must be the parent type. 481 * struct belle_sip_something{ 482 * belle_sip_object_t base; 483 * int myint1; 484 * int myint2; 485 * char *mychar; 486 * }; 487 * 4) still in the C file contaning the object's implementation, define a destructor and all functions of its API: 488 * The destructor must only manage the fields from the type, not the parent. 489 * static void belle_sip_something_destroy(belle_sip_something_t *obj){ 490 * if (obj->mychar) belle_sip_free(obj->mychar); 491 * } 492 * 493 * belle_sip_something_t *belle_sip_something_create(int arg1, int arg2){ 494 * belle_sip_something_t *obj=belle_sip_object_new(belle_sip_something_t); 495 * obj->myint1=arg1; 496 * obj->myint2=arg2; 497 * obj->mychar=belle_sip_strdup("Hello world"); 498 * return obj; 499 * } 500 * Declare the interfaces implemented by the object (to be documented) and instanciate its "vptr", necessary for dynamic casting. 501 * BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(belle_sip_something_t); 502 * BELLE_SIP_INSTANCIATE_VPTR(belle_sip_something_t, belle_sip_object_t,belle_sip_something_destroy, NULL, NULL,FALSE); 503 * 504 * 5) in .h file included everywhere in the source (typically belle_sip_internal.h), declare the vptr 505 * BELLE_SIP_DECLARE_VPTR(belle_sip_dns_srv_t); 506 */ 507 508 #if defined(__cplusplus) && defined(BELLE_SIP_USE_STL) 509 #include <ostream> 510 inline std::ostream& 511 operator<<( std::ostream& __os, const belle_sip_object_t* object) 512 { 513 char* object_as_string = belle_sip_object_to_string((void*)object); 514 __os << object_as_string; 515 belle_sip_free(object_as_string); 516 return __os; 517 } 518 #endif 519 #endif 520 521