Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(79)

Side by Side Diff: third_party/grpc/src/csharp/ext/grpc_csharp_ext.c

Issue 1932353002: Initial checkin of gRPC to third_party/ Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 *
3 * Copyright 2015-2016, Google Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
34 #include "src/core/support/string.h"
35
36 #include <grpc/byte_buffer_reader.h>
37 #include <grpc/support/port_platform.h>
38 #include <grpc/support/alloc.h>
39 #include <grpc/support/log.h>
40 #include <grpc/support/slice.h>
41 #include <grpc/support/string_util.h>
42 #include <grpc/support/thd.h>
43 #include <grpc/grpc.h>
44 #include <grpc/grpc_security.h>
45
46 #include <string.h>
47
48 #ifdef GPR_WIN32
49 #define GPR_EXPORT __declspec(dllexport)
50 #define GPR_CALLTYPE __stdcall
51 #endif
52
53 #ifndef GPR_EXPORT
54 #define GPR_EXPORT
55 #endif
56
57 #ifndef GPR_CALLTYPE
58 #define GPR_CALLTYPE
59 #endif
60
61 grpc_byte_buffer *string_to_byte_buffer(const char *buffer, size_t len) {
62 gpr_slice slice = gpr_slice_from_copied_buffer(buffer, len);
63 grpc_byte_buffer *bb = grpc_raw_byte_buffer_create(&slice, 1);
64 gpr_slice_unref(slice);
65 return bb;
66 }
67
68 /*
69 * Helper to maintain lifetime of batch op inputs and store batch op outputs.
70 */
71 typedef struct grpcsharp_batch_context {
72 grpc_metadata_array send_initial_metadata;
73 grpc_byte_buffer *send_message;
74 struct {
75 grpc_metadata_array trailing_metadata;
76 char *status_details;
77 } send_status_from_server;
78 grpc_metadata_array recv_initial_metadata;
79 grpc_byte_buffer *recv_message;
80 struct {
81 grpc_metadata_array trailing_metadata;
82 grpc_status_code status;
83 char *status_details;
84 size_t status_details_capacity;
85 } recv_status_on_client;
86 int recv_close_on_server_cancelled;
87 struct {
88 grpc_call *call;
89 grpc_call_details call_details;
90 grpc_metadata_array request_metadata;
91 } server_rpc_new;
92 } grpcsharp_batch_context;
93
94 GPR_EXPORT grpcsharp_batch_context *GPR_CALLTYPE grpcsharp_batch_context_create( ) {
95 grpcsharp_batch_context *ctx = gpr_malloc(sizeof(grpcsharp_batch_context));
96 memset(ctx, 0, sizeof(grpcsharp_batch_context));
97 return ctx;
98 }
99
100 /*
101 * Destroys array->metadata.
102 * The array pointer itself is not freed.
103 */
104 void grpcsharp_metadata_array_destroy_metadata_only(
105 grpc_metadata_array *array) {
106 gpr_free(array->metadata);
107 }
108
109 /*
110 * Destroys keys, values and array->metadata.
111 * The array pointer itself is not freed.
112 */
113 void grpcsharp_metadata_array_destroy_metadata_including_entries(
114 grpc_metadata_array *array) {
115 size_t i;
116 if (array->metadata) {
117 for (i = 0; i < array->count; i++) {
118 gpr_free((void *)array->metadata[i].key);
119 gpr_free((void *)array->metadata[i].value);
120 }
121 }
122 gpr_free(array->metadata);
123 }
124
125 /*
126 * Fully destroys the metadata array.
127 */
128 GPR_EXPORT void GPR_CALLTYPE
129 grpcsharp_metadata_array_destroy_full(grpc_metadata_array *array) {
130 if (!array) {
131 return;
132 }
133 grpcsharp_metadata_array_destroy_metadata_including_entries(array);
134 gpr_free(array);
135 }
136
137 /*
138 * Creates an empty metadata array with given capacity.
139 * Array can later be destroyed by grpc_metadata_array_destroy_full.
140 */
141 GPR_EXPORT grpc_metadata_array *GPR_CALLTYPE
142 grpcsharp_metadata_array_create(size_t capacity) {
143 grpc_metadata_array *array =
144 (grpc_metadata_array *)gpr_malloc(sizeof(grpc_metadata_array));
145 grpc_metadata_array_init(array);
146 array->capacity = capacity;
147 array->count = 0;
148 if (capacity > 0) {
149 array->metadata =
150 (grpc_metadata *)gpr_malloc(sizeof(grpc_metadata) * capacity);
151 memset(array->metadata, 0, sizeof(grpc_metadata) * capacity);
152 } else {
153 array->metadata = NULL;
154 }
155 return array;
156 }
157
158 GPR_EXPORT void GPR_CALLTYPE
159 grpcsharp_metadata_array_add(grpc_metadata_array *array, const char *key,
160 const char *value, size_t value_length) {
161 size_t i = array->count;
162 GPR_ASSERT(array->count < array->capacity);
163 array->metadata[i].key = gpr_strdup(key);
164 array->metadata[i].value = (char *)gpr_malloc(value_length);
165 memcpy((void *)array->metadata[i].value, value, value_length);
166 array->metadata[i].value_length = value_length;
167 array->count++;
168 }
169
170 GPR_EXPORT intptr_t GPR_CALLTYPE
171 grpcsharp_metadata_array_count(grpc_metadata_array *array) {
172 return (intptr_t)array->count;
173 }
174
175 GPR_EXPORT const char *GPR_CALLTYPE
176 grpcsharp_metadata_array_get_key(grpc_metadata_array *array, size_t index) {
177 GPR_ASSERT(index < array->count);
178 return array->metadata[index].key;
179 }
180
181 GPR_EXPORT const char *GPR_CALLTYPE
182 grpcsharp_metadata_array_get_value(grpc_metadata_array *array, size_t index) {
183 GPR_ASSERT(index < array->count);
184 return array->metadata[index].value;
185 }
186
187 GPR_EXPORT intptr_t GPR_CALLTYPE grpcsharp_metadata_array_get_value_length(
188 grpc_metadata_array *array, size_t index) {
189 GPR_ASSERT(index < array->count);
190 return (intptr_t)array->metadata[index].value_length;
191 }
192
193 /* Move contents of metadata array */
194 void grpcsharp_metadata_array_move(grpc_metadata_array *dest,
195 grpc_metadata_array *src) {
196 if (!src) {
197 dest->capacity = 0;
198 dest->count = 0;
199 dest->metadata = NULL;
200 return;
201 }
202
203 dest->capacity = src->capacity;
204 dest->count = src->count;
205 dest->metadata = src->metadata;
206
207 src->capacity = 0;
208 src->count = 0;
209 src->metadata = NULL;
210 }
211
212 GPR_EXPORT void GPR_CALLTYPE grpcsharp_batch_context_destroy(grpcsharp_batch_con text *ctx) {
213 if (!ctx) {
214 return;
215 }
216 grpcsharp_metadata_array_destroy_metadata_including_entries(
217 &(ctx->send_initial_metadata));
218
219 grpc_byte_buffer_destroy(ctx->send_message);
220
221 grpcsharp_metadata_array_destroy_metadata_including_entries(
222 &(ctx->send_status_from_server.trailing_metadata));
223 gpr_free(ctx->send_status_from_server.status_details);
224
225 grpcsharp_metadata_array_destroy_metadata_only(&(ctx->recv_initial_metadata));
226
227 grpc_byte_buffer_destroy(ctx->recv_message);
228
229 grpcsharp_metadata_array_destroy_metadata_only(
230 &(ctx->recv_status_on_client.trailing_metadata));
231 gpr_free((void *)ctx->recv_status_on_client.status_details);
232
233 /* NOTE: ctx->server_rpc_new.call is not destroyed because callback handler is
234 supposed
235 to take its ownership. */
236
237 grpc_call_details_destroy(&(ctx->server_rpc_new.call_details));
238 grpcsharp_metadata_array_destroy_metadata_only(
239 &(ctx->server_rpc_new.request_metadata));
240
241 gpr_free(ctx);
242 }
243
244 GPR_EXPORT const grpc_metadata_array *GPR_CALLTYPE
245 grpcsharp_batch_context_recv_initial_metadata(
246 const grpcsharp_batch_context *ctx) {
247 return &(ctx->recv_initial_metadata);
248 }
249
250 GPR_EXPORT intptr_t GPR_CALLTYPE grpcsharp_batch_context_recv_message_length(
251 const grpcsharp_batch_context *ctx) {
252 if (!ctx->recv_message) {
253 return -1;
254 }
255 return (intptr_t)grpc_byte_buffer_length(ctx->recv_message);
256 }
257
258 /*
259 * Copies data from recv_message to a buffer. Fatal error occurs if
260 * buffer is too small.
261 */
262 GPR_EXPORT void GPR_CALLTYPE grpcsharp_batch_context_recv_message_to_buffer(
263 const grpcsharp_batch_context *ctx, char *buffer, size_t buffer_len) {
264 grpc_byte_buffer_reader reader;
265 gpr_slice slice;
266 size_t offset = 0;
267
268 grpc_byte_buffer_reader_init(&reader, ctx->recv_message);
269
270 while (grpc_byte_buffer_reader_next(&reader, &slice)) {
271 size_t len = GPR_SLICE_LENGTH(slice);
272 GPR_ASSERT(offset + len <= buffer_len);
273 memcpy(buffer + offset, GPR_SLICE_START_PTR(slice),
274 GPR_SLICE_LENGTH(slice));
275 offset += len;
276 gpr_slice_unref(slice);
277 }
278 }
279
280 GPR_EXPORT grpc_status_code GPR_CALLTYPE
281 grpcsharp_batch_context_recv_status_on_client_status(
282 const grpcsharp_batch_context *ctx) {
283 return ctx->recv_status_on_client.status;
284 }
285
286 GPR_EXPORT const char *GPR_CALLTYPE
287 grpcsharp_batch_context_recv_status_on_client_details(
288 const grpcsharp_batch_context *ctx) {
289 return ctx->recv_status_on_client.status_details;
290 }
291
292 GPR_EXPORT const grpc_metadata_array *GPR_CALLTYPE
293 grpcsharp_batch_context_recv_status_on_client_trailing_metadata(
294 const grpcsharp_batch_context *ctx) {
295 return &(ctx->recv_status_on_client.trailing_metadata);
296 }
297
298 GPR_EXPORT grpc_call *GPR_CALLTYPE grpcsharp_batch_context_server_rpc_new_call(
299 const grpcsharp_batch_context *ctx) {
300 return ctx->server_rpc_new.call;
301 }
302
303 GPR_EXPORT const char *GPR_CALLTYPE
304 grpcsharp_batch_context_server_rpc_new_method(
305 const grpcsharp_batch_context *ctx) {
306 return ctx->server_rpc_new.call_details.method;
307 }
308
309 GPR_EXPORT const char *GPR_CALLTYPE grpcsharp_batch_context_server_rpc_new_host(
310 const grpcsharp_batch_context *ctx) {
311 return ctx->server_rpc_new.call_details.host;
312 }
313
314 GPR_EXPORT gpr_timespec GPR_CALLTYPE
315 grpcsharp_batch_context_server_rpc_new_deadline(
316 const grpcsharp_batch_context *ctx) {
317 return ctx->server_rpc_new.call_details.deadline;
318 }
319
320 GPR_EXPORT const grpc_metadata_array *GPR_CALLTYPE
321 grpcsharp_batch_context_server_rpc_new_request_metadata(
322 const grpcsharp_batch_context *ctx) {
323 return &(ctx->server_rpc_new.request_metadata);
324 }
325
326 GPR_EXPORT int32_t GPR_CALLTYPE
327 grpcsharp_batch_context_recv_close_on_server_cancelled(
328 const grpcsharp_batch_context *ctx) {
329 return (int32_t) ctx->recv_close_on_server_cancelled;
330 }
331
332 /* Init & shutdown */
333
334 GPR_EXPORT void GPR_CALLTYPE grpcsharp_init(void) { grpc_init(); }
335
336 GPR_EXPORT void GPR_CALLTYPE grpcsharp_shutdown(void) { grpc_shutdown(); }
337
338 /* Completion queue */
339
340 GPR_EXPORT grpc_completion_queue *GPR_CALLTYPE
341 grpcsharp_completion_queue_create(void) {
342 return grpc_completion_queue_create(NULL);
343 }
344
345 GPR_EXPORT void GPR_CALLTYPE
346 grpcsharp_completion_queue_shutdown(grpc_completion_queue *cq) {
347 grpc_completion_queue_shutdown(cq);
348 }
349
350 GPR_EXPORT void GPR_CALLTYPE
351 grpcsharp_completion_queue_destroy(grpc_completion_queue *cq) {
352 grpc_completion_queue_destroy(cq);
353 }
354
355 GPR_EXPORT grpc_event GPR_CALLTYPE
356 grpcsharp_completion_queue_next(grpc_completion_queue *cq) {
357 return grpc_completion_queue_next(cq, gpr_inf_future(GPR_CLOCK_REALTIME),
358 NULL);
359 }
360
361 GPR_EXPORT grpc_event GPR_CALLTYPE
362 grpcsharp_completion_queue_pluck(grpc_completion_queue *cq, void *tag) {
363 return grpc_completion_queue_pluck(cq, tag,
364 gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
365 }
366
367 /* Channel */
368
369 GPR_EXPORT grpc_channel *GPR_CALLTYPE
370
371 grpcsharp_insecure_channel_create(const char *target, const grpc_channel_args *a rgs) {
372 return grpc_insecure_channel_create(target, args, NULL);
373 }
374
375 GPR_EXPORT void GPR_CALLTYPE grpcsharp_channel_destroy(grpc_channel *channel) {
376 grpc_channel_destroy(channel);
377 }
378
379 GPR_EXPORT grpc_call *GPR_CALLTYPE
380 grpcsharp_channel_create_call(grpc_channel *channel, grpc_call *parent_call,
381 uint32_t propagation_mask,
382 grpc_completion_queue *cq,
383 const char *method, const char *host,
384 gpr_timespec deadline) {
385 return grpc_channel_create_call(channel, parent_call, propagation_mask, cq,
386 method, host, deadline, NULL);
387 }
388
389 GPR_EXPORT grpc_connectivity_state GPR_CALLTYPE
390 grpcsharp_channel_check_connectivity_state(grpc_channel *channel, int32_t try_to _connect) {
391 return grpc_channel_check_connectivity_state(channel, try_to_connect);
392 }
393
394 GPR_EXPORT void GPR_CALLTYPE grpcsharp_channel_watch_connectivity_state(
395 grpc_channel *channel, grpc_connectivity_state last_observed_state,
396 gpr_timespec deadline, grpc_completion_queue *cq, grpcsharp_batch_context *c tx) {
397 grpc_channel_watch_connectivity_state(channel, last_observed_state,
398 deadline, cq, ctx);
399 }
400
401 GPR_EXPORT char *GPR_CALLTYPE grpcsharp_channel_get_target(grpc_channel *channel ) {
402 return grpc_channel_get_target(channel);
403 }
404
405 /* Channel args */
406
407 GPR_EXPORT grpc_channel_args *GPR_CALLTYPE
408 grpcsharp_channel_args_create(size_t num_args) {
409 grpc_channel_args *args =
410 (grpc_channel_args *)gpr_malloc(sizeof(grpc_channel_args));
411 memset(args, 0, sizeof(grpc_channel_args));
412
413 args->num_args = num_args;
414 args->args = (grpc_arg *)gpr_malloc(sizeof(grpc_arg) * num_args);
415 memset(args->args, 0, sizeof(grpc_arg) * num_args);
416 return args;
417 }
418
419 GPR_EXPORT void GPR_CALLTYPE
420 grpcsharp_channel_args_set_string(grpc_channel_args *args, size_t index,
421 const char *key, const char *value) {
422 GPR_ASSERT(args);
423 GPR_ASSERT(index < args->num_args);
424 args->args[index].type = GRPC_ARG_STRING;
425 args->args[index].key = gpr_strdup(key);
426 args->args[index].value.string = gpr_strdup(value);
427 }
428
429 GPR_EXPORT void GPR_CALLTYPE
430 grpcsharp_channel_args_set_integer(grpc_channel_args *args, size_t index,
431 const char *key, int value) {
432 GPR_ASSERT(args);
433 GPR_ASSERT(index < args->num_args);
434 args->args[index].type = GRPC_ARG_INTEGER;
435 args->args[index].key = gpr_strdup(key);
436 args->args[index].value.integer = value;
437 }
438
439 GPR_EXPORT void GPR_CALLTYPE
440 grpcsharp_channel_args_destroy(grpc_channel_args *args) {
441 size_t i;
442 if (args) {
443 for (i = 0; i < args->num_args; i++) {
444 gpr_free(args->args[i].key);
445 if (args->args[i].type == GRPC_ARG_STRING) {
446 gpr_free(args->args[i].value.string);
447 }
448 }
449 gpr_free(args->args);
450 gpr_free(args);
451 }
452 }
453
454 /* Timespec */
455
456 GPR_EXPORT gpr_timespec GPR_CALLTYPE gprsharp_now(gpr_clock_type clock_type) {
457 return gpr_now(clock_type);
458 }
459
460 GPR_EXPORT gpr_timespec GPR_CALLTYPE gprsharp_inf_future(gpr_clock_type clock_ty pe) {
461 return gpr_inf_future(clock_type);
462 }
463
464 GPR_EXPORT gpr_timespec GPR_CALLTYPE gprsharp_inf_past(gpr_clock_type clock_type ) {
465 return gpr_inf_past(clock_type);
466 }
467
468 GPR_EXPORT gpr_timespec GPR_CALLTYPE gprsharp_convert_clock_type(gpr_timespec t, gpr_clock_type target_clock) {
469 return gpr_convert_clock_type(t, target_clock);
470 }
471
472 GPR_EXPORT int32_t GPR_CALLTYPE gprsharp_sizeof_timespec(void) {
473 return sizeof(gpr_timespec);
474 }
475
476 /* Call */
477
478 GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_cancel(grpc_call *call) {
479 return grpc_call_cancel(call, NULL);
480 }
481
482 GPR_EXPORT grpc_call_error GPR_CALLTYPE
483 grpcsharp_call_cancel_with_status(grpc_call *call, grpc_status_code status,
484 const char *description) {
485 return grpc_call_cancel_with_status(call, status, description, NULL);
486 }
487
488 GPR_EXPORT char *GPR_CALLTYPE grpcsharp_call_get_peer(grpc_call *call) {
489 return grpc_call_get_peer(call);
490 }
491
492 GPR_EXPORT void GPR_CALLTYPE gprsharp_free(void *p) {
493 gpr_free(p);
494 }
495
496 GPR_EXPORT void GPR_CALLTYPE grpcsharp_call_destroy(grpc_call *call) {
497 grpc_call_destroy(call);
498 }
499
500 GPR_EXPORT grpc_call_error GPR_CALLTYPE
501 grpcsharp_call_start_unary(grpc_call *call, grpcsharp_batch_context *ctx,
502 const char *send_buffer, size_t send_buffer_len,
503 grpc_metadata_array *initial_metadata, uint32_t write _flags) {
504 /* TODO: don't use magic number */
505 grpc_op ops[6];
506 ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
507 grpcsharp_metadata_array_move(&(ctx->send_initial_metadata),
508 initial_metadata);
509 ops[0].data.send_initial_metadata.count = ctx->send_initial_metadata.count;
510 ops[0].data.send_initial_metadata.metadata =
511 ctx->send_initial_metadata.metadata;
512 ops[0].flags = 0;
513 ops[0].reserved = NULL;
514
515 ops[1].op = GRPC_OP_SEND_MESSAGE;
516 ctx->send_message = string_to_byte_buffer(send_buffer, send_buffer_len);
517 ops[1].data.send_message = ctx->send_message;
518 ops[1].flags = write_flags;
519 ops[1].reserved = NULL;
520
521 ops[2].op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
522 ops[2].flags = 0;
523 ops[2].reserved = NULL;
524
525 ops[3].op = GRPC_OP_RECV_INITIAL_METADATA;
526 ops[3].data.recv_initial_metadata = &(ctx->recv_initial_metadata);
527 ops[3].flags = 0;
528 ops[3].reserved = NULL;
529
530 ops[4].op = GRPC_OP_RECV_MESSAGE;
531 ops[4].data.recv_message = &(ctx->recv_message);
532 ops[4].flags = 0;
533 ops[4].reserved = NULL;
534
535 ops[5].op = GRPC_OP_RECV_STATUS_ON_CLIENT;
536 ops[5].data.recv_status_on_client.trailing_metadata =
537 &(ctx->recv_status_on_client.trailing_metadata);
538 ops[5].data.recv_status_on_client.status =
539 &(ctx->recv_status_on_client.status);
540 /* not using preallocation for status_details */
541 ops[5].data.recv_status_on_client.status_details =
542 &(ctx->recv_status_on_client.status_details);
543 ops[5].data.recv_status_on_client.status_details_capacity =
544 &(ctx->recv_status_on_client.status_details_capacity);
545 ops[5].flags = 0;
546 ops[5].reserved = NULL;
547
548 return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx,
549 NULL);
550 }
551
552 GPR_EXPORT grpc_call_error GPR_CALLTYPE
553 grpcsharp_call_start_client_streaming(grpc_call *call,
554 grpcsharp_batch_context *ctx,
555 grpc_metadata_array *initial_metadata) {
556 /* TODO: don't use magic number */
557 grpc_op ops[4];
558 ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
559 grpcsharp_metadata_array_move(&(ctx->send_initial_metadata),
560 initial_metadata);
561 ops[0].data.send_initial_metadata.count = ctx->send_initial_metadata.count;
562 ops[0].data.send_initial_metadata.metadata =
563 ctx->send_initial_metadata.metadata;
564 ops[0].flags = 0;
565 ops[0].reserved = NULL;
566
567 ops[1].op = GRPC_OP_RECV_INITIAL_METADATA;
568 ops[1].data.recv_initial_metadata = &(ctx->recv_initial_metadata);
569 ops[1].flags = 0;
570 ops[1].reserved = NULL;
571
572 ops[2].op = GRPC_OP_RECV_MESSAGE;
573 ops[2].data.recv_message = &(ctx->recv_message);
574 ops[2].flags = 0;
575 ops[2].reserved = NULL;
576
577 ops[3].op = GRPC_OP_RECV_STATUS_ON_CLIENT;
578 ops[3].data.recv_status_on_client.trailing_metadata =
579 &(ctx->recv_status_on_client.trailing_metadata);
580 ops[3].data.recv_status_on_client.status =
581 &(ctx->recv_status_on_client.status);
582 /* not using preallocation for status_details */
583 ops[3].data.recv_status_on_client.status_details =
584 &(ctx->recv_status_on_client.status_details);
585 ops[3].data.recv_status_on_client.status_details_capacity =
586 &(ctx->recv_status_on_client.status_details_capacity);
587 ops[3].flags = 0;
588 ops[3].reserved = NULL;
589
590 return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx,
591 NULL);
592 }
593
594 GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_start_server_streaming(
595 grpc_call *call, grpcsharp_batch_context *ctx, const char *send_buffer,
596 size_t send_buffer_len, grpc_metadata_array *initial_metadata, uint32_t writ e_flags) {
597 /* TODO: don't use magic number */
598 grpc_op ops[4];
599 ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
600 grpcsharp_metadata_array_move(&(ctx->send_initial_metadata),
601 initial_metadata);
602 ops[0].data.send_initial_metadata.count = ctx->send_initial_metadata.count;
603 ops[0].data.send_initial_metadata.metadata =
604 ctx->send_initial_metadata.metadata;
605 ops[0].flags = 0;
606 ops[0].reserved = NULL;
607
608 ops[1].op = GRPC_OP_SEND_MESSAGE;
609 ctx->send_message = string_to_byte_buffer(send_buffer, send_buffer_len);
610 ops[1].data.send_message = ctx->send_message;
611 ops[1].flags = write_flags;
612 ops[1].reserved = NULL;
613
614 ops[2].op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
615 ops[2].flags = 0;
616 ops[2].reserved = NULL;
617
618 ops[3].op = GRPC_OP_RECV_STATUS_ON_CLIENT;
619 ops[3].data.recv_status_on_client.trailing_metadata =
620 &(ctx->recv_status_on_client.trailing_metadata);
621 ops[3].data.recv_status_on_client.status =
622 &(ctx->recv_status_on_client.status);
623 /* not using preallocation for status_details */
624 ops[3].data.recv_status_on_client.status_details =
625 &(ctx->recv_status_on_client.status_details);
626 ops[3].data.recv_status_on_client.status_details_capacity =
627 &(ctx->recv_status_on_client.status_details_capacity);
628 ops[3].flags = 0;
629 ops[3].reserved = NULL;
630
631 return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx,
632 NULL);
633 }
634
635 GPR_EXPORT grpc_call_error GPR_CALLTYPE
636 grpcsharp_call_start_duplex_streaming(grpc_call *call,
637 grpcsharp_batch_context *ctx,
638 grpc_metadata_array *initial_metadata) {
639 /* TODO: don't use magic number */
640 grpc_op ops[2];
641 ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
642 grpcsharp_metadata_array_move(&(ctx->send_initial_metadata),
643 initial_metadata);
644 ops[0].data.send_initial_metadata.count = ctx->send_initial_metadata.count;
645 ops[0].data.send_initial_metadata.metadata =
646 ctx->send_initial_metadata.metadata;
647 ops[0].flags = 0;
648 ops[0].reserved = NULL;
649
650 ops[1].op = GRPC_OP_RECV_STATUS_ON_CLIENT;
651 ops[1].data.recv_status_on_client.trailing_metadata =
652 &(ctx->recv_status_on_client.trailing_metadata);
653 ops[1].data.recv_status_on_client.status =
654 &(ctx->recv_status_on_client.status);
655 /* not using preallocation for status_details */
656 ops[1].data.recv_status_on_client.status_details =
657 &(ctx->recv_status_on_client.status_details);
658 ops[1].data.recv_status_on_client.status_details_capacity =
659 &(ctx->recv_status_on_client.status_details_capacity);
660 ops[1].flags = 0;
661 ops[1].reserved = NULL;
662
663 return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx,
664 NULL);
665 }
666
667 GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_recv_initial_metadata(
668 grpc_call *call, grpcsharp_batch_context *ctx) {
669 /* TODO: don't use magic number */
670 grpc_op ops[1];
671 ops[0].op = GRPC_OP_RECV_INITIAL_METADATA;
672 ops[0].data.recv_initial_metadata = &(ctx->recv_initial_metadata);
673 ops[0].flags = 0;
674 ops[0].reserved = NULL;
675
676 return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx,
677 NULL);
678 }
679
680 GPR_EXPORT grpc_call_error GPR_CALLTYPE
681 grpcsharp_call_send_message(grpc_call *call, grpcsharp_batch_context *ctx,
682 const char *send_buffer, size_t send_buffer_len,
683 uint32_t write_flags,
684 int32_t send_empty_initial_metadata) {
685 /* TODO: don't use magic number */
686 grpc_op ops[2];
687 size_t nops = send_empty_initial_metadata ? 2 : 1;
688 ops[0].op = GRPC_OP_SEND_MESSAGE;
689 ctx->send_message = string_to_byte_buffer(send_buffer, send_buffer_len);
690 ops[0].data.send_message = ctx->send_message;
691 ops[0].flags = write_flags;
692 ops[0].reserved = NULL;
693 ops[1].op = GRPC_OP_SEND_INITIAL_METADATA;
694 ops[1].data.send_initial_metadata.count = 0;
695 ops[1].data.send_initial_metadata.metadata = NULL;
696 ops[1].flags = 0;
697 ops[1].reserved = NULL;
698
699 return grpc_call_start_batch(call, ops, nops, ctx, NULL);
700 }
701
702 GPR_EXPORT grpc_call_error GPR_CALLTYPE
703 grpcsharp_call_send_close_from_client(grpc_call *call,
704 grpcsharp_batch_context *ctx) {
705 /* TODO: don't use magic number */
706 grpc_op ops[1];
707 ops[0].op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
708 ops[0].flags = 0;
709 ops[0].reserved = NULL;
710
711 return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx,
712 NULL);
713 }
714
715 GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_send_status_from_server(
716 grpc_call *call, grpcsharp_batch_context *ctx, grpc_status_code status_code,
717 const char *status_details, grpc_metadata_array *trailing_metadata,
718 int32_t send_empty_initial_metadata) {
719 /* TODO: don't use magic number */
720 grpc_op ops[2];
721 size_t nops = send_empty_initial_metadata ? 2 : 1;
722 ops[0].op = GRPC_OP_SEND_STATUS_FROM_SERVER;
723 ops[0].data.send_status_from_server.status = status_code;
724 ops[0].data.send_status_from_server.status_details =
725 gpr_strdup(status_details);
726 grpcsharp_metadata_array_move(
727 &(ctx->send_status_from_server.trailing_metadata), trailing_metadata);
728 ops[0].data.send_status_from_server.trailing_metadata_count =
729 ctx->send_status_from_server.trailing_metadata.count;
730 ops[0].data.send_status_from_server.trailing_metadata =
731 ctx->send_status_from_server.trailing_metadata.metadata;
732 ops[0].flags = 0;
733 ops[0].reserved = NULL;
734 ops[1].op = GRPC_OP_SEND_INITIAL_METADATA;
735 ops[1].data.send_initial_metadata.count = 0;
736 ops[1].data.send_initial_metadata.metadata = NULL;
737 ops[1].flags = 0;
738 ops[1].reserved = NULL;
739
740 return grpc_call_start_batch(call, ops, nops, ctx, NULL);
741 }
742
743 GPR_EXPORT grpc_call_error GPR_CALLTYPE
744 grpcsharp_call_recv_message(grpc_call *call, grpcsharp_batch_context *ctx) {
745 /* TODO: don't use magic number */
746 grpc_op ops[1];
747 ops[0].op = GRPC_OP_RECV_MESSAGE;
748 ops[0].data.recv_message = &(ctx->recv_message);
749 ops[0].flags = 0;
750 ops[0].reserved = NULL;
751 return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx,
752 NULL);
753 }
754
755 GPR_EXPORT grpc_call_error GPR_CALLTYPE
756 grpcsharp_call_start_serverside(grpc_call *call, grpcsharp_batch_context *ctx) {
757 /* TODO: don't use magic number */
758 grpc_op ops[1];
759 ops[0].op = GRPC_OP_RECV_CLOSE_ON_SERVER;
760 ops[0].data.recv_close_on_server.cancelled =
761 (&ctx->recv_close_on_server_cancelled);
762 ops[0].flags = 0;
763 ops[0].reserved = NULL;
764
765 return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx,
766 NULL);
767 }
768
769 GPR_EXPORT grpc_call_error GPR_CALLTYPE
770 grpcsharp_call_send_initial_metadata(grpc_call *call,
771 grpcsharp_batch_context *ctx,
772 grpc_metadata_array *initial_metadata) {
773 /* TODO: don't use magic number */
774 grpc_op ops[1];
775 ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
776 grpcsharp_metadata_array_move(&(ctx->send_initial_metadata),
777 initial_metadata);
778 ops[0].data.send_initial_metadata.count = ctx->send_initial_metadata.count;
779 ops[0].data.send_initial_metadata.metadata =
780 ctx->send_initial_metadata.metadata;
781 ops[0].flags = 0;
782 ops[0].reserved = NULL;
783
784 return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx,
785 NULL);
786 }
787
788 GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_set_credentials(
789 grpc_call *call,
790 grpc_call_credentials *creds) {
791 return grpc_call_set_credentials(call, creds);
792 }
793
794 /* Server */
795
796 GPR_EXPORT grpc_server *GPR_CALLTYPE
797 grpcsharp_server_create(grpc_completion_queue *cq,
798 const grpc_channel_args *args) {
799 grpc_server *server = grpc_server_create(args, NULL);
800 grpc_server_register_completion_queue(server, cq, NULL);
801 return server;
802 }
803
804 GPR_EXPORT int32_t GPR_CALLTYPE
805 grpcsharp_server_add_insecure_http2_port(grpc_server *server, const char *addr) {
806 return grpc_server_add_insecure_http2_port(server, addr);
807 }
808
809 GPR_EXPORT void GPR_CALLTYPE grpcsharp_server_start(grpc_server *server) {
810 grpc_server_start(server);
811 }
812
813 GPR_EXPORT void GPR_CALLTYPE
814 grpcsharp_server_shutdown_and_notify_callback(grpc_server *server,
815 grpc_completion_queue *cq,
816 grpcsharp_batch_context *ctx) {
817 grpc_server_shutdown_and_notify(server, cq, ctx);
818 }
819
820 GPR_EXPORT void GPR_CALLTYPE grpcsharp_server_cancel_all_calls(grpc_server *serv er) {
821 grpc_server_cancel_all_calls(server);
822 }
823
824 GPR_EXPORT void GPR_CALLTYPE grpcsharp_server_destroy(grpc_server *server) {
825 grpc_server_destroy(server);
826 }
827
828 GPR_EXPORT grpc_call_error GPR_CALLTYPE
829 grpcsharp_server_request_call(grpc_server *server, grpc_completion_queue *cq,
830 grpcsharp_batch_context *ctx) {
831 return grpc_server_request_call(
832 server, &(ctx->server_rpc_new.call), &(ctx->server_rpc_new.call_details),
833 &(ctx->server_rpc_new.request_metadata), cq, cq, ctx);
834 }
835
836 /* Security */
837
838 static char *default_pem_root_certs = NULL;
839
840 static grpc_ssl_roots_override_result override_ssl_roots_handler(
841 char **pem_root_certs) {
842 if (!default_pem_root_certs) {
843 *pem_root_certs = NULL;
844 return GRPC_SSL_ROOTS_OVERRIDE_FAIL_PERMANENTLY;
845 }
846 *pem_root_certs = gpr_strdup(default_pem_root_certs);
847 return GRPC_SSL_ROOTS_OVERRIDE_OK;
848 }
849
850 GPR_EXPORT void GPR_CALLTYPE grpcsharp_override_default_ssl_roots(
851 const char *pem_root_certs) {
852 /*
853 * This currently wastes ~300kB of memory by keeping a copy of roots
854 * in a static variable, but for desktop/server use, the overhead
855 * is negligible. In the future, we might want to change the behavior
856 * for mobile (e.g. Xamarin).
857 */
858 default_pem_root_certs = gpr_strdup(pem_root_certs);
859 grpc_set_ssl_roots_override_callback(override_ssl_roots_handler);
860 }
861
862 GPR_EXPORT grpc_channel_credentials *GPR_CALLTYPE
863 grpcsharp_ssl_credentials_create(const char *pem_root_certs,
864 const char *key_cert_pair_cert_chain,
865 const char *key_cert_pair_private_key) {
866 grpc_ssl_pem_key_cert_pair key_cert_pair;
867 if (key_cert_pair_cert_chain || key_cert_pair_private_key) {
868 key_cert_pair.cert_chain = key_cert_pair_cert_chain;
869 key_cert_pair.private_key = key_cert_pair_private_key;
870 return grpc_ssl_credentials_create(pem_root_certs, &key_cert_pair, NULL);
871 } else {
872 GPR_ASSERT(!key_cert_pair_cert_chain);
873 GPR_ASSERT(!key_cert_pair_private_key);
874 return grpc_ssl_credentials_create(pem_root_certs, NULL, NULL);
875 }
876 }
877
878 GPR_EXPORT void GPR_CALLTYPE grpcsharp_channel_credentials_release(
879 grpc_channel_credentials *creds) {
880 grpc_channel_credentials_release(creds);
881 }
882
883 GPR_EXPORT void GPR_CALLTYPE grpcsharp_call_credentials_release(
884 grpc_call_credentials *creds) {
885 grpc_call_credentials_release(creds);
886 }
887
888 GPR_EXPORT grpc_channel *GPR_CALLTYPE
889 grpcsharp_secure_channel_create(grpc_channel_credentials *creds,
890 const char *target,
891 const grpc_channel_args *args) {
892 return grpc_secure_channel_create(creds, target, args, NULL);
893 }
894
895 GPR_EXPORT grpc_server_credentials *GPR_CALLTYPE
896 grpcsharp_ssl_server_credentials_create(
897 const char *pem_root_certs, const char **key_cert_pair_cert_chain_array,
898 const char **key_cert_pair_private_key_array, size_t num_key_cert_pairs,
899 int force_client_auth) {
900 size_t i;
901 grpc_server_credentials *creds;
902 grpc_ssl_pem_key_cert_pair *key_cert_pairs =
903 gpr_malloc(sizeof(grpc_ssl_pem_key_cert_pair) * num_key_cert_pairs);
904 memset(key_cert_pairs, 0,
905 sizeof(grpc_ssl_pem_key_cert_pair) * num_key_cert_pairs);
906
907 for (i = 0; i < num_key_cert_pairs; i++) {
908 if (key_cert_pair_cert_chain_array[i] ||
909 key_cert_pair_private_key_array[i]) {
910 key_cert_pairs[i].cert_chain = key_cert_pair_cert_chain_array[i];
911 key_cert_pairs[i].private_key = key_cert_pair_private_key_array[i];
912 }
913 }
914 creds = grpc_ssl_server_credentials_create(pem_root_certs, key_cert_pairs,
915 num_key_cert_pairs,
916 force_client_auth, NULL);
917 gpr_free(key_cert_pairs);
918 return creds;
919 }
920
921 GPR_EXPORT void GPR_CALLTYPE grpcsharp_server_credentials_release(
922 grpc_server_credentials *creds) {
923 grpc_server_credentials_release(creds);
924 }
925
926 GPR_EXPORT int32_t GPR_CALLTYPE
927 grpcsharp_server_add_secure_http2_port(grpc_server *server, const char *addr,
928 grpc_server_credentials *creds) {
929 return grpc_server_add_secure_http2_port(server, addr, creds);
930 }
931
932 GPR_EXPORT grpc_channel_credentials *GPR_CALLTYPE grpcsharp_composite_channel_cr edentials_create(
933 grpc_channel_credentials *channel_creds,
934 grpc_call_credentials *call_creds) {
935 return grpc_composite_channel_credentials_create(channel_creds, call_creds, NU LL);
936 }
937
938 GPR_EXPORT grpc_call_credentials *GPR_CALLTYPE grpcsharp_composite_call_credenti als_create(
939 grpc_call_credentials *creds1,
940 grpc_call_credentials *creds2) {
941 return grpc_composite_call_credentials_create(creds1, creds2, NULL);
942 }
943
944
945 /* Metadata credentials plugin */
946
947 GPR_EXPORT void GPR_CALLTYPE grpcsharp_metadata_credentials_notify_from_plugin(
948 grpc_credentials_plugin_metadata_cb cb,
949 void *user_data, grpc_metadata_array *metadata,
950 grpc_status_code status, const char *error_details) {
951 cb(user_data, metadata->metadata, metadata->count, status, error_details);
952 }
953
954 typedef void(GPR_CALLTYPE *grpcsharp_metadata_interceptor_func)(
955 void *state, const char *service_url, const char *method_name,
956 grpc_credentials_plugin_metadata_cb cb,
957 void *user_data, int32_t is_destroy);
958
959 static void grpcsharp_get_metadata_handler(
960 void *state, grpc_auth_metadata_context context,
961 grpc_credentials_plugin_metadata_cb cb, void *user_data) {
962 grpcsharp_metadata_interceptor_func interceptor =
963 (grpcsharp_metadata_interceptor_func)(intptr_t)state;
964 interceptor(state, context.service_url, context.method_name, cb, user_data, 0) ;
965 }
966
967 static void grpcsharp_metadata_credentials_destroy_handler(void *state) {
968 grpcsharp_metadata_interceptor_func interceptor =
969 (grpcsharp_metadata_interceptor_func)(intptr_t)state;
970 interceptor(state, NULL, NULL, NULL, NULL, 1);
971 }
972
973 GPR_EXPORT grpc_call_credentials *GPR_CALLTYPE grpcsharp_metadata_credentials_cr eate_from_plugin(
974 grpcsharp_metadata_interceptor_func metadata_interceptor) {
975 grpc_metadata_credentials_plugin plugin;
976 plugin.get_metadata = grpcsharp_get_metadata_handler;
977 plugin.destroy = grpcsharp_metadata_credentials_destroy_handler;
978 plugin.state = (void*)(intptr_t)metadata_interceptor;
979 plugin.type = "";
980 return grpc_metadata_credentials_create_from_plugin(plugin, NULL);
981 }
982
983 /* Logging */
984
985 typedef void(GPR_CALLTYPE *grpcsharp_log_func)(const char *file, int32_t line,
986 uint64_t thd_id,
987 const char *severity_string,
988 const char *msg);
989 static grpcsharp_log_func log_func = NULL;
990
991 /* Redirects gpr_log to log_func callback */
992 static void grpcsharp_log_handler(gpr_log_func_args *args) {
993 log_func(args->file, args->line, gpr_thd_currentid(),
994 gpr_log_severity_string(args->severity), args->message);
995 }
996
997 GPR_EXPORT void GPR_CALLTYPE grpcsharp_redirect_log(grpcsharp_log_func func) {
998 GPR_ASSERT(func);
999 log_func = func;
1000 gpr_set_log_function(grpcsharp_log_handler);
1001 }
1002
1003 typedef void(GPR_CALLTYPE *test_callback_funcptr)(int32_t success);
1004
1005 /* Version info */
1006 GPR_EXPORT const char *GPR_CALLTYPE grpcsharp_version_string() {
1007 return grpc_version_string();
1008 }
1009
1010 /* For testing */
1011 GPR_EXPORT void GPR_CALLTYPE
1012 grpcsharp_test_callback(test_callback_funcptr callback) {
1013 callback(1);
1014 }
1015
1016 /* For testing */
1017 GPR_EXPORT void *GPR_CALLTYPE grpcsharp_test_nop(void *ptr) { return ptr; }
1018
1019 /* For testing */
1020 GPR_EXPORT int32_t GPR_CALLTYPE grpcsharp_sizeof_grpc_event(void) {
1021 return sizeof(grpc_event);
1022 }
OLDNEW
« no previous file with comments | « third_party/grpc/src/csharp/doc/grpc_csharp_public.shfbproj ('k') | third_party/grpc/src/csharp/generate_proto_csharp.sh » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698