Commit 4567654d authored by François Grisez's avatar François Grisez
Browse files

[Abstract API] Add a new type of list for lists holding objects that has been allocated on the fly.

parents c8797562 b75b48a5
......@@ -229,6 +229,7 @@ TAB_SIZE = 8
# newlines.
ALIASES = bctbx_list{1}="A list of \ref \1 objects. \xmlonly <bctbxlist>\1</bctbxlist> \endxmlonly"
ALIASES += onTheFlyList="The objects inside the list are freshly allocated with a reference counter equal to one, so they need to be freed on list destruction with bctbx_list_free_with_data() for instance. \xmlonly <onTheFlyList/> \endxmlonly"
ALIASES += donotwrap="\xmlonly <donotwrap /> \endxmlonly"
# This tag can be used to specify a number of word-keyword mappings (TCL only).
......
......@@ -182,7 +182,7 @@ LINPHONE_PUBLIC bctbx_list_t *linphone_chat_room_get_history (LinphoneChatRoom *
* @param[in] cr The #LinphoneChatRoom object corresponding to the conversation for which messages should be retrieved
* @param[in] begin The first message of the range to be retrieved. History most recent message has index 0.
* @param[in] end The last message of the range to be retrieved. History oldest message has index of history size - 1 (use #linphone_chat_room_get_history_size to retrieve history size)
* @return \bctbx_list{LinphoneChatMessage}
* @return \bctbx_list{LinphoneChatMessage} \onTheFlyList
*/
LINPHONE_PUBLIC bctbx_list_t *linphone_chat_room_get_history_range(LinphoneChatRoom *cr, int begin, int end);
......
......@@ -179,6 +179,14 @@ class ListType(Type):
return translator.translate_list_type(self, **params)
class BasicListType(ListType):
pass
class OnTheFlyListType(ListType):
pass
class DocumentableObject(Object):
def __init__(self, name):
Object.__init__(self, name)
......@@ -868,7 +876,10 @@ class CParser(object):
absType.isconst = cType.completeType.startswith('const ')
absType.isref = cType.completeType.endswith('*')
elif cType.ctype == self.cListType:
absType = ListType(cType.containedType)
if cType.onTheFlyList:
absType = OnTheFlyListType(cType.containedType)
else:
absType = BasicListType(cType.containedType)
absType.isconst = cType.completeType.startswith('const ')
elif cType.ctype.endswith('Mask'):
absType = BaseType('integer', isUnsigned=True)
......
......@@ -88,6 +88,7 @@ class CArgument(CObject):
CObject.__init__(self, name)
self.description = None
self.containedType = None
self.onTheFlyList = False
keywords = [ 'const', 'struct', 'enum', 'signed', 'unsigned', 'short', 'long', '*' ]
fullySplittedType = []
splittedType = t.strip().split(' ')
......@@ -563,6 +564,7 @@ class Project:
n = returndesc.find('.//bctbxlist')
if n is not None:
returnarg.containedType = n.text
returnarg.onTheFlyList = True if returndesc.find('.//onTheFlyList') is not None else False
returnarg.description = self.__cleanDescription(returndesc)
elif returnarg.completeType != 'void':
missingDocWarning += "\tReturn value is not documented\n"
......
......@@ -246,14 +246,14 @@ class CppTranslator(object):
return ', '.join(args)
def _wrap_cpp_expression_to_c(self, cppExpr, exprtype, usedNamespace=None):
if type(exprtype) is AbsApi.BaseType:
if isinstance(exprtype, AbsApi.BaseType):
if exprtype.name == 'string':
cExpr = 'StringUtilities::cppStringToC({0})'.format(cppExpr);
else:
cExpr = cppExpr
elif type(exprtype) is AbsApi.EnumType:
elif isinstance(exprtype, AbsApi.EnumType):
cExpr = '(::{0}){1}'.format(exprtype.desc.name.to_c(), cppExpr)
elif type(exprtype) is AbsApi.ClassType:
elif isinstance(exprtype, AbsApi.ClassType):
cPtrType = exprtype.desc.name.to_c()
if exprtype.desc.refcountable:
ptrType = exprtype.translate(self.langTranslator, namespace=usedNamespace)
......@@ -270,10 +270,10 @@ class CppTranslator(object):
cExpr = '(const ::{_type} *)({expr}).c_struct()'.format(_type=cPtrType, expr=cppExpr)
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':
elif isinstance(exprtype, AbsApi.ListType):
if isinstance(exprtype.containedTypeDesc, AbsApi.BaseType) and exprtype.containedTypeDesc.name == 'string':
cExpr = 'StringBctbxListWrapper({0}).c_list()'.format(cppExpr)
elif type(exprtype.containedTypeDesc) is AbsApi.ClassType:
elif isinstance(exprtype.containedTypeDesc, AbsApi.ClassType):
ptrType = exprtype.containedTypeDesc.translate(self.langTranslator, namespace=usedNamespace)
if exprtype.containedTypeDesc.desc.refcountable:
ptrType = CppTranslator.sharedPtrTypeExtractor.match(ptrType).group(2)
......@@ -290,7 +290,7 @@ class CppTranslator(object):
return cExpr
def _wrap_c_expression_to_cpp(self, cExpr, exprtype, usedNamespace=None):
if type(exprtype) is AbsApi.BaseType:
if isinstance(exprtype, AbsApi.BaseType):
if exprtype.name == 'string':
return 'StringUtilities::cStringToCpp({0})'.format(cExpr)
elif exprtype.name == 'string_array':
......@@ -299,15 +299,15 @@ class CppTranslator(object):
return '({0} != FALSE)'.format(cExpr)
else:
return cExpr
elif type(exprtype) is AbsApi.EnumType:
elif isinstance(exprtype, AbsApi.EnumType):
cppEnumName = exprtype.translate(self.langTranslator, namespace=usedNamespace)
return '({0}){1}'.format(cppEnumName, cExpr)
elif type(exprtype) is AbsApi.ClassType:
elif isinstance(exprtype, AbsApi.ClassType):
cppReturnType = exprtype.translate(self.langTranslator, namespace=usedNamespace)
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'):
if isinstance(exprtype.parent, 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)
......@@ -319,17 +319,18 @@ class CppTranslator(object):
exprtype.desc.name.to_camel_case(),
exprtype.desc.name.to_c(),
cExpr)
elif type(exprtype) is AbsApi.ListType:
if type(exprtype.containedTypeDesc) is AbsApi.BaseType and exprtype.containedTypeDesc.name == 'string':
elif isinstance(exprtype, AbsApi.ListType):
if isinstance(exprtype.containedTypeDesc, AbsApi.BaseType) and exprtype.containedTypeDesc.name == 'string':
return 'StringBctbxListWrapper::bctbxListToCppList({0})'.format(cExpr)
elif type(exprtype.containedTypeDesc) is AbsApi.ClassType:
elif isinstance(exprtype.containedTypeDesc, AbsApi.ClassType):
cppReturnType = exprtype.containedTypeDesc.translate(self.langTranslator, namespace=usedNamespace)
takeRef = 'false' if isinstance(exprtype, AbsApi.OnTheFlyListType) else 'true'
if exprtype.containedTypeDesc.desc.refcountable:
cppReturnType = CppTranslator.sharedPtrTypeExtractor.match(cppReturnType).group(2)
return 'ObjectBctbxListWrapper<{0}>::bctbxListToCppList({1})'.format(cppReturnType, cExpr)
return 'ObjectBctbxListWrapper<{0}>::bctbxListToCppList({1}, {2})'.format(cppReturnType, cExpr, takeRef)
else:
cType = exprtype.containedTypeDesc.desc.name.to_c()
return 'StructBctbxListWrapper<{0},{1}>::bctbxListToCppList({2})'.format(cppReturnType, cType, cExpr)
return 'StructBctbxListWrapper<{0},{1}>::bctbxListToCppList({2}, {3})'.format(cppReturnType, cType, cExpr, takeRef)
else:
raise AbsApi.Error('translation of bctbx_list_t of enums or basic C types is not supported')
else:
......
......@@ -50,16 +50,16 @@ namespace linphone {
bctbx_list_free_with_data(mCList, unrefData);
}
}
static std::list<std::shared_ptr<T> > bctbxListToCppList(const ::bctbx_list_t *bctbxList) {
static std::list<std::shared_ptr<T> > bctbxListToCppList(const ::bctbx_list_t *bctbxList, bool takeRef=true) {
std::list<std::shared_ptr<T> > cppList;
for(const ::bctbx_list_t *it=bctbxList; it!=NULL; it=it->next) {
std::shared_ptr<T> newObj = Object::cPtrToSharedPtr<T>(it->data);
std::shared_ptr<T> newObj = Object::cPtrToSharedPtr<T>(it->data, takeRef);
cppList.push_back(newObj);
}
return cppList;
}
static std::list<std::shared_ptr<T>> bctbxListToCppList(::bctbx_list_t *bctbxList) {
std::list<std::shared_ptr<T>> cppList = bctbxListToCppList((const ::bctbx_list_t *)bctbxList);
static std::list<std::shared_ptr<T>> bctbxListToCppList(::bctbx_list_t *bctbxList, bool takeRef=true) {
std::list<std::shared_ptr<T>> cppList = bctbxListToCppList(const_cast<const ::bctbx_list_t *>(bctbxList), takeRef);
bctbx_list_free(bctbxList);
return cppList;
}
......
......@@ -60,13 +60,13 @@ class CsharpTranslator(object):
return not methodDict['is_string'] and not methodDict['is_bool'] and not methodDict['is_class'] and not methodDict['is_enum'] and methodDict['list_type'] == None
def is_linphone_type(self, _type, isArg, dllImport=True):
if type(_type) is AbsApi.ClassType:
if isinstance(_type, AbsApi.ClassType)
return False if dllImport else True
elif type(_type) is AbsApi.EnumType:
elif isinstance(_type, AbsApi.EnumType)
return False if dllImport else True
def throws_exception(self, return_type):
if type(return_type) is AbsApi.BaseType:
if isinstance(return_type, AbsApi.BaseType)
if return_type.name == 'status':
return True
return False
......@@ -111,7 +111,7 @@ class CsharpTranslator(object):
methodDict['is_enum'] = self.is_linphone_type(method.returnType, False, False) and type(method.returnType) is AbsApi.EnumType
methodDict['is_generic'] = self.is_generic(methodDict)
methodDict['takeRef'] = 'true'
if type(method.returnType.parent) is AbsApi.Method and len(method.returnType.parent.name.words) >=1:
if isinstance(method.returnType.parent, AbsApi.Method) and len(method.returnType.parent.name.words) >=1:
if method.returnType.parent.name.words == ['new'] or method.returnType.parent.name.words[0] == 'create':
methodDict['takeRef'] = 'false'
......@@ -122,7 +122,7 @@ class CsharpTranslator(object):
methodDict['impl']['args'] += ', '
methodDict['impl']['c_args'] += ', '
if self.is_linphone_type(arg.type, False, False):
if type(arg.type) is AbsApi.ClassType:
if isinstance(arg.type, AbsApi.ClassType)
argname = arg.name.translate(self.nameTranslator)
methodDict['impl']['c_args'] += argname + " != null ? " + argname + ".nativePtr : IntPtr.Zero"
else:
......@@ -168,7 +168,7 @@ class CsharpTranslator(object):
methodDict['is_enum'] = self.is_linphone_type(prop.returnType, False, False) and type(prop.returnType) is AbsApi.EnumType
methodDict['is_generic'] = self.is_generic(methodDict)
methodDict['takeRef'] = 'true'
if type(prop.returnType.parent) is AbsApi.Method and len(prop.returnType.parent.name.words) >=1:
if isinstance(prop.returnType.parent, AbsApi.Method) and len(prop.returnType.parent.name.words) >=1:
if prop.returnType.parent.name.words == ['new'] or prop.returnType.parent.name.words[0] == 'create':
methodDict['takeRef'] = 'false'
......@@ -278,7 +278,7 @@ class CsharpTranslator(object):
listenerDict['delegate']['params'] += "fromNativePtr<" + normalType + ">(" + argName + ")"
elif self.is_linphone_type(arg.type, True, dllImport=False) and type(arg.type) is AbsApi.EnumType:
listenerDict['delegate']['params'] += "(" + normalType + ")" + argName + ""
elif type(arg.type) is AbsApi.ListType:
elif isinstance(arg.type, AbsApi.ListType):
if normalType == "string":
listenerDict['delegate']['params'] += "MarshalStringArray(" + argName + ")"
else:
......
......@@ -148,7 +148,7 @@ class JavaTranslator(object):
def throws_exception(self, _type):
if not self.exceptions:
return False
if type(_type) is AbsApi.BaseType:
if isinstance(_type, AbsApi.BaseType):
if _type.name == 'status':
return True
return False
......@@ -284,11 +284,11 @@ class JavaTranslator(object):
return {'notEmpty': False}
if methodDict['hasListReturn']:
if type(_method.returnType) is AbsApi.BaseType and _method.returnType.name == 'string_array':
if isinstance(_method.returnType, AbsApi.BaseType) and _method.returnType.name == 'string_array':
methodDict['isStringObjectArray'] = True
elif type(_method.returnType.containedTypeDesc) is AbsApi.BaseType:
elif isinstance(_method.returnType.containedTypeDesc, AbsApi.BaseType):
methodDict['isStringObjectArray'] = True
elif type(_method.returnType.containedTypeDesc) is AbsApi.ClassType:
elif isinstance(_method.returnType.containedTypeDesc, AbsApi.ClassType):
methodDict['isRealObjectArray'] = True
methodDict['objectCPrefix'] = 'linphone_' + _method.returnType.containedTypeDesc.desc.name.to_snake_case()
methodDict['objectClassCName'] = 'Linphone' + _method.returnType.containedTypeDesc.desc.name.to_camel_case()
......@@ -314,24 +314,24 @@ class JavaTranslator(object):
methodDict['params'] += arg.translate(self.langTranslator, jni=True, namespace=namespace)
argname = arg.name.translate(self.nameTranslator)
if type(arg.type) is AbsApi.ClassType:
if isinstance(arg.type, AbsApi.ClassType):
classCName = 'Linphone' + arg.type.desc.name.to_camel_case()
if classCName[-8:] == 'Listener':
classCName = 'Linphone' + arg.type.desc.name.to_camel_case()[:-8] + 'Cbs'
methodDict['objects'].append({'object': argname, 'objectClassCName': classCName})
methodDict['params_impl'] += 'c_' + argname
elif type(arg.type) is AbsApi.ListType:
elif isinstance(arg.type, AbsApi.ListType):
isStringList = type(arg.type.containedTypeDesc) is AbsApi.BaseType and arg.type.containedTypeDesc.name == 'string'
isObjList = type(arg.type.containedTypeDesc) is AbsApi.ClassType
methodDict['lists'].append({'list': argname, 'isStringList': isStringList, 'isObjList': isObjList, 'objectClassCName': arg.type.containedTypeDesc.name})
methodDict['params_impl'] += 'bctbx_list_' + argname
elif type(arg.type) is AbsApi.EnumType:
elif isinstance(arg.type, AbsApi.EnumType):
argCType = arg.type.name
methodDict['params_impl'] += '(' + argCType + ') ' + argname
elif type(arg.type) is AbsApi.BaseType:
elif isinstance(arg.type, AbsApi.BaseType):
if arg.type.name == 'integer' and arg.type.size is not None and arg.type.isref:
methodDict['bytes'].append({'bytesargname': argname, 'bytesargtype' : arg.type.translate(self.clangTranslator)})
methodDict['params_impl'] += 'c_' + argname
......@@ -407,11 +407,11 @@ class JavaTranslator(object):
methodDict['jniUpcallMethod'] = 'CallVoidMethod'
methodDict['isJniUpcallBasicType'] = False
methodDict['isJniUpcallObject'] = False
if type(_method.returnType) is AbsApi.ClassType:
if isinstance(_method.returnType, AbsApi.ClassType):
methodDict['jniUpcallMethod'] = 'CallObjectMethod'
methodDict['isJniUpcallObject'] = True
methodDict['jniUpcallType'] = 'jobject'
elif type(_method.returnType) is AbsApi.BaseType:
elif isinstance(_method.returnType, AbsApi.BaseType):
if not _method.returnType.name == 'void':
methodDict['jniUpcallMethod'] = 'CallIntMethod'
methodDict['jniUpcallType'] = _method.returnType.translate(self.langTranslator, jni=True)
......@@ -438,22 +438,22 @@ class JavaTranslator(object):
methodDict['params'] += '{0} {1}'.format(arg.type.translate(self.clangTranslator), argname)
if type(arg.type) is AbsApi.ClassType:
if isinstance(arg.type, AbsApi.ClassType):
methodDict['jparams'] += 'L' + self.jni_path + arg.type.desc.name.to_camel_case() + ';'
methodDict['params_impl'] += 'j_' + argname
methodDict['jobjects'].append({'objectName': argname, 'className': arg.type.desc.name.to_camel_case(), })
elif type(arg.type) is AbsApi.BaseType:
elif isinstance(arg.type, AbsApi.BaseType):
methodDict['jparams'] += arg.type.translate(self.jnilangTranslator)
if arg.type.name == 'string':
methodDict['params_impl'] += 'j_' + argname
methodDict['jstrings'].append({'stringName': argname,})
else:
methodDict['params_impl'] += argname
elif type(arg.type) is AbsApi.EnumType:
elif isinstance(arg.type, AbsApi.EnumType):
methodDict['jparams'] += 'L' + self.jni_path + arg.type.desc.name.translate(self.jninameTranslator) + ';'
methodDict['params_impl'] += 'j_' + argname
methodDict['jenums'].append({'enumName': argname, 'cEnumPrefix': arg.type.desc.name.to_snake_case(fullName=True)})
elif type(arg.type) is AbsApi.ListType:
elif isinstance(arg.type, AbsApi.ListType):
methodDict['jparams'] += '[L' + self.jni_path + arg.type.containedTypeDesc.name + ';'
methodDict['params_impl'] += 'NULL'
......@@ -461,9 +461,9 @@ class JavaTranslator(object):
if (methodDict['return'] == 'void'):
methodDict['jparams'] += 'V'
else:
if type(_method.returnType) is AbsApi.ClassType:
if isinstance(_method.returnType, AbsApi.ClassType):
methodDict['jparams'] += 'L' + self.jni_path + _method.returnType.desc.name.to_camel_case() + ';'
elif type(_method.returnType) is AbsApi.BaseType:
elif isinstance(_method.returnType, AbsApi.BaseType):
methodDict['jparams'] += self.translate_java_jni_base_type_name(_method.returnType.name)
else:
pass #TODO
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment