From f18fcbdf2f2bbdc5c34f0ec9160d19f17e3586da Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Tue, 7 Nov 2017 10:12:29 +0100 Subject: [PATCH] feat(c-wrapper): misc => - use correct macro in Wrapped DialPlan - add a type verification in c object declaration (compil time) - reset c back pointer if belle sip object is destroyed before cpp object --- src/c-wrapper/api/c-dial-plan.cpp | 2 +- src/c-wrapper/internal/c-tools.h | 167 +++++++++++++++++------------- 2 files changed, 97 insertions(+), 72 deletions(-) diff --git a/src/c-wrapper/api/c-dial-plan.cpp b/src/c-wrapper/api/c-dial-plan.cpp index 7dc7ef030..a3aad76fb 100644 --- a/src/c-wrapper/api/c-dial-plan.cpp +++ b/src/c-wrapper/api/c-dial-plan.cpp @@ -27,7 +27,7 @@ using namespace std; -L_DECLARE_C_OBJECT_IMPL(DialPlan); +L_DECLARE_C_CLONABLE_OBJECT_IMPL(DialPlan); LinphoneDialPlan *linphone_dial_plan_ref (LinphoneDialPlan *dp) { return reinterpret_cast(belle_sip_object_ref(dp)); diff --git a/src/c-wrapper/internal/c-tools.h b/src/c-wrapper/internal/c-tools.h index 0b94a1681..75ec2445e 100644 --- a/src/c-wrapper/internal/c-tools.h +++ b/src/c-wrapper/internal/c-tools.h @@ -61,62 +61,62 @@ struct CTypeMetaInfo { typedef void cppType; }; +// --------------------------------------------------------------------------- +// IsCppObject traits. +// --------------------------------------------------------------------------- + +template +struct IsCppObject { + enum { + value = std::is_base_of::value || std::is_base_of::value + }; +}; + +template +struct IsPrivateCppObject { + enum { + value = std::is_base_of::value || + std::is_base_of::value + }; +}; + +template +struct IsRegisteredCppObject { + enum { + value = CppTypeMetaInfo::defined && ( + !CppTypeMetaInfo::isSubtype || + std::is_base_of::cType>::cppType, CppType>::value + ) + }; +}; + +// --------------------------------------------------------------------------- +// IsDefined traits. +// --------------------------------------------------------------------------- + +template +struct IsDefinedBaseCppObject { + enum { + value = IsRegisteredCppObject::value && std::is_base_of::value + }; +}; + +template +struct IsDefinedCppObject { + enum { + value = IsDefinedBaseCppObject::value && std::is_base_of::value + }; +}; + +template +struct IsDefinedClonableCppObject { + enum { + value = IsRegisteredCppObject::value && std::is_base_of::value + }; +}; + class Wrapper { private: - // --------------------------------------------------------------------------- - // IsCppObject traits. - // --------------------------------------------------------------------------- - - template - struct IsCppObject { - enum { - value = std::is_base_of::value || std::is_base_of::value - }; - }; - - template - struct IsPrivateCppObject { - enum { - value = std::is_base_of::value || - std::is_base_of::value - }; - }; - - template - struct IsRegisteredCppObject { - enum { - value = CppTypeMetaInfo::defined && ( - !CppTypeMetaInfo::isSubtype || - std::is_base_of::cType>::cppType, CppType>::value - ) - }; - }; - - // --------------------------------------------------------------------------- - // IsDefined traits. - // --------------------------------------------------------------------------- - - template - struct IsDefinedBaseCppObject { - enum { - value = IsRegisteredCppObject::value && std::is_base_of::value - }; - }; - - template - struct IsDefinedCppObject { - enum { - value = IsDefinedBaseCppObject::value && std::is_base_of::value - }; - }; - - template - struct IsDefinedClonableCppObject { - enum { - value = IsRegisteredCppObject::value && std::is_base_of::value - }; - }; - // --------------------------------------------------------------------------- // Wrapped Objects. // --------------------------------------------------------------------------- @@ -215,12 +215,31 @@ public: // --------------------------------------------------------------------------- template< - typename CppType, - typename = typename std::enable_if::value, CppType>::type + typename CType, + typename CppType = typename CTypeMetaInfo::cppType, + typename = typename std::enable_if::value, CppType>::type > - static void resetCBackPtr (const std::shared_ptr &cppObject) { + static void uninitBaseCppObject (CType *cObject) { + WrappedBaseObject *wrappedObject = reinterpret_cast *>(cObject); + + std::shared_ptr cppObject = wrappedObject->owner == WrappedObjectOwner::Internal + ? wrappedObject->weakCppPtr.lock() + : wrappedObject->cppPtr; + if (cppObject) - cppObject->setCBackPtr(nullptr); + cppObject->setCBackPtr(nullptr); \ + + wrappedObject->cppPtr.~shared_ptr(); + wrappedObject->weakCppPtr.~weak_ptr(); + } + + template< + typename CType, + typename CppType = typename CTypeMetaInfo::cppType, + typename = typename std::enable_if::value, CppType>::type + > + static void uninitClonableCppObject (CType *cObject) { + delete reinterpret_cast *>(cObject)->cppPtr; } // --------------------------------------------------------------------------- @@ -261,10 +280,11 @@ public: typename = typename std::enable_if::value, CppType>::type > static void signalCppPtrDestruction (CppType *cppObject) { - //void *value = cppObject->getCBackPtr(); - //TODO - /*if (value && static_cast *>(value)->owner == WrappedObjectOwner::Internal) - belle_sip_object_unref(value);*/ + // TODO: Remove commented section in the future. + // Repair message storage first. + // void *value = cppObject->getCBackPtr(); + // if (value && static_cast *>(value)->owner == WrappedObjectOwner::Internal) + // belle_sip_object_unref(value); } // --------------------------------------------------------------------------- @@ -570,6 +590,12 @@ LINPHONE_END_NAMESPACE #define L_INTERNAL_DECLARE_C_OBJECT(C_TYPE, CPP_TYPE, ...) \ static_assert(LinphonePrivate::CTypeMetaInfo::defined, "Type is not defined."); \ + static_assert( \ + LinphonePrivate::IsDefinedBaseCppObject< \ + LinphonePrivate::CTypeMetaInfo::cppType \ + >::value, \ + "Type is not declared as base object." \ + ); \ struct _Linphone ## C_TYPE { \ belle_sip_object_t base; \ std::shared_ptr cppPtr; \ @@ -589,14 +615,7 @@ LINPHONE_END_NAMESPACE } \ static void _linphone_ ## C_TYPE ## _uninit(Linphone ## C_TYPE * object) { \ DESTRUCTOR(object); \ - { \ - std::shared_ptr wrappedObject = object->weakCppPtr.lock(); \ - if (!wrappedObject) \ - wrappedObject = object->cppPtr; \ - LinphonePrivate::Wrapper::resetCBackPtr(wrappedObject); \ - } \ - object->cppPtr.~shared_ptr(); \ - object->weakCppPtr.~weak_ptr(); \ + LinphonePrivate::Wrapper::uninitBaseCppObject(object); \ } \ BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(Linphone ## C_TYPE); \ BELLE_SIP_INSTANCIATE_VPTR2( \ @@ -680,6 +699,12 @@ LINPHONE_END_NAMESPACE // Declare clonable wrapped C object. #define L_DECLARE_C_CLONABLE_OBJECT_IMPL(C_TYPE, ...) \ static_assert(LinphonePrivate::CTypeMetaInfo::defined, "Type is not defined."); \ + static_assert( \ + LinphonePrivate::IsDefinedClonableCppObject< \ + LinphonePrivate::CTypeMetaInfo::cppType \ + >::value, \ + "Type is not declared as clonable object." \ + ); \ struct _Linphone ## C_TYPE { \ belle_sip_object_t base; \ L_CPP_TYPE_OF_C_TYPE(C_TYPE) *cppPtr; \ @@ -690,7 +715,7 @@ LINPHONE_END_NAMESPACE return belle_sip_object_new(Linphone ## C_TYPE); \ } \ static void _linphone_ ## C_TYPE ## _uninit(Linphone ## C_TYPE * object) { \ - delete object->cppPtr; \ + LinphonePrivate::Wrapper::uninitClonableCppObject(object); \ } \ static void _linphone_ ## C_TYPE ## _clone(Linphone ## C_TYPE * dest, const Linphone ## C_TYPE * src) { \ L_ASSERT(src->cppPtr); \