forked from mirrors/linphone-iphone
C++ wrapper: pubilc structures support
This commit is contained in:
parent
3ec8d3669d
commit
26c0dccfeb
8 changed files with 207 additions and 70 deletions
|
|
@ -38,6 +38,7 @@ target_link_libraries(linphone++
|
|||
target_include_directories(linphone++
|
||||
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/include
|
||||
PRIVATE ${CMAKE_BINARY_DIR}/include
|
||||
PRIVATE ${CMAKE_SOURCE_DIR}/include
|
||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
PRIVATE ${BCTOOLBOX_INCLUDE_DIRS}
|
||||
PRIVATE ${BELLESIP_INCLUDE_DIRS}
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ class ArgName(Name):
|
|||
return Name.to_snake_case(self)
|
||||
|
||||
|
||||
class PropertyName(Name):
|
||||
class PropertyName(ArgName):
|
||||
pass
|
||||
|
||||
|
||||
|
|
@ -357,6 +357,7 @@ class Property(DocumentableObject):
|
|||
DocumentableObject.__init__(self, name)
|
||||
self._setter = None
|
||||
self._getter = None
|
||||
self._type = None
|
||||
|
||||
def set_setter(self, setter):
|
||||
self._setter = setter
|
||||
|
|
@ -367,6 +368,8 @@ class Property(DocumentableObject):
|
|||
|
||||
def set_getter(self, getter):
|
||||
self._getter = getter
|
||||
if self._type is None:
|
||||
self._type = getter.returnType
|
||||
getter.parent = self
|
||||
|
||||
def get_getter(self):
|
||||
|
|
@ -384,6 +387,7 @@ class Class(DocumentableObject):
|
|||
self.classMethods = []
|
||||
self._listenerInterface = None
|
||||
self.multilistener = False
|
||||
self.refcountable = False
|
||||
|
||||
def add_property(self, property):
|
||||
self.properties.append(property)
|
||||
|
|
@ -482,13 +486,21 @@ class CParser(object):
|
|||
'linphone_friend_new', # was deprecated when the wrapper generator was made
|
||||
'linphone_friend_new_with_address', # was deprecated when the wrapper generator was made
|
||||
'linphone_core_get_sound_source', # was deprecated when the wrapper generator was made
|
||||
'linphone_core_set_sound_source'] # was deprecated when the wrapper generator was made
|
||||
'linphone_core_set_sound_source', # was deprecated when the wrapper generator was made
|
||||
'linphone_core_get_sip_transports', # not wrappable
|
||||
'linphone_core_get_sip_transports_used'] # not wrappable
|
||||
|
||||
self.classBl = ['LinphoneImEncryptionEngine',
|
||||
'LinphoneImEncryptionEngineCbs',
|
||||
'LinphoneImNotifPolicy',
|
||||
'LpConfig',
|
||||
'LinphoneCallStats'] # temporarly blacklisted
|
||||
'LinphoneErrorInfo',
|
||||
'LinphonePayloadType',
|
||||
'LinphonePlayer'] # temporarly blacklisted
|
||||
|
||||
# list of classes that must be concidered as refcountable even if
|
||||
# they are no ref()/unref() methods
|
||||
self.forcedRefcountableClasses = ['LinphoneFactory']
|
||||
|
||||
self.cProject = cProject
|
||||
|
||||
|
|
@ -531,8 +543,19 @@ class CParser(object):
|
|||
pass
|
||||
except Error as e:
|
||||
print('Could not parse \'{0}\' class: {1}'.format(_class.name, e.args[0]))
|
||||
|
||||
CParser._fix_all_types(self)
|
||||
|
||||
|
||||
def _class_is_refcountable(self, _class):
|
||||
if _class.name in self.forcedRefcountableClasses:
|
||||
return True
|
||||
|
||||
for method in _class.instanceMethods:
|
||||
if method.startswith(_class.cFunctionPrefix) and method[len(_class.cFunctionPrefix):] == 'ref':
|
||||
return True
|
||||
return False
|
||||
|
||||
def _fix_all_types(self):
|
||||
for _class in self.classesIndex.values() + self.interfacesIndex.values():
|
||||
if _class is not None:
|
||||
|
|
@ -563,24 +586,24 @@ class CParser(object):
|
|||
except Error as e:
|
||||
print('warning: some types could not be fixed in {0}() function: {1}'.format(method.name.to_snake_case(fullName=True), e.args[0]))
|
||||
|
||||
def _fix_type(self, type):
|
||||
if isinstance(type, EnumType) and type.desc is None:
|
||||
type.desc = self.enumsIndex[type.name]
|
||||
elif isinstance(type, ClassType) and type.desc is None:
|
||||
if type.name in self.classesIndex:
|
||||
type.desc = self.classesIndex[type.name]
|
||||
def _fix_type(self, _type):
|
||||
if isinstance(_type, EnumType) and _type.desc is None:
|
||||
_type.desc = self.enumsIndex[_type.name]
|
||||
elif isinstance(_type, ClassType) and _type.desc is None:
|
||||
if _type.name in self.classesIndex:
|
||||
_type.desc = self.classesIndex[_type.name]
|
||||
else:
|
||||
type.desc = self.interfacesIndex[type.name]
|
||||
elif isinstance(type, ListType) and type.containedTypeDesc is None:
|
||||
if type.containedTypeName in self.classesIndex:
|
||||
type.containedTypeDesc = ClassType(type.containedTypeName, classDesc=self.classesIndex[type.containedTypeName])
|
||||
elif type.containedTypeName in self.interfacesIndex:
|
||||
type.containedTypeDesc = ClassType(type.containedTypeName, classDesc=self.interfacesIndex[type.containedTypeName])
|
||||
elif type.containedTypeName in self.enumsIndex:
|
||||
type.containedTypeDesc = EnumType(type.containedTypeName, enumDesc=self.enumsIndex[type.containedTypeName])
|
||||
_type.desc = self.interfacesIndex[_type.name]
|
||||
elif isinstance(_type, ListType) and _type.containedTypeDesc is None:
|
||||
if _type.containedTypeName in self.classesIndex:
|
||||
_type.containedTypeDesc = ClassType(_type.containedTypeName, classDesc=self.classesIndex[_type.containedTypeName])
|
||||
elif _type.containedTypeName in self.interfacesIndex:
|
||||
_type.containedTypeDesc = ClassType(_type.containedTypeName, classDesc=self.interfacesIndex[_type.containedTypeName])
|
||||
elif _type.containedTypeName in self.enumsIndex:
|
||||
_type.containedTypeDesc = EnumType(_type.containedTypeName, enumDesc=self.enumsIndex[_type.containedTypeName])
|
||||
else:
|
||||
if type.containedTypeName is not None:
|
||||
type.containedTypeDesc = CParser.parse_c_base_type(self, type.containedTypeName)
|
||||
if _type.containedTypeName is not None:
|
||||
_type.containedTypeDesc = CParser.parse_c_base_type(self, _type.containedTypeName)
|
||||
else:
|
||||
raise Error('bctbx_list_t type without specified contained type')
|
||||
|
||||
|
|
@ -621,6 +644,7 @@ class CParser(object):
|
|||
name = ClassName()
|
||||
name.from_camel_case(cclass.name, namespace=self.namespace.name)
|
||||
_class = Class(name)
|
||||
_class.refcountable = CParser._class_is_refcountable(self, cclass)
|
||||
|
||||
for cproperty in cclass.properties.values():
|
||||
try:
|
||||
|
|
@ -755,10 +779,8 @@ class CParser(object):
|
|||
elif cType.ctype in self.enumsIndex:
|
||||
absType = EnumType(cType.ctype, enumDesc=self.enumsIndex[cType.ctype])
|
||||
elif cType.ctype in self.classesIndex or cType.ctype in self.interfacesIndex:
|
||||
#params = {'classDesc': self.classesIndex[cType.ctype]}
|
||||
#if 'const' in cType.completeType.split(' '):
|
||||
#params['isconst'] = True
|
||||
absType = ClassType(cType.ctype)
|
||||
absType.isconst = cType.completeType.startswith('const ')
|
||||
elif cType.ctype == self.cListType:
|
||||
absType = ListType(cType.containedType)
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -43,14 +43,23 @@ namespace linphone {
|
|||
{{/priorDeclarations}}
|
||||
|
||||
{{#_class}}
|
||||
class {{className}}: public {{{parentClassName}}} {
|
||||
class {{className}}{{#parentClassName}}: public {{{parentClassName}}}{{/parentClassName}} {
|
||||
{{#friendClasses}}
|
||||
friend class {{name}};
|
||||
{{/friendClasses}}
|
||||
|
||||
public:
|
||||
{{#isNotListener}}
|
||||
{{#isrefcountable}}
|
||||
{{{className}}}(void *ptr, bool takeRef=true);
|
||||
{{/isrefcountable}}
|
||||
{{#isnotrefcountable}}
|
||||
LINPHONECXX_PUBLIC {{{className}}}();
|
||||
LINPHONECXX_PUBLIC {{{className}}}(const {{{className}}} &src);
|
||||
{{{className}}}(const void *src);
|
||||
LINPHONECXX_PUBLIC ~{{{className}}}();
|
||||
LINPHONECXX_PUBLIC const void *c_struct() const {return mPrivPtr;}
|
||||
{{/isnotrefcountable}}
|
||||
{{/isNotListener}}
|
||||
|
||||
{{#ismonolistenable}}
|
||||
|
|
@ -71,6 +80,7 @@ namespace linphone {
|
|||
{{#isVcard}}
|
||||
LINPHONECXX_PUBLIC std::shared_ptr<belcard::BelCard> &getVcard();
|
||||
{{/isVcard}}
|
||||
|
||||
|
||||
{{#methods}}
|
||||
{{{prototype}}}
|
||||
|
|
@ -91,7 +101,11 @@ namespace linphone {
|
|||
private:
|
||||
void *mCallbacks;
|
||||
{{/ismultilistenable}}
|
||||
|
||||
|
||||
{{#isnotrefcountable}}
|
||||
private:
|
||||
void *mPrivPtr;
|
||||
{{/isnotrefcountable}}
|
||||
};
|
||||
{{/_class}}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,12 +47,33 @@ static {{{returnType}}} {{{cbName}}}({{{declArgs}}}) {
|
|||
{{/wrapperCbs}}
|
||||
|
||||
{{#isNotListener}}
|
||||
{{#isrefcountable}}
|
||||
{{{namespace}}}::{{{className}}}::{{{className}}}(void *ptr, bool takeRef): {{{parentClassName}}}(ptr, takeRef) {
|
||||
{{#ismultilistenable}}
|
||||
mCallbacks = ({{{cListenerName}}} *)createCallbacks(&getListeners());
|
||||
{{{callbacksAdder}}}(({{{cClassName}}} *)mPrivPtr, ({{{cListenerName}}} *)mCallbacks);
|
||||
{{/ismultilistenable}}
|
||||
}
|
||||
{{/isrefcountable}}
|
||||
|
||||
{{#isnotrefcountable}}
|
||||
{{{namespace}}}::{{{className}}}::{{{className}}}() {
|
||||
mPrivPtr = new {{{cClassName}}};
|
||||
memset(mPrivPtr, 0, sizeof({{{cClassName}}}));
|
||||
}
|
||||
|
||||
{{{namespace}}}::{{{className}}}::{{{className}}}(const {{{className}}} &src) {
|
||||
mPrivPtr = new {{{cClassName}}}(*({{{cClassName}}} *)src.mPrivPtr);
|
||||
}
|
||||
|
||||
{{{namespace}}}::{{{className}}}::{{{className}}}(const void *src) {
|
||||
mPrivPtr = new {{{cClassName}}}(*({{{cClassName}}} *)src);
|
||||
}
|
||||
|
||||
{{{namespace}}}::{{{className}}}::~{{{className}}}() {
|
||||
delete ({{{cClassName}}} *)mPrivPtr;
|
||||
}
|
||||
{{/isnotrefcountable}}
|
||||
{{/isNotListener}}
|
||||
|
||||
{{#ismonolistenable}}
|
||||
|
|
|
|||
|
|
@ -66,22 +66,24 @@ class CppTranslator(object):
|
|||
ismonolistenable = (islistenable and not _class.multilistener)
|
||||
ismultilistenable = (islistenable and _class.multilistener)
|
||||
|
||||
classDict = {}
|
||||
classDict['islistenable'] = islistenable
|
||||
classDict['isnotlistenable'] = not islistenable
|
||||
classDict['ismonolistenable'] = ismonolistenable
|
||||
classDict['ismultilistenable'] = ismultilistenable
|
||||
classDict['isNotListener'] = True
|
||||
classDict['isfactory'] = (_class.name.to_c() == 'LinphoneFactory')
|
||||
classDict['isVcard'] = (_class.name.to_c() == 'LinphoneVcard')
|
||||
classDict['parentClassName'] = None
|
||||
classDict['className'] = CppTranslator.translate_class_name(_class.name)
|
||||
classDict['cClassName'] = '::' + _class.name.to_c()
|
||||
classDict['parentClassName'] = 'Object'
|
||||
classDict['methods'] = []
|
||||
classDict['staticMethods'] = []
|
||||
classDict['wrapperCbs'] = []
|
||||
classDict['friendClasses'] = []
|
||||
classDict = {
|
||||
'islistenable' : islistenable,
|
||||
'isnotlistenable' : not islistenable,
|
||||
'ismonolistenable' : ismonolistenable,
|
||||
'ismultilistenable' : ismultilistenable,
|
||||
'isrefcountable' : _class.refcountable,
|
||||
'isnotrefcountable' : not _class.refcountable,
|
||||
'isNotListener' : True,
|
||||
'isfactory' : (_class.name.to_c() == 'LinphoneFactory'),
|
||||
'isVcard' : (_class.name.to_c() == 'LinphoneVcard'),
|
||||
'className' : CppTranslator.translate_class_name(_class.name),
|
||||
'cClassName' : '::' + _class.name.to_c(),
|
||||
'parentClassName' : 'Object' if _class.refcountable else None,
|
||||
'methods' : [],
|
||||
'staticMethods' : [],
|
||||
'wrapperCbs' : [],
|
||||
'friendClasses' : []
|
||||
}
|
||||
|
||||
if _class.name.to_c() == 'LinphoneCore':
|
||||
classDict['friendClasses'].append({'name': 'Factory'});
|
||||
|
|
@ -279,20 +281,33 @@ class CppTranslator(object):
|
|||
elif type(exprtype) is AbsApi.EnumType:
|
||||
cExpr = '(::{0}){1}'.format(exprtype.desc.name.to_c(), cppExpr)
|
||||
elif type(exprtype) is AbsApi.ClassType:
|
||||
param = {}
|
||||
param['ptrType'] = CppTranslator.translate_class_type(self, exprtype, namespace=usedNamespace)
|
||||
param['ptrType'] = CppTranslator.sharedPtrTypeExtractor.match(param['ptrType']).group(2)
|
||||
param['cPtrType'] = exprtype.desc.name.to_c()
|
||||
param['cppExpr'] = cppExpr
|
||||
param['object'] = 'const Object' if exprtype.isconst else 'Object'
|
||||
cExpr = '(::{cPtrType} *)Object::sharedPtrToCPtr(std::static_pointer_cast<{object},{ptrType}>({cppExpr}))'.format(**param)
|
||||
cPtrType = exprtype.desc.name.to_c()
|
||||
if exprtype.desc.refcountable:
|
||||
ptrType = CppTranslator.translate_class_type(self, exprtype, namespace=usedNamespace)
|
||||
ptrType = CppTranslator.sharedPtrTypeExtractor.match(ptrType).group(2)
|
||||
param = {
|
||||
'ptrType' : ptrType,
|
||||
'cPtrType': cPtrType,
|
||||
'cppExpr' : cppExpr,
|
||||
'object' : 'const Object' if exprtype.isconst else 'Object'
|
||||
}
|
||||
cExpr = '(::{cPtrType} *)Object::sharedPtrToCPtr(std::static_pointer_cast<{object},{ptrType}>({cppExpr}))'.format(**param)
|
||||
else:
|
||||
cExpr = '(const ::{_type} *)({expr}).c_struct()'.format(_type=cPtrType, expr=cppExpr)
|
||||
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)
|
||||
elif type(exprtype.containedTypeDesc) is AbsApi.ClassType:
|
||||
ptrType = CppTranslator.translate_class_type(self, exprtype.containedTypeDesc, namespace=usedNamespace)
|
||||
ptrType = CppTranslator.sharedPtrTypeExtractor.match(ptrType).group(2)
|
||||
cExpr = 'ObjectBctbxListWrapper<{0}>({1}).c_list()'.format(ptrType, cppExpr)
|
||||
if exprtype.containedTypeDesc.desc.refcountable:
|
||||
ptrType = CppTranslator.sharedPtrTypeExtractor.match(ptrType).group(2)
|
||||
cExpr = 'ObjectBctbxListWrapper<{0}>({1}).c_list()'.format(ptrType, cppExpr)
|
||||
else:
|
||||
cType = exprtype.containedTypeDesc.desc.name.to_c()
|
||||
if exprtype.isconst:
|
||||
cExpr = 'StructBctbxListWrapper<{0},{1}>({2}).c_list()'.format(ptrType, cType, cppExpr)
|
||||
else:
|
||||
cExpr = 'StructBctbxListWrapper<{0},{1}>::cppListToBctbxList({2})'.format(ptrType, cType, cppExpr)
|
||||
else:
|
||||
raise AbsApi.Error('translation of bctbx_list_t of enums or basic C types is not supported')
|
||||
|
||||
|
|
@ -315,19 +330,26 @@ class CppTranslator(object):
|
|||
return '({0}){1}'.format(cppEnumName, cExpr)
|
||||
elif type(exprtype) is AbsApi.ClassType:
|
||||
cppReturnType = CppTranslator.translate_class_type(self, exprtype, namespace=usedNamespace)
|
||||
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 'Object::cPtrToSharedPtr<{0}>((::belle_sip_object_t *){1}, false)'.format(cppReturnType, cExpr)
|
||||
if exprtype.desc.refcountable:
|
||||
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 'Object::cPtrToSharedPtr<{0}>({1}, false)'.format(cppReturnType, cExpr)
|
||||
else:
|
||||
return 'Object::cPtrToSharedPtr<{0}>({1})'.format(cppReturnType, cExpr)
|
||||
else:
|
||||
return 'Object::cPtrToSharedPtr<{0}>((::belle_sip_object_t *){1})'.format(cppReturnType, cExpr)
|
||||
return '{0}({1})'.format(exprtype.desc.name.to_camel_case(), cExpr);
|
||||
elif type(exprtype) is AbsApi.ListType:
|
||||
if type(exprtype.containedTypeDesc) is AbsApi.BaseType and exprtype.containedTypeDesc.name == 'string':
|
||||
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 'ObjectBctbxListWrapper<{0}>::bctbxListToCppList({1})'.format(cppReturnType, cExpr)
|
||||
if exprtype.containedTypeDesc.desc.refcountable:
|
||||
cppReturnType = CppTranslator.sharedPtrTypeExtractor.match(cppReturnType).group(2)
|
||||
return 'ObjectBctbxListWrapper<{0}>::bctbxListToCppList({1})'.format(cppReturnType, cExpr)
|
||||
else:
|
||||
cType = exprtype.containedTypeDesc.desc.name.to_c()
|
||||
return 'StructBctbxListWrapper<{0},{1}>::bctbxListToCppList({2})'.format(cppReturnType, cType, cExpr)
|
||||
else:
|
||||
raise AbsApi.Error('translation of bctbx_list_t of enums or basic C types is not supported')
|
||||
else:
|
||||
|
|
@ -429,13 +451,18 @@ class CppTranslator(object):
|
|||
|
||||
res = CppTranslator.translate_class_name(_type.desc.name, recursive=True, topAncestor=nsName)
|
||||
|
||||
if _type.isconst:
|
||||
res = 'const ' + res
|
||||
|
||||
if type(_type.parent) is AbsApi.Argument:
|
||||
return 'const std::shared_ptr<{0}> &'.format(res)
|
||||
if _type.desc.refcountable:
|
||||
if _type.isconst:
|
||||
res = 'const ' + res
|
||||
if type(_type.parent) is AbsApi.Argument:
|
||||
return 'const std::shared_ptr<{0}> &'.format(res)
|
||||
else:
|
||||
return 'std::shared_ptr<{0}>'.format(res)
|
||||
else:
|
||||
return 'std::shared_ptr<{0}>'.format(res)
|
||||
if type(_type.parent) is AbsApi.Argument:
|
||||
return 'const {0} &'.format(res)
|
||||
else:
|
||||
return '{0}'.format(res)
|
||||
|
||||
def translate_list_type(self, _type, **params):
|
||||
if _type.containedTypeDesc is None:
|
||||
|
|
@ -679,6 +706,8 @@ def main():
|
|||
render(renderer, header, includedir + '/enums.hh')
|
||||
|
||||
mainHeader = MainHeader()
|
||||
mainHeader.add_include('enums.hh')
|
||||
|
||||
impl = ClassImpl()
|
||||
|
||||
for _class in parser.classesIndex.values() + parser.interfacesIndex.values():
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ std::map<std::string,void *> &Object::getUserData() const {
|
|||
return *userData;
|
||||
}
|
||||
|
||||
Object *Object::getBackPtrFromCPtr(void *ptr) {
|
||||
linphone::Object *linphone::Object::getBackPtrFromCPtr(const void *ptr) {
|
||||
return (Object *)belle_sip_object_data_get((::belle_sip_object_t *)ptr, "cpp_object");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -85,11 +85,25 @@ namespace linphone {
|
|||
}
|
||||
}
|
||||
}
|
||||
template <class T>
|
||||
static std::shared_ptr<const T> cPtrToSharedPtr(const void *ptr, bool takeRef=true) {
|
||||
if (ptr == NULL) {
|
||||
return nullptr;
|
||||
} else {
|
||||
Object *cppPtr = getBackPtrFromCPtr(ptr);
|
||||
if (cppPtr == NULL) {
|
||||
return std::make_shared<const T>((void *)ptr, takeRef);
|
||||
} else {
|
||||
return std::static_pointer_cast<const T,Object>(cppPtr->shared_from_this());
|
||||
}
|
||||
}
|
||||
}
|
||||
static void *sharedPtrToCPtr(const std::shared_ptr<const Object> &sharedPtr);
|
||||
|
||||
|
||||
private:
|
||||
LINPHONECXX_PUBLIC std::map<std::string,void *> &getUserData() const;
|
||||
static Object *getBackPtrFromCPtr(void *ptr);
|
||||
static Object *getBackPtrFromCPtr(const void *ptr);
|
||||
template <class T> static void deleteSharedPtr(std::shared_ptr<T> *ptr) {if (ptr != NULL) delete ptr;}
|
||||
static void deleteString(std::string *str) {if (str != NULL) delete str;}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,14 +43,12 @@ namespace linphone {
|
|||
class ObjectBctbxListWrapper: public AbstractBctbxListWrapper {
|
||||
public:
|
||||
ObjectBctbxListWrapper(const std::list<std::shared_ptr<T> > &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<Object,T>(*it));
|
||||
if (cPtr != NULL) belle_sip_object_ref(cPtr);
|
||||
mCList = bctbx_list_append(mCList, cPtr);
|
||||
}
|
||||
mCList = cppListToBctbxList(cppList);
|
||||
}
|
||||
virtual ~ObjectBctbxListWrapper() {
|
||||
mCList = bctbx_list_free_with_data(mCList, unrefData);
|
||||
if (mCList != NULL) {
|
||||
bctbx_list_free_with_data(mCList, unrefData);
|
||||
}
|
||||
}
|
||||
static std::list<std::shared_ptr<T> > bctbxListToCppList(const ::bctbx_list_t *bctbxList) {
|
||||
std::list<std::shared_ptr<T> > cppList;
|
||||
|
|
@ -60,6 +58,15 @@ namespace linphone {
|
|||
}
|
||||
return cppList;
|
||||
}
|
||||
static ::bctbx_list_t *cppListToBctbxList(const std::list<std::shared_ptr<T> > &cppList) {
|
||||
bctbx_list_t *cList = NULL;
|
||||
for(auto it=cppList.cbegin(); it!=cppList.cend(); it++) {
|
||||
::belle_sip_object_t *cPtr = (::belle_sip_object_t *)Object::sharedPtrToCPtr(std::static_pointer_cast<Object,T>(*it));
|
||||
if (cPtr != NULL) belle_sip_object_ref(cPtr);
|
||||
cList = bctbx_list_append(cList, cPtr);
|
||||
}
|
||||
return cList;
|
||||
}
|
||||
|
||||
private:
|
||||
static void unrefData(void *data) {
|
||||
|
|
@ -75,6 +82,35 @@ namespace linphone {
|
|||
static std::list<std::string> bctbxListToCppList(const ::bctbx_list_t *bctbxList);
|
||||
};
|
||||
|
||||
|
||||
template <class T, class U>
|
||||
class StructBctbxListWrapper: public AbstractBctbxListWrapper {
|
||||
public:
|
||||
StructBctbxListWrapper(const std::list<T> &cppList): AbstractBctbxListWrapper() {
|
||||
mCList = cppListToBctbxList(cppList);
|
||||
}
|
||||
virtual ~StructBctbxListWrapper() {
|
||||
bctbx_list_free_with_data(mCList, (bctbx_list_free_func)deleteCStruct);
|
||||
}
|
||||
static std::list<T> bctbxListToCppList(const ::bctbx_list_t *bctbxList) {
|
||||
std::list<T> cppList;
|
||||
for(const bctbx_list_t *it = bctbx_list_first_elem(bctbxList); it != NULL; it = bctbx_list_next(it)) {
|
||||
cppList->push_back(T(it->data));
|
||||
}
|
||||
return cppList;
|
||||
}
|
||||
static bctbx_list_t *cppListToBctbxList(const std::list<T> &cppList) {
|
||||
bctbx_list_t *cList = NULL;
|
||||
for(auto it=cppList.cbegin(); it!=cppList.cend(); it++) {
|
||||
cList = bctbx_list_append(cList, new U(it->c_struct()));
|
||||
}
|
||||
return cList;
|
||||
}
|
||||
|
||||
private:
|
||||
static void deleteCStruct(U *cStruct) {delete cStruct;}
|
||||
};
|
||||
|
||||
class StringUtilities {
|
||||
public:
|
||||
static std::string cStringToCpp(const char *cstr);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue