1 # -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
3 # This file is part of the LibreOffice project.
5 # This Source Code Form is subject to the terms of the Mozilla Public
6 # License, v. 2.0. If a copy of the MPL was not distributed with this
7 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
14 class UnsupportedType(Exception):
15 '''Represents exception thrown when an unsupported UNO type(like
16 array or union) is used.'''
18 def __init__(self
, type):
21 class UnknownType(Exception):
22 '''Represents exception thrown when an unknown UNO type is used.'''
24 def __init__(self
, type):
27 class TypeClass(object):
28 '''Represents type class of UNO type.'''
34 # type class of boolean
40 # type class of unsigned short
44 # type class of unsigned long
48 # type class of unsigned hyper
52 # type class of double
54 # type class of string
62 # type class of typedef
64 # type class of struct
67 # type class of exception
69 # type class of sequence
72 # type class of interface
74 # type class of service (not implemented)
76 # type class of module (not implemented)
78 # type class of interface method
80 # type class of interface attribute
81 INTERFACE_ATTRIBUTE
= 26
82 # type class of unknown type
84 # type class of properties
86 # type class of constants
88 # type class of constants groups
90 # type class of singletons
93 class TemplateType(object):
95 def __init__(self
, template
, *args
):
96 self
.template
= template
100 argtypes
= [str(gdb
.lookup_type(arg
).strip_typedefs()) for arg
in self
.args
]
101 return self
.template
+ '<' + ', '.join(argtypes
) + '>'
104 '''Describes a UNO type.'''
106 def __init__(self
, typeclass
, tag
):
107 '''Constructs a new Type.
108 @param[in] typeclass value of com::sun::star::uno::TypeClass
109 @param[in] tag UNO name of the type
111 self
.typeclass
= typeclass
113 # C++ name of the type
117 '''Gets gdb.Type for the type'''
119 return gdb
.lookup_type(str(self
.typename
))
123 def uno2cpp(typename
):
124 return str(typename
).replace('.', '::')[1:-1]
126 def strip_typedefs(self
):
128 copy
.typename
= self
._strip
_typedefs
(self
.typename
)
131 def _strip_typedefs(self
, typename
):
132 template_args
= re
.compile('([^<]+)(<.*>)')
133 match
= template_args
.match(typename
)
134 type = self
._lookup
_type
(match
.group(1))
137 list_delim
= re
.compile(', *')
138 # FIXME: this does not work with nested templates
139 for arg
in match
.group(2).split(list_delim
):
140 types
.append(self
._lookup
_type
(arg
))
143 if not types
.empty():
144 typename
+= '<' + types
.join(', ') + '>'
148 def _lookup_type(self
, typename
):
150 type = gdb
.lookup_type(typename
)
152 type = type.strip_typedefs()
155 def make_uno_type(val
):
156 '''Creates a UNO type from gdb.Value of type
157 com::sun::star::uno::Type, typelib_TypeDescription, or
158 typelib_TypeDescriptionReference
161 cssu_type
= 'com::sun::star::uno::Type'
162 type_desc
= '_typelib_TypeDescription'
165 '_typelib_CompoundTypeDescription',
166 '_typelib_StructTypeDescription',
167 '_typelib_IndirectTypeDescription',
168 '_typelib_EnumTypeDescription',
169 '_typelib_InterfaceMemberTypeDescription',
170 '_typelib_InterfaceMethodTypeDescription',
171 '_typelib_InterfaceAttributeTypeDescription',
172 '_typelib_InterfaceTypeDescription'
174 type_desc_ref
= '_typelib_TypeDescriptionReference'
176 type = val
.type.strip_typedefs()
178 if type.tag
== cssu_type
:
179 pvalue
= val
['_pType']
181 val
= pvalue
.dereference()
182 type = val
.type.strip_typedefs()
184 while type.tag
== type_desc_ref
:
185 pvalue
= val
['pType']
187 val
= pvalue
.dereference()
188 type = val
.type.strip_typedefs()
190 if type.tag
not in type_descs
:
193 # determination of the UNO type
195 if type.tag
!= type_desc
:
196 while 'aBase' in val
:
198 type_class
= int(val
['eTypeClass'])
199 name
= val
['pTypeName'].dereference()
201 if type_class
== TypeClass
.VOID
:
202 uno_type
= VoidType()
203 elif type_class
== TypeClass
.CHAR
:
204 uno_type
= PrimitiveType(type_class
, name
, 'sal_Char')
205 elif type_class
== TypeClass
.BOOLEAN
:
206 uno_type
= PrimitiveType(type_class
, name
, 'sal_Bool')
207 elif type_class
== TypeClass
.BYTE
:
208 uno_type
= PrimitiveType(type_class
, name
, 'sal_Int8')
209 elif type_class
== TypeClass
.SHORT
:
210 uno_type
= PrimitiveType(type_class
, name
, 'sal_Int16')
211 elif type_class
== TypeClass
.UNSIGNED_SHORT
:
212 uno_type
= PrimitiveType(type_class
, name
, 'sal_uInt16')
213 elif type_class
== TypeClass
.LONG
:
214 uno_type
= PrimitiveType(type_class
, name
, 'sal_Int32')
215 elif type_class
== TypeClass
.UNSIGNED_LONG
:
216 uno_type
= PrimitiveType(type_class
, name
, 'sal_uInt32')
217 elif type_class
== TypeClass
.HYPER
:
218 uno_type
= PrimitiveType(type_class
, name
, 'sal_Int64')
219 elif type_class
== TypeClass
.UNSIGNED_HYPER
:
220 uno_type
= PrimitiveType(type_class
, name
, 'sal_uInt64')
221 elif type_class
== TypeClass
.FLOAT
:
222 uno_type
= PrimitiveType(type_class
, name
, 'float')
223 elif type_class
== TypeClass
.DOUBLE
:
224 uno_type
= PrimitiveType(type_class
, name
, 'double')
225 elif type_class
== TypeClass
.STRING
:
226 uno_type
= PrimitiveType(type_class
, name
, 'rtl::OUString')
227 elif type_class
== TypeClass
.TYPE
:
228 uno_type
= PrimitiveType(type_class
, name
, 'com::sun::star::uno::Type')
229 elif type_class
== TypeClass
.ANY
:
230 uno_type
= PrimitiveType(type_class
, name
, 'com::sun::star::uno::Any')
231 elif type_class
== TypeClass
.ENUM
:
232 uno_type
= EnumType(val
, full_val
)
233 elif type_class
== TypeClass
.TYPEDEF
:
235 elif type_class
== TypeClass
.STRUCT
:
236 uno_type
= StructType(val
, full_val
)
237 elif type_class
== TypeClass
.EXCEPTION
:
238 uno_type
= CompoundType(val
, full_val
)
239 elif type_class
== TypeClass
.SEQUENCE
:
240 uno_type
= IndirectType(val
, full_val
)
241 elif type_class
== TypeClass
.INTERFACE
:
242 uno_type
= InterfaceType(val
, full_val
)
243 elif type_class
== TypeClass
.SERVICE
:
244 raise UnsupportedType('service')
245 elif type_class
== TypeClass
.MODULE
:
246 raise UnsupportedType('module')
247 elif type_class
== TypeClass
.INTERFACE_METHOD
:
248 uno_type
= InterfaceMethodType(val
, full_val
)
249 elif type_class
== TypeClass
.INTERFACE_ATTRIBUTE
:
250 uno_type
= InterfaceAttributeType(val
, full_val
)
251 elif type_class
== TypeClass
.UNKNOWN
:
252 raise UnknownType(type)
253 elif type_class
== TypeClass
.PROPERTY
:
255 elif type_class
== TypeClass
.CONSTANT
:
257 elif type_class
== TypeClass
.CONSTANTS
:
259 elif type_class
== TypeClass
.SINGLETON
:
262 raise UnknownType(type)
267 def uno_cast(type, val
):
268 '''Casts val or pointer to UNO type represented by type'''
269 if val
.type.code
== gdb
.TYPE_CODE_PTR
:
270 return val
.cast(type.type().pointer())
272 return val
.cast(type.type())
274 class VoidType(Type
):
277 super(VoidType
, self
).__init
__(TypeClass
.VOID
, "void")
278 self
.typename
= "void"
280 class PrimitiveType(Type
):
282 def __init__(self
, typeclass
, typename_uno
, typename_cpp
):
283 super(PrimitiveType
, self
).__init
__(typeclass
, typename_uno
)
284 self
.typename
= str(typename_cpp
)
286 class CompoundType(Type
):
288 def __init__(self
, type, full_type
):
289 super(CompoundType
, self
).__init
__(type['eTypeClass'], type['pTypeName'].dereference())
290 self
.typename
= self
.uno2cpp(self
.tag
)
291 self
._type
= full_type
293 class _iterator(six
.Iterator
):
295 def __init__(self
, count
, types
, names
):
297 self
.members
= members
305 assert self
.pos
>= 0 and self
.pos
<= self
.count
306 if self
.pos
== self
.count
:
309 pmember
= self
.members
[self
.pos
]
311 pname
= self
.names
[self
.i
]
313 self
.pos
= self
.pos
+ 1
314 member
= make_uno_type(pmember
.dereference())
316 name
= str(pname
.dereference())
317 return (name
, member
)
319 def attributes(self
):
320 return _iterator(self
._type
['nMembers'], self
._type
['ppTypeRefs'],
321 self
._type
['ppMemberNames'])
323 class StructType(CompoundType
):
325 def __init__(self
, type, full_type
):
326 full_type
= full_type
.cast(gdb
.lookup_type('_typelib_StructTypeDescription'))
327 super(StructType
, self
).__init
__(type, full_type
['aBase'])
329 class IndirectType(Type
):
331 def __init__(self
, type, full_type
):
332 super(IndirectType
, self
).__init
__(type['eTypeClass'], type['pTypeName'].dereference())
333 full_type
= full_type
.cast(gdb
.lookup_type('_typelib_IndirectTypeDescription'))
334 pelem
= full_type
['pType']
336 self
.element
= make_uno_type(pelem
.dereference())
338 self
.typename
= TemplateType('com::sun::star::uno::Sequence', self
.element
.typename
)
340 class EnumType(Type
):
342 def __init__(self
, type, full_type
):
343 super(EnumType
, self
).__init
__(TypeClass
.ENUM
, type['pTypeName'].dereference())
344 self
.typename
= self
.uno2cpp(self
.tag
)
345 self
._type
= full_type
.cast(gdb
.lookup_type('_typelib_EnumTypeDescription'))
347 class _iterator(six
.Iterator
):
349 def __init__(self
, count
, values
, names
):
359 assert self
.pos
>= 0 and self
.pos
<= self
.count
360 if self
.pos
== self
.count
:
363 pvalue
= self
.values
[self
.pos
]
365 pname
= self
.names
[self
.pos
]
367 self
.pos
= self
.pos
+ 1
368 val
= int(pvalue
.dereference())
369 name
= str(pname
.dereference())
373 return _iterator(self
._type
['nEnumValues'],
374 self
._type
['ppEnumNames'], self
._type
['pEnumValues'])
376 def default_value(self
):
377 return self
._type
['nDefaultEnumValue']
379 class InterfaceMemberType(Type
):
381 def __init__(self
, type, full_type
):
382 super(InterfaceMemberType
, self
).__init
__(type['eTypeClass'], type['pTypeName'].dereference())
383 (interface
, delim
, member
) = self
.tag
.partition('::')
384 self
.typename
= self
.uno2cpp(interface
) + '::*' + member
385 full_type
= full_type
.cast(gdb
.lookup_type('_typelib_InterfaceMemberTypeDescription'))
386 self
.position
= full_type
['nPosition']
387 pname
= full_type
['pMemberName']
389 self
.name
= pname
.dereference()
391 class InterfaceMethodType(InterfaceMemberType
):
393 def __init__(self
, type, full_type
):
394 full_type
= full_type
.cast(gdb
.lookup_type('_typelib_InterfaceMethodTypeDescription'))
395 super(InterfaceMethodType
, self
).__init
__(type, full_type
['aBase'])
396 pret
= full_type
['pReturnTypeRef']
398 self
.return_type
= make_uno_type(pret
.dereference())
399 assert self
.return_type
400 self
.oneway
= full_type
['bOneWay']
401 self
._type
= full_type
403 class _iterator(six
.Iterator
):
405 def __init__(self
, count
, values
):
415 assert self
.pos
>= 0 and self
.pos
<= self
.count
416 if self
.pos
== self
.count
:
419 val
= self
.values
[self
.pos
]
420 self
.pos
= self
.pos
+ 1
423 class parameter(tuple):
425 def __init__(self
, type):
426 self
.__init
_tuple
(type)
427 self
.input = type['bIn']
428 self
.output
= type['bOut']
430 def _init_tuple(self
, type):
431 pname
= self
['pName']
433 ptype
= self
['pTypeRef']
435 name
= str(pname
.dereference())
436 type = make_uno_type(ptype
.dereference())
438 super(parameter
, self
).__init
__(name
, type)
440 def parameters(self
):
441 for param
in _iterator(self
._type
['nParams'], self
._type
['pParams']):
442 yield parameter(param
)
444 def exceptions(self
):
445 def make_exception(self
, pex
):
447 ex
= make_uno_type(pex
.dereference())
452 self
._type
['nExceptions'], self
._type
['ppExceptions']):
453 yield make_exception(ex
)
455 class InterfaceAttributeType(InterfaceMemberType
):
457 def __init__(self
, type, full_type
):
458 full_type
= full_type
.cast(gdb
.lookup_type('_typelib_InterfaceAttributeTypeDescription'))
459 super(InterfaceAttributeType
, self
).__init
__(type, full_type
['aBase'])
460 self
.readonly
= full_type
['bReadOnly']
461 ptype
= full_type
['pAttributeTypeRef']
463 self
.type = make_uno_type(ptype
.dereference())
466 class MembersNotInitialized(Exception):
467 '''Represents exception raised when interface type' members haven't
468 been initialized(i.e. just level 1 initialization has been
472 class InterfaceType(Type
):
474 def __init__(self
, type, full_type
):
475 super(InterfaceType
, self
).__init
__(TypeClass
.INTERFACE
, type['pTypeName'].dereference())
476 assert int(type['eTypeClass']) == TypeClass
.INTERFACE
477 self
.typename
= self
.uno2cpp(self
.tag
)
478 full_type
= full_type
.cast(gdb
.lookup_type('_typelib_InterfaceTypeDescription'))
479 self
.uik
= full_type
['aUik']
480 self
._type
= full_type
482 class _iterator(six
.Iterator
):
484 def __init__(self
, count
, values
):
494 assert self
.pos
>= 0 and self
.pos
<= self
.count
495 pvalue
= self
.values
[self
.pos
]
497 self
.pos
= self
.pos
+ 1
498 uno
= make_uno_type(pvalue
.dereference())
503 return __members(self
._type
['nMembers'], self
._type
['ppMembers'])
505 def all_members(self
):
506 return __members(self
._type
['nAllMembers'], self
._type
['ppAllMembers'])
508 def __members(count
, values
):
510 raise MembersNotInitialized
511 return _iterator(count
, values
)
514 return _iterator(self
._type
['nBaseTypes'], self
._type
['ppBaseTypes'])
516 # vim:set shiftwidth=4 softtabstop=4 expandtab: