1# Copyright 2018 gRPC authors. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15 16cdef class _GrpcArgWrapper: 17 18 cdef grpc_arg arg 19 20 21cdef tuple _wrap_grpc_arg(grpc_arg arg): 22 wrapped = _GrpcArgWrapper() 23 wrapped.arg = arg 24 return ("grpc.python._cygrpc._GrpcArgWrapper", wrapped) 25 26 27cdef grpc_arg _unwrap_grpc_arg(tuple wrapped_arg): 28 cdef _GrpcArgWrapper wrapped = wrapped_arg[1] 29 return wrapped.arg 30 31 32cdef class _ChannelArg: 33 34 cdef void c(self, argument, references) except *: 35 key, value = argument 36 cdef bytes encoded_key = _encode(key) 37 if encoded_key is not key: 38 references.append(encoded_key) 39 self.c_argument.key = encoded_key 40 if isinstance(value, int): 41 self.c_argument.type = GRPC_ARG_INTEGER 42 self.c_argument.value.integer = value 43 elif isinstance(value, (bytes, str, unicode,)): 44 self.c_argument.type = GRPC_ARG_STRING 45 encoded_value = _encode(value) 46 if encoded_value is not value: 47 references.append(encoded_value) 48 self.c_argument.value.string = encoded_value 49 elif isinstance(value, _GrpcArgWrapper): 50 self.c_argument = (<_GrpcArgWrapper>value).arg 51 elif hasattr(value, '__int__'): 52 # Pointer objects must override __int__() to return 53 # the underlying C address (Python ints are word size). The 54 # lifecycle of the pointer is fixed to the lifecycle of the 55 # python object wrapping it. 56 self.c_argument.type = GRPC_ARG_POINTER 57 self.c_argument.value.pointer.vtable = &default_vtable 58 self.c_argument.value.pointer.address = <void*>(<intptr_t>int(value)) 59 else: 60 raise TypeError( 61 'Expected int, bytes, or behavior, got {}'.format(type(value))) 62 63 64cdef class _ChannelArgs: 65 66 def __cinit__(self, arguments): 67 self._arguments = () if arguments is None else tuple(arguments) 68 self._channel_args = [] 69 self._references = [] 70 self._c_arguments.arguments_length = len(self._arguments) 71 if self._c_arguments.arguments_length != 0: 72 self._c_arguments.arguments = <grpc_arg *>gpr_malloc( 73 self._c_arguments.arguments_length * sizeof(grpc_arg)) 74 for index, argument in enumerate(self._arguments): 75 channel_arg = _ChannelArg() 76 channel_arg.c(argument, self._references) 77 self._c_arguments.arguments[index] = channel_arg.c_argument 78 self._channel_args.append(channel_arg) 79 80 cdef grpc_channel_args *c_args(self) except *: 81 return &self._c_arguments 82 83 def __dealloc__(self): 84 if self._c_arguments.arguments != NULL: 85 gpr_free(self._c_arguments.arguments) 86