1# Copyright 2017 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 Operation:
17
18  cdef void c(self):
19    raise NotImplementedError()
20
21  cdef void un_c(self):
22    raise NotImplementedError()
23
24
25cdef class SendInitialMetadataOperation(Operation):
26
27  def __cinit__(self, initial_metadata, flags):
28    self._initial_metadata = initial_metadata
29    self._flags = flags
30
31  def type(self):
32    return GRPC_OP_SEND_INITIAL_METADATA
33
34  cdef void c(self):
35    self.c_op.type = GRPC_OP_SEND_INITIAL_METADATA
36    self.c_op.flags = self._flags
37    _store_c_metadata(
38        self._initial_metadata, &self._c_initial_metadata,
39        &self._c_initial_metadata_count)
40    self.c_op.data.send_initial_metadata.metadata = self._c_initial_metadata
41    self.c_op.data.send_initial_metadata.count = self._c_initial_metadata_count
42    self.c_op.data.send_initial_metadata.maybe_compression_level.is_set = 0
43
44  cdef void un_c(self):
45    _release_c_metadata(
46        self._c_initial_metadata, self._c_initial_metadata_count)
47
48
49cdef class SendMessageOperation(Operation):
50
51  def __cinit__(self, bytes message, int flags):
52    self._message = message
53    self._flags = flags
54
55  def type(self):
56    return GRPC_OP_SEND_MESSAGE
57
58  cdef void c(self):
59    self.c_op.type = GRPC_OP_SEND_MESSAGE
60    self.c_op.flags = self._flags
61    cdef grpc_slice message_slice = grpc_slice_from_copied_buffer(
62        self._message, len(self._message))
63    self._c_message_byte_buffer = grpc_raw_byte_buffer_create(
64        &message_slice, 1)
65    grpc_slice_unref(message_slice)
66    self.c_op.data.send_message.send_message = self._c_message_byte_buffer
67
68  cdef void un_c(self):
69    grpc_byte_buffer_destroy(self._c_message_byte_buffer)
70
71
72cdef class SendCloseFromClientOperation(Operation):
73
74  def __cinit__(self, int flags):
75    self._flags = flags
76
77  def type(self):
78    return GRPC_OP_SEND_CLOSE_FROM_CLIENT
79
80  cdef void c(self):
81    self.c_op.type = GRPC_OP_SEND_CLOSE_FROM_CLIENT
82    self.c_op.flags = self._flags
83
84  cdef void un_c(self):
85    pass
86
87
88cdef class SendStatusFromServerOperation(Operation):
89
90  def __cinit__(self, trailing_metadata, code, object details, int flags):
91    self._trailing_metadata = trailing_metadata
92    self._code = code
93    self._details = details
94    self._flags = flags
95
96  def type(self):
97    return GRPC_OP_SEND_STATUS_FROM_SERVER
98
99  cdef void c(self):
100    self.c_op.type = GRPC_OP_SEND_STATUS_FROM_SERVER
101    self.c_op.flags = self._flags
102    _store_c_metadata(
103        self._trailing_metadata, &self._c_trailing_metadata,
104        &self._c_trailing_metadata_count)
105    self.c_op.data.send_status_from_server.trailing_metadata = (
106        self._c_trailing_metadata)
107    self.c_op.data.send_status_from_server.trailing_metadata_count = (
108        self._c_trailing_metadata_count)
109    self.c_op.data.send_status_from_server.status = self._code
110    self._c_details = _slice_from_bytes(_encode(self._details))
111    self.c_op.data.send_status_from_server.status_details = &self._c_details
112
113  cdef void un_c(self):
114    grpc_slice_unref(self._c_details)
115    _release_c_metadata(
116        self._c_trailing_metadata, self._c_trailing_metadata_count)
117
118
119cdef class ReceiveInitialMetadataOperation(Operation):
120
121  def __cinit__(self, flags):
122    self._flags = flags
123
124  def type(self):
125    return GRPC_OP_RECV_INITIAL_METADATA
126
127  cdef void c(self):
128    self.c_op.type = GRPC_OP_RECV_INITIAL_METADATA
129    self.c_op.flags = self._flags
130    grpc_metadata_array_init(&self._c_initial_metadata)
131    self.c_op.data.receive_initial_metadata.receive_initial_metadata = (
132        &self._c_initial_metadata)
133
134  cdef void un_c(self):
135    self._initial_metadata = _metadata(&self._c_initial_metadata)
136    grpc_metadata_array_destroy(&self._c_initial_metadata)
137
138  def initial_metadata(self):
139    return self._initial_metadata
140
141
142cdef class ReceiveMessageOperation(Operation):
143
144  def __cinit__(self, flags):
145    self._flags = flags
146
147  def type(self):
148    return GRPC_OP_RECV_MESSAGE
149
150  cdef void c(self):
151    self.c_op.type = GRPC_OP_RECV_MESSAGE
152    self.c_op.flags = self._flags
153    self.c_op.data.receive_message.receive_message = (
154        &self._c_message_byte_buffer)
155
156  cdef void un_c(self):
157    cdef grpc_byte_buffer_reader message_reader
158    cdef bint message_reader_status
159    cdef grpc_slice message_slice
160    cdef size_t message_slice_length
161    cdef void *message_slice_pointer
162    if self._c_message_byte_buffer != NULL:
163      message_reader_status = grpc_byte_buffer_reader_init(
164          &message_reader, self._c_message_byte_buffer)
165      if message_reader_status:
166        message = bytearray()
167        while grpc_byte_buffer_reader_next(&message_reader, &message_slice):
168          message_slice_pointer = grpc_slice_start_ptr(message_slice)
169          message_slice_length = grpc_slice_length(message_slice)
170          message += (<char *>message_slice_pointer)[:message_slice_length]
171          grpc_slice_unref(message_slice)
172        grpc_byte_buffer_reader_destroy(&message_reader)
173        self._message = bytes(message)
174      else:
175        self._message = None
176      grpc_byte_buffer_destroy(self._c_message_byte_buffer)
177    else:
178      self._message = None
179
180  def message(self):
181    return self._message
182
183
184cdef class ReceiveStatusOnClientOperation(Operation):
185
186  def __cinit__(self, flags):
187    self._flags = flags
188
189  def type(self):
190    return GRPC_OP_RECV_STATUS_ON_CLIENT
191
192  cdef void c(self):
193    self.c_op.type = GRPC_OP_RECV_STATUS_ON_CLIENT
194    self.c_op.flags = self._flags
195    grpc_metadata_array_init(&self._c_trailing_metadata)
196    self.c_op.data.receive_status_on_client.trailing_metadata = (
197        &self._c_trailing_metadata)
198    self.c_op.data.receive_status_on_client.status = (
199        &self._c_code)
200    self.c_op.data.receive_status_on_client.status_details = (
201        &self._c_details)
202    self.c_op.data.receive_status_on_client.error_string = (
203        &self._c_error_string)
204
205  cdef void un_c(self):
206    self._trailing_metadata = _metadata(&self._c_trailing_metadata)
207    grpc_metadata_array_destroy(&self._c_trailing_metadata)
208    self._code = self._c_code
209    self._details = _decode(_slice_bytes(self._c_details))
210    grpc_slice_unref(self._c_details)
211    if self._c_error_string != NULL:
212      self._error_string = _decode(self._c_error_string)
213      gpr_free(<void*>self._c_error_string)
214    else:
215      self._error_string = ""
216
217  def trailing_metadata(self):
218    return self._trailing_metadata
219
220  def code(self):
221    return self._code
222
223  def details(self):
224    return self._details
225
226  def error_string(self):
227    return self._error_string
228
229
230cdef class ReceiveCloseOnServerOperation(Operation):
231
232  def __cinit__(self, flags):
233    self._flags = flags
234
235  def type(self):
236    return GRPC_OP_RECV_CLOSE_ON_SERVER
237
238  cdef void c(self):
239    self.c_op.type = GRPC_OP_RECV_CLOSE_ON_SERVER
240    self.c_op.flags = self._flags
241    self.c_op.data.receive_close_on_server.cancelled = &self._c_cancelled
242
243  cdef void un_c(self):
244    self._cancelled = bool(self._c_cancelled)
245
246  def cancelled(self):
247    return self._cancelled
248