diff --git a/coreapi/chat.c b/coreapi/chat.c index b51c7284a..40d80657a 100644 --- a/coreapi/chat.c +++ b/coreapi/chat.c @@ -190,9 +190,9 @@ BELLE_SIP_INSTANCIATE_VPTR(LinphoneChatRoom, belle_sip_object_t, LinphoneChatRoom *_linphone_core_create_chat_room_base(LinphoneCore *lc, const LinphoneAddress *addr) { LinphoneChatRoom *cr = belle_sip_object_new(LinphoneChatRoom); if (linphone_core_realtime_text_enabled(lc)) - cr->cr = new LinphonePrivate::RealTimeTextChatRoom(lc, *L_GET_CPP_PTR_FROM_C_STRUCT(addr, Address).get()); + cr->cr = new LinphonePrivate::RealTimeTextChatRoom(lc, *L_GET_CPP_PTR_FROM_C_STRUCT(addr, Address)); else - cr->cr = new LinphonePrivate::BasicChatRoom(lc, *L_GET_CPP_PTR_FROM_C_STRUCT(addr, Address).get()); + cr->cr = new LinphonePrivate::BasicChatRoom(lc, *L_GET_CPP_PTR_FROM_C_STRUCT(addr, Address)); L_GET_PRIVATE(cr->cr)->setCBackPointer(cr); return cr; } diff --git a/src/address/address.cpp b/src/address/address.cpp index 7bac71911..5bd7226d8 100644 --- a/src/address/address.cpp +++ b/src/address/address.cpp @@ -66,15 +66,15 @@ Address &Address::operator= (const Address &src) { return *this; } -Address::operator bool () const { - L_D(const Address); - return static_cast(d->internalAddress); -} - bool Address::operator== (const Address &address) const { return equal(address); } +bool Address::isValid () const { + L_D(const Address); + return static_cast(d->internalAddress); +} + const string &Address::getScheme () const { L_D(const Address); d->cache.scheme = L_C_TO_STRING(sal_address_get_scheme(d->internalAddress)); diff --git a/src/address/address.h b/src/address/address.h index 84048a681..e35688f0c 100644 --- a/src/address/address.h +++ b/src/address/address.h @@ -38,10 +38,10 @@ public: Address &operator= (const Address &src); - operator bool () const; - bool operator== (const Address &address) const; + bool isValid () const; + const std::string &getScheme () const; const std::string &getDisplayName () const; diff --git a/src/c-wrapper/api/c-address.cpp b/src/c-wrapper/api/c-address.cpp index 126c416d8..bd9ec8b29 100644 --- a/src/c-wrapper/api/c-address.cpp +++ b/src/c-wrapper/api/c-address.cpp @@ -26,12 +26,14 @@ using namespace std; -L_DECLARE_C_STRUCT_IMPL(Address, address); +L_DECLARE_C_CLONABLE_STRUCT_IMPL(Address, address); LinphoneAddress *linphone_address_new (const char *address) { - shared_ptr cppPtr = make_shared(L_C_TO_STRING(address)); - if (!*cppPtr.get()) + LINPHONE_NAMESPACE::Address *cppPtr = new LINPHONE_NAMESPACE::Address(L_C_TO_STRING(address)); + if (!cppPtr->isValid()) { + delete cppPtr; return nullptr; + } LinphoneAddress *object = _linphone_address_init(); object->cppPtr = cppPtr; @@ -136,11 +138,11 @@ char *linphone_address_as_string_uri_only (const LinphoneAddress *address) { } bool_t linphone_address_weak_equal (const LinphoneAddress *address1, const LinphoneAddress *address2) { - return address1->cppPtr->weakEqual(*address2->cppPtr.get()); + return address1->cppPtr->weakEqual(*address2->cppPtr); } bool_t linphone_address_equal (const LinphoneAddress *address1, const LinphoneAddress *address2) { - return *address1->cppPtr.get() == *address2->cppPtr.get(); + return *address1->cppPtr == *address2->cppPtr; } const char *linphone_address_get_header (const LinphoneAddress *address, const char *header_name) { diff --git a/src/c-wrapper/c-tools.h b/src/c-wrapper/c-tools.h index e97368bcf..4878f60fb 100644 --- a/src/c-wrapper/c-tools.h +++ b/src/c-wrapper/c-tools.h @@ -38,24 +38,62 @@ private: std::shared_ptr cppPtr; }; + template + struct WrappedClonableObject { + belle_sip_object_t base; + T *cppPtr; + }; + public: template static inline decltype (std::declval().getPrivate()) getPrivate (T *object) { if (!object) - return nullptr; + return nullptr; return object->getPrivate(); } - template - static inline std::shared_ptr getCppPtrFromC (void *object) { + // --------------------------------------------------------------------------- + // Get c/cpp ptr helpers. + // --------------------------------------------------------------------------- + + template< + typename CppType, + typename CType, + typename std::enable_if::value>::type = 0 + > + static inline std::shared_ptr getCppPtrFromC (CType *object) { L_ASSERT(object); - return static_cast *>(object)->cppPtr; + return reinterpret_cast *>(object)->cppPtr; } - template - static inline std::shared_ptr getCppPtrFromC (const void *object) { + template< + typename CppType, + typename CType, + typename std::enable_if::value, CppType>::type = 0 + > + static inline std::shared_ptr getCppPtrFromC (const CType *object) { L_ASSERT(object); - return static_cast *>(object)->cppPtr; + return reinterpret_cast *>(object)->cppPtr; + } + + template< + typename CppType, + typename CType, + typename = typename std::enable_if::value, CppType>::type + > + static inline CppType *getCppPtrFromC (CType *object) { + L_ASSERT(object); + return reinterpret_cast *>(object)->cppPtr; + } + + template< + typename CppType, + typename CType, + typename = typename std::enable_if::value, CppType>::type + > + static inline const CppType *getCppPtrFromC (const CType *object) { + L_ASSERT(object); + return reinterpret_cast *>(object)->cppPtr; } template @@ -64,6 +102,18 @@ public: static_cast *>(object)->cppPtr = cppPtr; } + template + static T *getCppPtr (const std::shared_ptr &cppPtr) { + return cppPtr.get(); + } + + template + static T *getCppPtr (T *cppPtr) { + return cppPtr; + } + + // --------------------------------------------------------------------------- + template static inline bctbx_list_t * getCListFromCppList (std::list cppList) { bctbx_list_t *result = nullptr; @@ -116,6 +166,30 @@ LINPHONE_END_NAMESPACE FALSE \ ); +#define L_DECLARE_C_CLONABLE_STRUCT_IMPL(STRUCT, C_NAME) \ + struct _Linphone ## STRUCT { \ + belle_sip_object_t base; \ + LINPHONE_NAMESPACE::STRUCT *cppPtr; \ + }; \ + BELLE_SIP_DECLARE_VPTR_NO_EXPORT(Linphone ## STRUCT); \ + static Linphone ## STRUCT *_linphone_ ## C_NAME ## _init() { \ + return belle_sip_object_new(Linphone ## STRUCT); \ + } \ + static void _linphone_ ## C_NAME ## _uninit(Linphone ## STRUCT * object) { \ + delete object->cppPtr; \ + } \ + static void _linphone_ ## C_NAME ## _clone(Linphone ## STRUCT * dest, const Linphone ## STRUCT * src) { \ + L_ASSERT(src->cppPtr); \ + dest->cppPtr = new LINPHONE_NAMESPACE::STRUCT(*src->cppPtr); \ + } \ + BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(Linphone ## STRUCT); \ + BELLE_SIP_INSTANCIATE_VPTR(Linphone ## STRUCT, belle_sip_object_t, \ + _linphone_ ## C_NAME ## _uninit, \ + _linphone_ ## C_NAME ## _clone, \ + NULL, \ + FALSE \ + ); + #define L_DECLARE_C_STRUCT_NEW_DEFAULT(STRUCT, C_NAME) \ Linphone ## STRUCT * linphone_ ## C_NAME ## _new() { \ Linphone ## STRUCT * object = _linphone_ ## C_NAME ## _init(); \ @@ -127,7 +201,7 @@ LINPHONE_END_NAMESPACE #define L_C_TO_STRING(STR) ((STR) == NULL ? std::string() : (STR)) #define L_GET_CPP_PTR_FROM_C_STRUCT(OBJECT, TYPE) \ - LINPHONE_NAMESPACE::Wrapper::getCppPtrFromC(OBJECT) + LINPHONE_NAMESPACE::Wrapper::getCppPtrFromC(OBJECT) #define L_SET_CPP_PTR_FROM_C_STRUCT(OBJECT, CPP_PTR) \ LINPHONE_NAMESPACE::Wrapper::setCppPtrFromC(OBJECT, CPP_PTR) @@ -136,7 +210,9 @@ LINPHONE_END_NAMESPACE LINPHONE_NAMESPACE::Wrapper::getPrivate(OBJECT) #define L_GET_PRIVATE_FROM_C_STRUCT(OBJECT, TYPE) \ - L_GET_PRIVATE(L_GET_CPP_PTR_FROM_C_STRUCT(OBJECT, TYPE).get()) + L_GET_PRIVATE(LINPHONE_NAMESPACE::Wrapper::getCppPtr( \ + L_GET_CPP_PTR_FROM_C_STRUCT(OBJECT, TYPE) \ + )) #define L_GET_C_LIST_FROM_CPP_LIST(LIST, TYPE) \ LINPHONE_NAMESPACE::Wrapper::getCListFromCppList(LIST) diff --git a/src/chat/chat-room.cpp b/src/chat/chat-room.cpp index 8e1158644..b9000397d 100644 --- a/src/chat/chat-room.cpp +++ b/src/chat/chat-room.cpp @@ -909,4 +909,3 @@ const Address& ChatRoom::getPeerAddress () const { } LINPHONE_END_NAMESPACE - diff --git a/src/conference/session/media-session.cpp b/src/conference/session/media-session.cpp index 615f1bdf4..72f39635b 100644 --- a/src/conference/session/media-session.cpp +++ b/src/conference/session/media-session.cpp @@ -1224,7 +1224,7 @@ void MediaSessionPrivate::makeLocalMediaDescription () { md->nb_streams = (biggestDesc ? biggestDesc->nb_streams : 1); /* Re-check local ip address each time we make a new offer, because it may change in case of network reconnection */ - getLocalIp(*L_GET_CPP_PTR_FROM_C_STRUCT((direction == LinphoneCallOutgoing) ? log->to : log->from, Address).get()); + getLocalIp(*L_GET_CPP_PTR_FROM_C_STRUCT((direction == LinphoneCallOutgoing) ? log->to : log->from, Address)); strncpy(md->addr, mediaLocalIp.c_str(), sizeof(md->addr)); LinphoneAddress *addr = nullptr; if (destProxy) { diff --git a/tester/setup_tester.c b/tester/setup_tester.c index ba4956e5f..5f4e24890 100644 --- a/tester/setup_tester.c +++ b/tester/setup_tester.c @@ -42,7 +42,6 @@ static void core_init_test(void) { static void linphone_address_test(void) { linphone_address_unref(create_linphone_address(NULL)); BC_ASSERT_PTR_NULL(linphone_address_new("sip:@sip.linphone.org")); - } static void core_sip_transport_test(void) {