Example #1
0
 def _run_test_decode_value(self, typ, cases):
     for decoded, encoded in cases:
         value = Decoder.decode(binascii.unhexlify(encoded), Types().as_type(typ))
         if typ in ('float','double'):
             self.assertEqual(str(decoded)[0:8], str(value)[0:8])
         else:
             self.assertEqual(decoded, value)
Example #2
0
    def _invoke(self, service, procedure, args=[], kwargs={}, param_names=[], param_types=[], return_type=None):
        """ Execute an RPC """

        def encode_argument(i, value):
            typ = param_types[i]
            if type(value) != typ.python_type:
                # Try coercing to the correct type
                try:
                    value = self._types.coerce_to(value, typ)
                except ValueError:
                    raise TypeError('%s.%s() argument %d must be a %s, got a %s' % (service, procedure, i, typ.python_type, type(value)))
            return _Encoder.encode(value, typ)

        if len(args) > len(param_types):
            raise TypeError('%s.%s() takes exactly %d arguments (%d given)' % (service, procedure, len(param_types), len(args)))

        # Encode positional arguments
        arguments = []
        for i,arg in enumerate(args):
            argument = krpc.schema.KRPC.Argument()
            argument.position = i
            argument.value = encode_argument(i, arg)
            arguments.append(argument)

        # Encode keyword arguments
        for key,arg in kwargs.items():
            try:
                i = param_names.index(key)
            except ValueError:
                raise TypeError('%s.%s() got an unexpected keyword argument \'%s\'' % (service, procedure, key))
            if i < len(args):
                raise TypeError('%s.%s() got multiple values for keyword argument \'%s\'' % (service, procedure, key))
            argument = krpc.schema.KRPC.Argument()
            argument.position = i
            argument.value = encode_argument(i, arg)
            arguments.append(argument)

        # Build the request object
        request = krpc.schema.KRPC.Request()
        request.service = service
        request.procedure = procedure
        request.arguments.extend(arguments)

        # Send the request
        with self._connection_lock:
            self._send_request(request)
            response = self._receive_response()

        # Check for an error response
        if response.HasField('error'):
            raise RPCError(response.error)

        # Decode the response and return the (optional) result
        result = None
        if return_type is not None:
            result = _Decoder.decode(response.return_value, return_type)
        return result
Example #3
0
File: stream.py Project: ilo/krpc
def update_thread(connection):
    stream_message_type = _Types().as_type('KRPC.StreamMessage')
    response_type = _Types().as_type('KRPC.Response')

    while True:

        # Read the size and position of the response message
        data = b''
        while True:
            try:
                data += connection.partial_receive(1)
                size,position = _Decoder.decode_size_and_position(data)
                break
            except IndexError:
                pass
            except socket.error:
                return

        # Read and decode the response message
        try:
            data = connection.receive(size)
        except socket.error:
            return
        response = _Decoder.decode(data, stream_message_type)

        # Add the data to the cache
        with _stream_cache_lock:
            for response in response.responses:
                id = response.id
                if id not in _stream_cache:
                    continue

                # Check for an error response
                if response.response.HasField('error'):
                    _stream_cache[id].value = RPCError(response.response.error)
                    continue

                # Decode the return value and store it in the cache
                typ = _stream_cache[id].return_type
                value = _Decoder.decode(response.response.return_value, typ)
                _stream_cache[id].update(value)
Example #4
0
File: client.py Project: ilo/krpc
    def _receive_response(self):
        """ Receive data from the server and decode it into a KRPC.Response object """

        # Read the size and position of the response message
        data = b''
        while True:
            try:
                data += self._rpc_connection.partial_receive(1)
                size,position = _Decoder.decode_size_and_position(data)
                break
            except IndexError:
                pass

        # Read and decode the response message
        data = self._rpc_connection.receive(size)
        return _Decoder.decode(data, self._response_type)
Example #5
0
File: client.py Project: ilo/krpc
    def _invoke(self, service, procedure, args=[], kwargs={}, param_names=[], param_types=[], return_type=None):
        """ Execute an RPC """

        # Build the request
        request = self._build_request(service, procedure, args, kwargs, param_names, param_types, return_type)

        # Send the request
        with self._rpc_connection_lock:
            self._send_request(request)
            response = self._receive_response()

        # Check for an error response
        if response.HasField('error'):
            raise RPCError(response.error)

        # Decode the response and return the (optional) result
        result = None
        if return_type is not None:
            result = _Decoder.decode(response.return_value, return_type)
        return result
Example #6
0
 def test_decode_class_none(self):
     typ = Types().as_type('Class(ServiceName.ClassName)')
     value = Decoder.decode(binascii.unhexlify('00'), typ)
     self.assertIsNone(value)
Example #7
0
 def test_decode_class(self):
     typ = Types().as_type('Class(ServiceName.ClassName)')
     value = Decoder.decode(binascii.unhexlify('ac02'), typ)
     self.assertTrue(isinstance(value, typ.python_type))
     self.assertEqual(300, value._object_id)
Example #8
0
 def test_decode_value(self):
     value = Decoder.decode(binascii.unhexlify('ac02'), Types().as_type('int32'))
     self.assertEquals(int(300), value)
Example #9
0
 def test_decode_message(self):
     typ = krpc.schema.KRPC.Request
     message = '0a0b536572766963654e616d65120d50726f6365647572654e616d65'
     request = Decoder.decode(binascii.unhexlify(message), Types().as_type('KRPC.Request'))
     self.assertEquals('ServiceName', request.service)
     self.assertEquals('ProcedureName', request.procedure)