1# Copyright (C) 2003, 2004, 2005, 2006 Red Hat Inc. <http://www.redhat.com/> 2# Copyright (C) 2003 David Zeuthen 3# Copyright (C) 2004 Rob Taylor 4# Copyright (C) 2005, 2006 Collabora Ltd. <http://www.collabora.co.uk/> 5# 6# SPDX-License-Identifier: MIT 7# 8# Permission is hereby granted, free of charge, to any person 9# obtaining a copy of this software and associated documentation 10# files (the "Software"), to deal in the Software without 11# restriction, including without limitation the rights to use, copy, 12# modify, merge, publish, distribute, sublicense, and/or sell copies 13# of the Software, and to permit persons to whom the Software is 14# furnished to do so, subject to the following conditions: 15# 16# The above copyright notice and this permission notice shall be 17# included in all copies or substantial portions of the Software. 18# 19# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 22# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 23# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 24# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26# DEALINGS IN THE SOFTWARE. 27 28from xml.parsers.expat import ParserCreate 29from dbus.exceptions import IntrospectionParserException 30 31class _Parser(object): 32 __slots__ = ('map', 'in_iface', 'in_method', 'sig') 33 def __init__(self): 34 self.map = {} 35 self.in_iface = '' 36 self.in_method = '' 37 self.sig = '' 38 39 def parse(self, data): 40 parser = ParserCreate('UTF-8', ' ') 41 parser.buffer_text = True 42 parser.StartElementHandler = self.StartElementHandler 43 parser.EndElementHandler = self.EndElementHandler 44 parser.Parse(data) 45 return self.map 46 47 def StartElementHandler(self, name, attributes): 48 if not self.in_iface: 49 if (not self.in_method and name == 'interface'): 50 self.in_iface = attributes['name'] 51 else: 52 if (not self.in_method and name == 'method'): 53 self.in_method = attributes['name'] 54 elif (self.in_method and name == 'arg'): 55 if attributes.get('direction', 'in') == 'in': 56 self.sig += attributes['type'] 57 58 def EndElementHandler(self, name): 59 if self.in_iface: 60 if (not self.in_method and name == 'interface'): 61 self.in_iface = '' 62 elif (self.in_method and name == 'method'): 63 self.map[self.in_iface + '.' + self.in_method] = self.sig 64 self.in_method = '' 65 self.sig = '' 66 67def process_introspection_data(data): 68 """Return a dict mapping ``interface.method`` strings to the 69 concatenation of all their 'in' parameters, and mapping 70 ``interface.signal`` strings to the concatenation of all their 71 parameters. 72 73 Example output:: 74 75 { 76 'com.example.SignalEmitter.OneString': 's', 77 'com.example.MethodImplementor.OneInt32Argument': 'i', 78 } 79 80 :Parameters: 81 `data` : str 82 The introspection XML. Must be an 8-bit string of UTF-8. 83 """ 84 try: 85 return _Parser().parse(data) 86 except Exception as e: 87 raise IntrospectionParserException('%s: %s' % (e.__class__, e)) 88