From a20b9a9441badf9fb139462604062feec3cb74de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Grisez?= Date: Thu, 16 Mar 2017 14:19:04 +0100 Subject: [PATCH] Make the C++ wrapper headers not depends on belle-sip and bctooblox headers --- wrappers/cpp/CMakeLists.txt | 1 + wrappers/cpp/class_header.mustache | 30 +------- wrappers/cpp/class_impl.mustache | 60 ++++++++------- wrappers/cpp/genwrapper.py | 24 +++--- wrappers/cpp/object.cc | 115 ++++++----------------------- wrappers/cpp/object.hh | 77 +++++-------------- wrappers/cpp/tools.cc | 81 ++++++++++++++++++++ wrappers/cpp/tools.hh | 88 ++++++++++++++++++++++ 8 files changed, 258 insertions(+), 218 deletions(-) create mode 100644 wrappers/cpp/tools.cc create mode 100644 wrappers/cpp/tools.hh diff --git a/wrappers/cpp/CMakeLists.txt b/wrappers/cpp/CMakeLists.txt index bb817038f..af9657294 100644 --- a/wrappers/cpp/CMakeLists.txt +++ b/wrappers/cpp/CMakeLists.txt @@ -8,6 +8,7 @@ add_custom_command(OUTPUT include/linphone++/linphone.hh src/linphone++.cc add_library(linphone++ SHARED object.cc + tools.cc ${CMAKE_CURRENT_BINARY_DIR}/src/linphone++.cc ) target_link_libraries(linphone++ diff --git a/wrappers/cpp/class_header.mustache b/wrappers/cpp/class_header.mustache index 4aca63452..160bb9b67 100644 --- a/wrappers/cpp/class_header.mustache +++ b/wrappers/cpp/class_header.mustache @@ -35,22 +35,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "config.hh" {{/isfactory}}{{/_class}} -#include "linphone/linphonecore.h" -#include "linphone/linphone_tunnel.h" -#include "linphone/linphonecore_utils.h" -#include "linphone/wrapper_utils.h" - -#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 namespace linphone { @@ -66,7 +50,7 @@ namespace linphone { public: {{#isNotListener}} - {{{className}}}(::belle_sip_object_t *ptr, bool takeRef=true); + {{{className}}}(void *ptr, bool takeRef=true); {{/isNotListener}} {{#ismonolistenable}} @@ -96,22 +80,16 @@ namespace linphone { {{{prototype}}} {{/staticMethods}} - + {{#ismultilistenable}} private: - static {{{cListenerName}}} *createCallbacks(void *userData); + static void *createCallbacks(void *userData); {{/ismultilistenable}} - {{#islistenable}} - private: - {{#wrapperCbs}} - {{decl}} - {{/wrapperCbs}} - {{/islistenable}} {{#ismultilistenable}} private: - {{{cListenerName}}} *mCallbacks; + void *mCallbacks; {{/ismultilistenable}} }; diff --git a/wrappers/cpp/class_impl.mustache b/wrappers/cpp/class_impl.mustache index 8e0c0e380..a9e3aec11 100644 --- a/wrappers/cpp/class_impl.mustache +++ b/wrappers/cpp/class_impl.mustache @@ -16,17 +16,41 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include +#include +#include +#include +#include #include "linphone++/linphone.hh" +#include "tools.hh" using namespace {{{namespace}}}; {{#classes}} -{{#isNotListener}} -{{{namespace}}}::{{{className}}}::{{{className}}}(::belle_sip_object_t *ptr, bool takeRef): {{{parentClassName}}}(ptr, takeRef) { +{{#wrapperCbs}} +static {{{returnType}}} {{{cbName}}}({{{declArgs}}}) { + {{#ismonolistenable}} + std::shared_ptr<{{{cppListenerName}}}> listener = std::static_pointer_cast<{{{cppListenerName}}},Listener>(ListenableObject::getListenerFromObject((::belle_sip_object_t *){{{firstArgName}}})); + {{#hasReturnValue}}return {{/hasReturnValue}}{{{cppMethodCallingLine}}}; + {{/ismonolistenable}} + {{#ismultilistenable}} - mCallbacks = createCallbacks(&getListeners()); - {{{callbacksAdder}}}(({{{cClassName}}} *)mPrivPtr, mCallbacks); + {{{cListenerName}}} *cbs = {{{currentCallbacksGetter}}}({{{firstArgName}}}); + std::list > &listeners = *(std::list > *){{{userDataGetter}}}(cbs); + for(auto it=listeners.begin(); it!=listeners.end(); it++) { + std::shared_ptr<{{{cppListenerName}}}> listener = std::static_pointer_cast<{{{cppListenerName}}},Listener>(*it); + {{{cppMethodCallingLine}}}; + } + {{/ismultilistenable}} +} +{{/wrapperCbs}} + +{{#isNotListener}} +{{{namespace}}}::{{{className}}}::{{{className}}}(void *ptr, bool takeRef): {{{parentClassName}}}(ptr, takeRef) { + {{#ismultilistenable}} + mCallbacks = ({{{cListenerName}}} *)createCallbacks(&getListeners()); + {{{callbacksAdder}}}(({{{cClassName}}} *)mPrivPtr, ({{{cListenerName}}} *)mCallbacks); {{/ismultilistenable}} } {{/isNotListener}} @@ -49,7 +73,7 @@ void {{{namespace}}}::{{{className}}}::setListener(const std::shared_ptr<{{{list {{#ismultilistenable}} {{{className}}}::~{{{className}}}() { - {{{callbacksRemover}}}(({{{cClassName}}} *)mPrivPtr, mCallbacks); + {{{callbacksRemover}}}(({{{cClassName}}} *)mPrivPtr, ({{{cListenerName}}} *)mCallbacks); belle_sip_object_unref(mCallbacks); } @@ -61,7 +85,7 @@ void {{{className}}}::removeListener(const std::shared_ptr<{{{listenerClassName} MultiListenableObject::removeListener(std::static_pointer_cast(listener)); } -{{{cListenerName}}} *{{{className}}}::createCallbacks(void *userData) { +void *{{{className}}}::createCallbacks(void *userData) { {{{cListenerName}}} *cbs = {{{listenerCreator}}}(linphone_factory_get()); {{#wrapperCbs}} {{{callbackSetter}}}(cbs, {{{cbName}}}); @@ -77,11 +101,11 @@ std::shared_ptr Factory::createCore(const std::shared_ptr & std::list > listeners; if (listener != nullptr) { listeners.push_back(std::static_pointer_cast(listener)); - cbs = Core::createCallbacks(&listeners); + cbs = (::LinphoneCoreCbs *)Core::createCallbacks(&listeners); } ::LinphoneFactory *factory = linphone_factory_get(); - ::LinphoneCore *core_ptr = linphone_factory_create_core(factory, cbs, cppStringToC(configPath), cppStringToC(factoryConfigPath)); + ::LinphoneCore *core_ptr = linphone_factory_create_core(factory, cbs, StringUtilities::cppStringToC(configPath), StringUtilities::cppStringToC(factoryConfigPath)); if (cbs != NULL) { linphone_core_remove_callbacks(core_ptr, cbs); @@ -98,7 +122,7 @@ std::shared_ptr Factory::createCoreWithConfig(const std::shared_ptr > listeners; if (listener != nullptr) { listeners.push_back(std::static_pointer_cast(listener)); - cbs = Core::createCallbacks(&listeners); + cbs = (::LinphoneCoreCbs *)Core::createCallbacks(&listeners); } ::LinphoneFactory *factory = linphone_factory_get(); @@ -133,22 +157,4 @@ std::shared_ptr &Vcard::getVcard() { } {{/staticMethods}} -{{#wrapperCbs}} -{{{returnType}}} {{{className}}}::{{{cbName}}}({{{declArgs}}}) { - {{#ismonolistenable}} - std::shared_ptr<{{{cppListenerName}}}> listener = std::static_pointer_cast<{{{cppListenerName}}},Listener>(getListenerFromObject((::belle_sip_object_t *){{{firstArgName}}})); - {{#hasReturnValue}}return {{/hasReturnValue}}{{{cppMethodCallingLine}}}; - {{/ismonolistenable}} - - {{#ismultilistenable}} - {{{cListenerName}}} *cbs = {{{currentCallbacksGetter}}}({{{firstArgName}}}); - std::list > &listeners = *(std::list > *){{{userDataGetter}}}(cbs); - for(auto it=listeners.begin(); it!=listeners.end(); it++) { - std::shared_ptr<{{{cppListenerName}}}> listener = std::static_pointer_cast<{{{cppListenerName}}},Listener>(*it); - {{{cppMethodCallingLine}}}; - } - {{/ismultilistenable}} -} -{{/wrapperCbs}} - {{/classes}} diff --git a/wrappers/cpp/genwrapper.py b/wrappers/cpp/genwrapper.py index 36cd6a0e4..14c94fa1c 100755 --- a/wrappers/cpp/genwrapper.py +++ b/wrappers/cpp/genwrapper.py @@ -132,8 +132,7 @@ class CppTranslator(object): listenedClass = method.find_first_ancestor_by_type(AbsApi.Interface).listenedClass params = {} - params['name'] = method.name.to_camel_case(lower=True)[2:] + 'Cb' - params['name'] = params['name'][0].lower() + params['name'][1:] + params['name'] = method.name.to_snake_case(fullName=True) + '_cb' args = [] wrappedArgs = [] for arg in method.args: @@ -143,11 +142,8 @@ class CppTranslator(object): params['returnType'] = method.returnType.cname wrapperCbDict = {} - wrapperCbDict['decl'] = 'static {returnType} {name}({params});'.format(**params) wrapperCbDict['cbName'] = params['name'] wrapperCbDict['declArgs'] = params['params'] - #wrapperCbDict['methodName'] = method.name.to_camel_case(lower=True) - #wrapperCbDict['wrappedArgs'] = ', '.join(wrappedArgs) wrapperCbDict['firstArgName'] = method.args[0].name.to_c() wrapperCbDict['returnType'] = params['returnType'] wrapperCbDict['hasReturnValue'] = (params['returnType'] != 'void') @@ -218,7 +214,7 @@ class CppTranslator(object): else: methodElems['methodType'] = '' - methodElems['deprecated'] = 'LINPHONE_DEPRECATED ' if method.deprecated else '' + methodElems['deprecated'] = 'LINPHONECXX_DEPRECATED ' if method.deprecated else '' methodDict = {} methodDict['prototype'] = 'LINPHONECXX_PUBLIC {deprecated}{methodType}{return} {name}({params}){const}{semicolon}'.format(**methodElems) @@ -275,7 +271,7 @@ class CppTranslator(object): def _wrap_cpp_expression_to_c(self, cppExpr, exprtype, usedNamespace=None): if type(exprtype) is AbsApi.BaseType: if exprtype.name == 'string': - cExpr = 'cppStringToC({0})'.format(cppExpr); + cExpr = 'StringUtilities::cppStringToC({0})'.format(cppExpr); elif exprtype.name not in ['void', 'string', 'string_array'] and exprtype.isref: cExpr = '&' + cppExpr else: @@ -289,7 +285,7 @@ class CppTranslator(object): param['cPtrType'] = exprtype.desc.name.to_c() param['cppExpr'] = cppExpr param['object'] = 'const Object' if exprtype.isconst else 'Object' - cExpr = '(::{cPtrType} *)sharedPtrToCPtr(std::static_pointer_cast<{object},{ptrType}>({cppExpr}))'.format(**param) + cExpr = '(::{cPtrType} *)Object::sharedPtrToCPtr(std::static_pointer_cast<{object},{ptrType}>({cppExpr}))'.format(**param) elif type(exprtype) is AbsApi.ListType: if type(exprtype.containedTypeDesc) is AbsApi.BaseType and exprtype.containedTypeDesc.name == 'string': cExpr = 'StringBctbxListWrapper({0}).c_list()'.format(cppExpr) @@ -307,9 +303,9 @@ class CppTranslator(object): if exprtype.name == 'void' and not exprtype.isref: return cExpr elif exprtype.name == 'string': - return 'cStringToCpp({0})'.format(cExpr) + return 'StringUtilities::cStringToCpp({0})'.format(cExpr) elif exprtype.name == 'string_array': - return 'cStringArrayToCppList({0})'.format(cExpr) + return 'StringUtilities::cStringArrayToCppList({0})'.format(cExpr) elif exprtype.name == 'boolean': return '({0} != FALSE)'.format(cExpr) else: @@ -322,16 +318,16 @@ class CppTranslator(object): cppReturnType = CppTranslator.sharedPtrTypeExtractor.match(cppReturnType).group(2) if type(exprtype.parent) is AbsApi.Method and len(exprtype.parent.name.words) >=1 and (exprtype.parent.name.words == ['new'] or exprtype.parent.name.words[0] == 'create'): - return 'cPtrToSharedPtr<{0}>((::belle_sip_object_t *){1}, false)'.format(cppReturnType, cExpr) + return 'Object::cPtrToSharedPtr<{0}>((::belle_sip_object_t *){1}, false)'.format(cppReturnType, cExpr) else: - return 'cPtrToSharedPtr<{0}>((::belle_sip_object_t *){1})'.format(cppReturnType, cExpr) + return 'Object::cPtrToSharedPtr<{0}>((::belle_sip_object_t *){1})'.format(cppReturnType, cExpr) elif type(exprtype) is AbsApi.ListType: if type(exprtype.containedTypeDesc) is AbsApi.BaseType and exprtype.containedTypeDesc.name == 'string': - return 'bctbxStringListToCppList({0})'.format(cExpr) + return 'StringBctbxListWrapper::bctbxListToCppList({0})'.format(cExpr) elif type(exprtype.containedTypeDesc) is AbsApi.ClassType: cppReturnType = CppTranslator.translate_class_type(self, exprtype.containedTypeDesc, namespace=usedNamespace) cppReturnType = CppTranslator.sharedPtrTypeExtractor.match(cppReturnType).group(2) - return 'bctbxObjectListToCppList<{0}>({1})'.format(cppReturnType, cExpr) + return 'ObjectBctbxListWrapper<{0}>::bctbxListToCppList({1})'.format(cppReturnType, cExpr) else: raise AbsApi.Error('translation of bctbx_list_t of enums or basic C types is not supported') else: diff --git a/wrappers/cpp/object.cc b/wrappers/cpp/object.cc index a4d590e78..eb99658d8 100644 --- a/wrappers/cpp/object.cc +++ b/wrappers/cpp/object.cc @@ -19,6 +19,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "object.hh" #include +#include #include #include #include @@ -26,49 +27,18 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. using namespace linphone; using namespace std; -template -ObjectBctbxListWrapper::ObjectBctbxListWrapper(const std::list > &cppList): AbstractBctbxListWrapper() { - for(auto it=cppList.cbegin(); it!=cppList.cend(); it++) { - ::belle_sip_object_t *cPtr = Object::sharedPtrToCPtr(static_pointer_cast(*it)); - if (cPtr != NULL) belle_sip_object_ref(cPtr); - mCList = bctbx_list_append(mCList, cPtr); - } -} - -static void unrefData(void *data) { - if (data != NULL) belle_sip_object_unref(data); -} - -template -ObjectBctbxListWrapper::~ObjectBctbxListWrapper() { - mCList = bctbx_list_free_with_data(mCList, unrefData); -} - -StringBctbxListWrapper::StringBctbxListWrapper(const std::list &cppList): AbstractBctbxListWrapper() { - for(auto it=cppList.cbegin(); it!=cppList.cend(); it++) { - char *buffer = (char *)malloc(it->length()+1); - strcpy(buffer, it->c_str()); - mCList = bctbx_list_append(mCList, buffer); - } -} - -StringBctbxListWrapper::~StringBctbxListWrapper() { - mCList = bctbx_list_free_with_data(mCList, free); -} - - const std::string Object::sUserDataKey = "cppUserData"; -Object::Object(::belle_sip_object_t *ptr, bool takeRef): +Object::Object(void *ptr, bool takeRef): enable_shared_from_this(), mPrivPtr(ptr) { if(takeRef) belle_sip_object_ref(mPrivPtr); - belle_sip_object_data_set(ptr, "cpp_object", this, NULL); + belle_sip_object_data_set((belle_sip_object_t *)ptr, "cpp_object", this, NULL); } Object::~Object() { if(mPrivPtr != NULL) { - belle_sip_object_data_set(mPrivPtr, "cpp_object", NULL, NULL); + belle_sip_object_data_set((::belle_sip_object_t *)mPrivPtr, "cpp_object", NULL, NULL); belle_sip_object_unref(mPrivPtr); } } @@ -84,109 +54,70 @@ bool Object::dataExists(const std::string &key) { return userData.find(key) != userData.end(); } -::belle_sip_object_t *Object::sharedPtrToCPtr(const std::shared_ptr &sharedPtr) { +void *linphone::Object::sharedPtrToCPtr(const std::shared_ptr< const linphone::Object > &sharedPtr) { if (sharedPtr == nullptr) return NULL; else return sharedPtr->mPrivPtr; } -std::string Object::cStringToCpp(const char *cstr) { - if (cstr == NULL) { - return std::string(); - } else { - return std::string(cstr); - } -} - -std::string Object::cStringToCpp(char *cstr) { - if (cstr == NULL) { - return std::string(); - } else { - std::string cppStr = cstr; - bctbx_free(cstr); - return cppStr; - } -} - -const char *Object::cppStringToC(const std::string &cppstr) { - if (cppstr.empty()) { - return NULL; - } else { - return cppstr.c_str(); - } -} - -list Object::bctbxStringListToCppList(const ::bctbx_list_t *bctbxList) { - list cppList; - for(const ::bctbx_list_t *it=bctbxList; it!=NULL; it=it->next) { - cppList.push_back(string((char *)it->data)); - } - return cppList; -} - -std::list Object::cStringArrayToCppList(const char **cArray) { - list cppList; - int i; - for(i=0; cArray[i]!=NULL; i++) { - cppList.push_back(cArray[i]); - } - return cppList; -} - static void deleteCppUserDataMap(std::map *userDataMap) { delete userDataMap; } std::map &Object::getUserData() const { - map *userData = (map *)belle_sip_object_data_get(mPrivPtr, sUserDataKey.c_str()); + map *userData = (map *)belle_sip_object_data_get((::belle_sip_object_t *)mPrivPtr, sUserDataKey.c_str()); if (userData == NULL) { userData = new map(); - belle_sip_object_data_set(mPrivPtr, sUserDataKey.c_str(), userData, (belle_sip_data_destroy)deleteCppUserDataMap); + belle_sip_object_data_set((::belle_sip_object_t *)mPrivPtr, sUserDataKey.c_str(), userData, (belle_sip_data_destroy)deleteCppUserDataMap); } return *userData; } +Object *Object::getBackPtrFromCPtr(void *ptr) { + return (Object *)belle_sip_object_data_get((::belle_sip_object_t *)ptr, "cpp_object"); +} + std::string ListenableObject::sListenerDataName = "cpp_listener"; -ListenableObject::ListenableObject(::belle_sip_object_t *ptr, bool takeRef): Object(ptr, takeRef) { - shared_ptr *cppListener = (shared_ptr *)belle_sip_object_data_get(mPrivPtr, sListenerDataName.c_str()); +ListenableObject::ListenableObject(void *ptr, bool takeRef): Object(ptr, takeRef) { + shared_ptr *cppListener = (shared_ptr *)belle_sip_object_data_get((::belle_sip_object_t *)mPrivPtr, sListenerDataName.c_str()); if (cppListener == NULL) { cppListener = new shared_ptr(); - belle_sip_object_data_set(mPrivPtr, sListenerDataName.c_str(), cppListener, (belle_sip_data_destroy)deleteListenerPtr); + belle_sip_object_data_set((::belle_sip_object_t *)mPrivPtr, sListenerDataName.c_str(), cppListener, (belle_sip_data_destroy)deleteListenerPtr); } } void ListenableObject::setListener(const std::shared_ptr &listener) { - shared_ptr &curListener = *(shared_ptr *)belle_sip_object_data_get(mPrivPtr, sListenerDataName.c_str()); + shared_ptr &curListener = *(shared_ptr *)belle_sip_object_data_get((::belle_sip_object_t *)mPrivPtr, sListenerDataName.c_str()); curListener = listener; } -std::shared_ptr & ListenableObject::getListenerFromObject(::belle_sip_object_t *object) { - return *(std::shared_ptr *)belle_sip_object_data_get(object, sListenerDataName.c_str()); +std::shared_ptr & ListenableObject::getListenerFromObject(void *object) { + return *(std::shared_ptr *)belle_sip_object_data_get((::belle_sip_object_t *)object, sListenerDataName.c_str()); } std::string MultiListenableObject::sListenerListName = "cpp_listeners"; -MultiListenableObject::MultiListenableObject(::belle_sip_object_t *ptr, bool takeRef): Object(ptr, takeRef) { +MultiListenableObject::MultiListenableObject(void *ptr, bool takeRef): Object(ptr, takeRef) { if (ptr != NULL) { - if (belle_sip_object_data_get(ptr, sListenerListName.c_str()) == NULL) { + if (belle_sip_object_data_get((::belle_sip_object_t *)ptr, sListenerListName.c_str()) == NULL) { list > *listeners = new list >; - belle_sip_object_data_set(ptr, sListenerListName.c_str(), listeners, (belle_sip_data_destroy)deleteListenerList); + belle_sip_object_data_set((::belle_sip_object_t *)ptr, sListenerListName.c_str(), listeners, (belle_sip_data_destroy)deleteListenerList); } } } std::list > &MultiListenableObject::getListeners() const { - return *(std::list > *)belle_sip_object_data_get(mPrivPtr, sListenerListName.c_str()); + return *(std::list > *)belle_sip_object_data_get((::belle_sip_object_t *)mPrivPtr, sListenerListName.c_str()); } void MultiListenableObject::addListener(const std::shared_ptr &listener) { - std::list > &listeners = *(std::list > *)belle_sip_object_data_get(mPrivPtr, sListenerListName.c_str()); + std::list > &listeners = *(std::list > *)belle_sip_object_data_get((::belle_sip_object_t *)mPrivPtr, sListenerListName.c_str()); listeners.push_back(listener); } void MultiListenableObject::removeListener(const std::shared_ptr &listener) { - std::list > &listeners = *(std::list > *)belle_sip_object_data_get(mPrivPtr, sListenerListName.c_str()); + std::list > &listeners = *(std::list > *)belle_sip_object_data_get((::belle_sip_object_t *)mPrivPtr, sListenerListName.c_str()); listeners.remove(listener); } diff --git a/wrappers/cpp/object.hh b/wrappers/cpp/object.hh index 3d41db0ea..c124eb8fd 100644 --- a/wrappers/cpp/object.hh +++ b/wrappers/cpp/object.hh @@ -23,8 +23,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include #include #include -#include -#include #ifndef LINPHONECXX_PUBLIC #if defined(_MSC_VER) @@ -38,41 +36,19 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #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; - 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); + Object(void *ptr, bool takeRef=true); virtual ~Object(); public: @@ -96,11 +72,11 @@ namespace linphone { public: template - static std::shared_ptr cPtrToSharedPtr(::belle_sip_object_t *ptr, bool takeRef=true) { + static std::shared_ptr cPtrToSharedPtr(void *ptr, bool takeRef=true) { if (ptr == NULL) { return nullptr; } else { - T *cppPtr = (T *)belle_sip_object_data_get(ptr, "cpp_object"); + Object *cppPtr = getBackPtrFromCPtr(ptr); if (cppPtr == NULL) { return std::make_shared(ptr, takeRef); } else { @@ -108,33 +84,16 @@ namespace linphone { } } } - 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); + static void *sharedPtrToCPtr(const std::shared_ptr &sharedPtr); private: LINPHONECXX_PUBLIC std::map &getUserData() const; + static Object *getBackPtrFromCPtr(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: - ::belle_sip_object_t *mPrivPtr; + void *mPrivPtr; private: static const std::string sUserDataKey; @@ -146,11 +105,11 @@ namespace linphone { class ListenableObject: public Object { protected: - ListenableObject(::belle_sip_object_t *ptr, bool takeRef=true); + ListenableObject(void *ptr, bool takeRef=true); void setListener(const std::shared_ptr &listener); - protected: - static std::shared_ptr & getListenerFromObject(::belle_sip_object_t *object); + public: + static std::shared_ptr & getListenerFromObject(void *object); private: static void deleteListenerPtr(std::shared_ptr *ptr) {delete ptr;} @@ -163,7 +122,7 @@ namespace linphone { friend class Factory; protected: - MultiListenableObject(::belle_sip_object_t *ptr, bool takeRef=true); + MultiListenableObject(void *ptr, bool takeRef=true); virtual ~MultiListenableObject() {}; protected: diff --git a/wrappers/cpp/tools.cc b/wrappers/cpp/tools.cc new file mode 100644 index 000000000..9f7cdc9a7 --- /dev/null +++ b/wrappers/cpp/tools.cc @@ -0,0 +1,81 @@ +/* +tools.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. +*/ + +#include "tools.hh" +#include "object.hh" +#include + +using namespace linphone; +using namespace std; + + +StringBctbxListWrapper::StringBctbxListWrapper(const std::list &cppList): AbstractBctbxListWrapper() { + for(auto it=cppList.cbegin(); it!=cppList.cend(); it++) { + char *buffer = (char *)malloc(it->length()+1); + strcpy(buffer, it->c_str()); + mCList = bctbx_list_append(mCList, buffer); + } +} + +StringBctbxListWrapper::~StringBctbxListWrapper() { + mCList = bctbx_list_free_with_data(mCList, free); +} + +list StringBctbxListWrapper::bctbxListToCppList(const ::bctbx_list_t *bctbxList) { + list cppList; + for(const ::bctbx_list_t *it=bctbxList; it!=NULL; it=it->next) { + cppList.push_back(string((char *)it->data)); + } + return cppList; +} + +std::string StringUtilities::cStringToCpp(const char *cstr) { + if (cstr == NULL) { + return std::string(); + } else { + return std::string(cstr); + } +} + +std::string StringUtilities::cStringToCpp(char *cstr) { + if (cstr == NULL) { + return std::string(); + } else { + std::string cppStr = cstr; + bctbx_free(cstr); + return cppStr; + } +} + +const char *StringUtilities::cppStringToC(const std::string &cppstr) { + if (cppstr.empty()) { + return NULL; + } else { + return cppstr.c_str(); + } +} + +std::list StringUtilities::cStringArrayToCppList(const char **cArray) { + list cppList; + int i; + for(i=0; cArray[i]!=NULL; i++) { + cppList.push_back(cArray[i]); + } + return cppList; +} diff --git a/wrappers/cpp/tools.hh b/wrappers/cpp/tools.hh new file mode 100644 index 000000000..81c5dbcdb --- /dev/null +++ b/wrappers/cpp/tools.hh @@ -0,0 +1,88 @@ +/* +tools.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 _TOOLS_HH +#define _TOOLS_HH + +#include +#include +#include +#include +#include "object.hh" + +namespace linphone { + + 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) { + for(auto it=cppList.cbegin(); it!=cppList.cend(); it++) { + ::belle_sip_object_t *cPtr = (::belle_sip_object_t *)Object::sharedPtrToCPtr(std::static_pointer_cast(*it)); + if (cPtr != NULL) belle_sip_object_ref(cPtr); + mCList = bctbx_list_append(mCList, cPtr); + } + } + virtual ~ObjectBctbxListWrapper() { + mCList = bctbx_list_free_with_data(mCList, unrefData); + } + static std::list > bctbxListToCppList(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(it->data); + cppList.push_back(newObj); + } + return cppList; + } + + private: + static void unrefData(void *data) { + if (data != NULL) belle_sip_object_unref(data); + } + }; + + + class StringBctbxListWrapper: public AbstractBctbxListWrapper { + public: + StringBctbxListWrapper(const std::list &cppList); + virtual ~StringBctbxListWrapper(); + static std::list bctbxListToCppList(const ::bctbx_list_t *bctbxList); + }; + + class StringUtilities { + public: + static std::string cStringToCpp(const char *cstr); + static std::string cStringToCpp(char *cstr); + static const char *cppStringToC(const std::string &cppstr); + static std::list cStringArrayToCppList(const char **cArray); + }; + +}; + +#endif // _TOOLS_HH