def _marshal(self, newSerial=True): """ Encodes the message into binary format. The resulting binary message is stored in C{self.rawMessage} """ flags = 0 if not self.expectReply: flags |= 0x1 if not self.autoStart: flags |= 0x2 self.headers = list() for attr_name, code, is_required in self._headerAttrs: hval = getattr(self, attr_name, None) if hval is not None: if attr_name == 'path': hval = marshal.ObjectPath(hval) elif attr_name == 'signature': hval = marshal.Signature(hval) self.headers.append( [code, hval] ) if self.signature: binBody = b''.join( marshal.marshal( self.signature, self.body )[1] ) else: binBody = b'' self.bodyLength = len(binBody) if newSerial: self.serial = DBusMessage._nextSerial DBusMessage._nextSerial += 1 binHeader = b''.join(marshal.marshal(_headerFormat, [self.endian, self._messageType, flags, self._protocolVersion, self.bodyLength, self.serial, self.headers], lendian = self.endian == ord('l') )[1]) headerPadding = marshal.pad['header']( len(binHeader) ) self.rawHeader = binHeader self.rawPadding = headerPadding self.rawBody = binBody self.rawMessage = b''.join( [binHeader, headerPadding, binBody] ) if len(self.rawMessage) > self._maxMsgLen: raise error.MarshallingError('Marshalled message exceeds maximum message size of %d' % (self._maxMsgLen,))
def parseMessage(rawMessage, oobFDs): """ Parses the raw binary message and returns a L{DBusMessage} subclass. Unmarshalling DBUS 'h' (UNIX_FD) gets the FDs from the oobFDs list. @type rawMessage: C{str} @param rawMessage: Raw binary message to parse @rtype: L{DBusMessage} subclass @returns: The L{DBusMessage} subclass corresponding to the contained message """ lendian = rawMessage[0] == b'l'[0] nheader, hval = marshal.unmarshal( _headerFormat, rawMessage, 0, lendian, oobFDs, ) messageType = hval[1] if messageType not in _mtype: raise error.MarshallingError( 'Unknown Message Type: ' + str(messageType) ) m = object.__new__(_mtype[messageType]) m.rawHeader = rawMessage[:nheader] npad = nheader % 8 and (8 - nheader % 8) or 0 m.rawPadding = rawMessage[nheader: nheader + npad] m.rawBody = rawMessage[nheader + npad:] m.serial = hval[5] for code, v in hval[6]: try: setattr(m, _hcode[code], v) except KeyError: pass if m.signature: nbytes, m.body = marshal.unmarshal( m.signature, m.rawBody, lendian=lendian, oobFDs=oobFDs, ) return m
def __init__(self, path, member, interface=None, destination=None, signature=None, body=None, expectReply=True, autoStart=True, oobFDs=None): """ @param path: C{str} DBus object path @param member: C{str} Member name @param interface: C{str} DBus interface name or None @param destination: C{str} DBus bus name for message destination or None @param signature: C{str} DBus signature string for encoding C{self.body} @param body: C{list} of python objects to encode. Objects must match the C{self.signature} @param expectReply: True if a Method Return message should be sent in reply to this message @param autoStart: True if the Bus should auto-start a service to handle this message if the service is not already running. """ marshal.validateMemberName(member) if interface: marshal.validateInterfaceName(interface) if destination: marshal.validateBusName(destination) if path == '/org/freedesktop/DBus/Local': raise error.MarshallingError( '/org/freedesktop/DBus/Local is a reserved path') self.path = path self.member = member self.interface = interface self.destination = destination self.signature = signature self.body = body self.expectReply = expectReply self.autoStart = autoStart self.oobFDs = oobFDs self._marshal(oobFDs=oobFDs)
def _marshal(self, newSerial=True, oobFDs=None): """ Encodes the message into binary format. The resulting binary message is stored in C{self.rawMessage} """ flags = 0 if not self.expectReply: flags |= 0x1 if not self.autoStart: flags |= 0x2 # may be overriden below, depending on oobFDs _headerAttrs = self._headerAttrs # marshal body before headers to know if the 'unix_fd' header is needed if self.signature: binBody = b''.join( marshal.marshal( self.signature, self.body, oobFDs=oobFDs )[1] ) if oobFDs: # copy class based _headerAttrs to add a unix_fds header this # time _headerAttrs = list(self._headerAttrs) _headerAttrs.append(('unix_fds', 9, False)) self.unix_fds = len(oobFDs) else: binBody = b'' self.headers = [] for attr_name, code, is_required in _headerAttrs: hval = getattr(self, attr_name, None) if hval is not None: if attr_name == 'path': hval = marshal.ObjectPath(hval) elif attr_name == 'signature': hval = marshal.Signature(hval) elif attr_name == 'unix_fds': hval = marshal.UInt32(hval) self.headers.append([code, hval]) self.bodyLength = len(binBody) if newSerial: self.serial = DBusMessage._nextSerial DBusMessage._nextSerial += 1 binHeader = b''.join(marshal.marshal( _headerFormat, [ self.endian, self._messageType, flags, self._protocolVersion, self.bodyLength, self.serial, self.headers ], lendian=self.endian == ord('l') )[1]) headerPadding = marshal.pad['header'](len(binHeader)) self.rawHeader = binHeader self.rawPadding = headerPadding self.rawBody = binBody self.rawMessage = b''.join([binHeader, headerPadding, binBody]) if len(self.rawMessage) > self._maxMsgLen: raise error.MarshallingError( 'Marshalled message exceeds maximum message size of %d' % (self._maxMsgLen,), )