/* object.hh Copyright (C) 2017 Belledonne Communications SARL This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _LINPHONE_OBJECT_HH #define _LINPHONE_OBJECT_HH #include #include #include #include #ifndef LINPHONECXX_PUBLIC #if defined(_MSC_VER) #ifdef LINPHONECXX_EXPORTS #define LINPHONECXX_PUBLIC __declspec(dllexport) #else #define LINPHONECXX_PUBLIC __declspec(dllimport) #endif #else #define LINPHONECXX_PUBLIC #endif #endif #ifndef LINPHONECXX_DEPRECATED #if defined(_MSC_VER) #define LINPHONECXX_DEPRECATED __declspec(deprecated) #else #define LINPHONECXX_DEPRECATED __attribute__ ((deprecated)) #endif #endif namespace linphone { class Object: public std::enable_shared_from_this { public: Object(void *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; } } LINPHONECXX_PUBLIC void unsetData(const std::string &key); LINPHONECXX_PUBLIC bool dataExists(const std::string &key); public: template static std::shared_ptr cPtrToSharedPtr(void *ptr, bool takeRef=true) { if (ptr == NULL) { return nullptr; } else { Object *cppPtr = getBackPtrFromCPtr(ptr); if (cppPtr == NULL) { return std::make_shared(ptr, takeRef); } else { return std::static_pointer_cast(cppPtr->shared_from_this()); } } } template static std::shared_ptr cPtrToSharedPtr(const void *ptr, bool takeRef=true) { if (ptr == NULL) { return nullptr; } else { Object *cppPtr = getBackPtrFromCPtr(ptr); if (cppPtr == NULL) { return std::make_shared((void *)ptr, takeRef); } else { return std::static_pointer_cast(cppPtr->shared_from_this()); } } } static void *sharedPtrToCPtr(const std::shared_ptr &sharedPtr); private: LINPHONECXX_PUBLIC std::map &getUserData() const; static Object *getBackPtrFromCPtr(const void *ptr); 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: void *mPrivPtr; private: static const std::string sUserDataKey; }; class Listener {}; class ListenableObject: public Object { protected: ListenableObject(void *ptr, bool takeRef=true); void setListener(const std::shared_ptr &listener); public: static std::shared_ptr & getListenerFromObject(void *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(void *ptr, bool takeRef=true); virtual ~MultiListenableObject() {}; protected: void addListener(const std::shared_ptr &listener); void removeListener(const std::shared_ptr &listener); std::list > &getListeners() const; private: static void deleteListenerList(std::list > *listeners) {delete listeners;} private: static std::string sListenerListName; }; }; #endif // _LINPHONE_OBJECT_HH