#ifndef _LINPHONE_OBJECT_HH #define _LINPHONE_OBJECT_HH #include #include #include #include #include namespace linphone { class Object; class Listener; class AbstractBctbxListWrapper { public: AbstractBctbxListWrapper(): mCList(NULL) {} virtual ~AbstractBctbxListWrapper() {} ::bctbx_list_t *c_list() {return mCList;} protected: ::bctbx_list_t *mCList; }; template class ObjectBctbxListWrapper: public AbstractBctbxListWrapper { public: ObjectBctbxListWrapper(const std::list > &cppList); virtual ~ObjectBctbxListWrapper(); }; class StringBctbxListWrapper: public AbstractBctbxListWrapper { public: StringBctbxListWrapper(const std::list &cppList); virtual ~StringBctbxListWrapper(); }; class Object: public std::enable_shared_from_this { public: Object(::belle_sip_object_t *ptr, bool takeRef=true); virtual ~Object(); public: template void setData(const std::string &key, T &data) { std::map &userData = getUserData(); userData[key] = &data; } template T &getData(const std::string &key) { std::map &userData = getUserData(); void *ptr = userData[key]; if (ptr == NULL) { throw std::out_of_range("unknown data key [" + key + "]"); } else { return *(T *)ptr; } } void unsetData(const std::string &key); bool dataExists(const std::string &key); public: template static std::shared_ptr cPtrToSharedPtr(::belle_sip_object_t *ptr, bool takeRef=true) { if (ptr == NULL) { return nullptr; } else { T *cppPtr = (T *)belle_sip_object_data_get(ptr, "cpp_object"); if (cppPtr == NULL) { return std::make_shared(ptr, takeRef); } else { return std::static_pointer_cast(cppPtr->shared_from_this()); } } } static ::belle_sip_object_t *sharedPtrToCPtr(const std::shared_ptr &sharedPtr); protected: static std::string cStringToCpp(const char *cstr); static std::string cStringToCpp(char *cstr); static const char *cppStringToC(const std::string &cppstr); template static std::list > bctbxObjectListToCppList(const ::bctbx_list_t *bctbxList) { std::list > cppList; for(const ::bctbx_list_t *it=bctbxList; it!=NULL; it=it->next) { std::shared_ptr newObj = Object::cPtrToSharedPtr((::belle_sip_object_t *)it->data); cppList.push_back(newObj); } return cppList; } static std::list bctbxStringListToCppList(const ::bctbx_list_t *bctbxList); static std::list cStringArrayToCppList(const char **cArray); private: std::map &getUserData() const; template static void deleteSharedPtr(std::shared_ptr *ptr) {if (ptr != NULL) delete ptr;} static void deleteString(std::string *str) {if (str != NULL) delete str;} protected: ::belle_sip_object_t *mPrivPtr; private: static const std::string sUserDataKey; }; class Listener { public: Listener(): mCbs(NULL) {} virtual ~Listener() {setCallbacks(NULL);} public: void setCallbacks(::belle_sip_object_t *cbs) { if (mCbs != NULL) belle_sip_object_unref(mCbs); if (cbs == NULL) mCbs = NULL; else mCbs = belle_sip_object_ref(cbs); } belle_sip_object_t *getCallbacks() {return mCbs;} private: ::belle_sip_object_t *mCbs; }; class ListenableObject: public Object { protected: ListenableObject(::belle_sip_object_t *ptr, bool takeRef=true); void setListener(const std::shared_ptr &listener); protected: static std::shared_ptr & getListenerFromObject(::belle_sip_object_t *object); private: static void deleteListenerPtr(std::shared_ptr *ptr) {delete ptr;} private: static std::string sListenerDataName; }; class MultiListenableObject: public Object { friend class Factory; protected: MultiListenableObject(::belle_sip_object_t *ptr, bool takeRef=true); virtual ~MultiListenableObject(); protected: void addListener(const std::shared_ptr &listener); void removeListener(const std::shared_ptr &listener); private: static void deleteListenerList(std::list > *listeners) {delete listeners;} private: static std::string sListenerListName; }; }; #endif // _LINPHONE_OBJECT_HH