aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/csharp/ext/grpc_csharp_ext.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/csharp/ext/grpc_csharp_ext.c')
-rw-r--r--src/csharp/ext/grpc_csharp_ext.c162
1 files changed, 125 insertions, 37 deletions
diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c
index 51abb632f7..9a1c908d11 100644
--- a/src/csharp/ext/grpc_csharp_ext.c
+++ b/src/csharp/ext/grpc_csharp_ext.c
@@ -102,34 +102,114 @@ grpcsharp_batch_context *grpcsharp_batch_context_create() {
return ctx;
}
-/**
- * Destroys metadata array including keys and values.
+/*
+ * Destroys array->metadata.
+ * The array pointer itself is not freed.
+ */
+void grpcsharp_metadata_array_destroy_metadata_only(
+ grpc_metadata_array *array) {
+ gpr_free(array->metadata);
+}
+
+/*
+ * Destroys keys, values and array->metadata.
+ * The array pointer itself is not freed.
+ */
+void grpcsharp_metadata_array_destroy_metadata_including_entries(
+ grpc_metadata_array *array) {
+ size_t i;
+ if (array->metadata) {
+ for (i = 0; i < array->count; i++) {
+ gpr_free((void *)array->metadata[i].key);
+ gpr_free((void *)array->metadata[i].value);
+ }
+ }
+ gpr_free(array->metadata);
+}
+
+/*
+ * Fully destroys the metadata array.
+ */
+GPR_EXPORT void GPR_CALLTYPE
+grpcsharp_metadata_array_destroy_full(grpc_metadata_array *array) {
+ if (!array) {
+ return;
+ }
+ grpcsharp_metadata_array_destroy_metadata_including_entries(array);
+ gpr_free(array);
+}
+
+/*
+ * Creates an empty metadata array with given capacity.
+ * Array can later be destroyed by grpc_metadata_array_destroy_full.
*/
-void grpcsharp_metadata_array_destroy_recursive(grpc_metadata_array *array) {
- if (!array->metadata) {
+GPR_EXPORT grpc_metadata_array *GPR_CALLTYPE
+grpcsharp_metadata_array_create(size_t capacity) {
+ grpc_metadata_array *array =
+ (grpc_metadata_array *)gpr_malloc(sizeof(grpc_metadata_array));
+ grpc_metadata_array_init(array);
+ array->capacity = capacity;
+ array->count = 0;
+ if (capacity > 0) {
+ array->metadata =
+ (grpc_metadata *)gpr_malloc(sizeof(grpc_metadata) * capacity);
+ memset(array->metadata, 0, sizeof(grpc_metadata) * capacity);
+ } else {
+ array->metadata = NULL;
+ }
+ return array;
+}
+
+GPR_EXPORT void GPR_CALLTYPE
+grpcsharp_metadata_array_add(grpc_metadata_array *array, const char *key,
+ const char *value, size_t value_length) {
+ size_t i = array->count;
+ GPR_ASSERT(array->count < array->capacity);
+ array->metadata[i].key = gpr_strdup(key);
+ array->metadata[i].value = (char *)gpr_malloc(value_length);
+ memcpy((void *)array->metadata[i].value, value, value_length);
+ array->metadata[i].value_length = value_length;
+ array->count++;
+}
+
+/* Move contents of metadata array */
+void grpcsharp_metadata_array_move(grpc_metadata_array *dest,
+ grpc_metadata_array *src) {
+ if (!src) {
+ dest->capacity = 0;
+ dest->count = 0;
+ dest->metadata = NULL;
return;
}
- /* TODO: destroy also keys and values */
- grpc_metadata_array_destroy(array);
+
+ dest->capacity = src->capacity;
+ dest->count = src->count;
+ dest->metadata = src->metadata;
+
+ src->capacity = 0;
+ src->count = 0;
+ src->metadata = NULL;
}
void grpcsharp_batch_context_destroy(grpcsharp_batch_context *ctx) {
if (!ctx) {
return;
}
- grpcsharp_metadata_array_destroy_recursive(&(ctx->send_initial_metadata));
+ grpcsharp_metadata_array_destroy_metadata_including_entries(
+ &(ctx->send_initial_metadata));
grpc_byte_buffer_destroy(ctx->send_message);
- grpcsharp_metadata_array_destroy_recursive(
+ grpcsharp_metadata_array_destroy_metadata_including_entries(
&(ctx->send_status_from_server.trailing_metadata));
gpr_free(ctx->send_status_from_server.status_details);
- grpc_metadata_array_destroy(&(ctx->recv_initial_metadata));
+ grpcsharp_metadata_array_destroy_metadata_only(&(ctx->recv_initial_metadata));
grpc_byte_buffer_destroy(ctx->recv_message);
- grpc_metadata_array_destroy(&(ctx->recv_status_on_client.trailing_metadata));
+ grpcsharp_metadata_array_destroy_metadata_only(
+ &(ctx->recv_status_on_client.trailing_metadata));
gpr_free((void *)ctx->recv_status_on_client.status_details);
/* NOTE: ctx->server_rpc_new.call is not destroyed because callback handler is
@@ -137,7 +217,8 @@ void grpcsharp_batch_context_destroy(grpcsharp_batch_context *ctx) {
to take its ownership. */
grpc_call_details_destroy(&(ctx->server_rpc_new.call_details));
- grpc_metadata_array_destroy(&(ctx->server_rpc_new.request_metadata));
+ grpcsharp_metadata_array_destroy_metadata_only(
+ &(ctx->server_rpc_new.request_metadata));
gpr_free(ctx);
}
@@ -346,17 +427,19 @@ grpcsharp_call_start_write_from_copied_buffer(grpc_call *call,
GPR_EXPORT grpc_call_error GPR_CALLTYPE
grpcsharp_call_start_unary(grpc_call *call, callback_funcptr callback,
- const char *send_buffer, size_t send_buffer_len) {
+ const char *send_buffer, size_t send_buffer_len,
+ grpc_metadata_array *initial_metadata) {
/* TODO: don't use magic number */
grpc_op ops[6];
grpcsharp_batch_context *ctx = grpcsharp_batch_context_create();
ctx->callback = callback;
- /* TODO: implement sending the metadata... */
ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
- /* ctx->send_initial_metadata is already zeroed out. */
- ops[0].data.send_initial_metadata.count = 0;
- ops[0].data.send_initial_metadata.metadata = NULL;
+ grpcsharp_metadata_array_move(&(ctx->send_initial_metadata),
+ initial_metadata);
+ ops[0].data.send_initial_metadata.count = ctx->send_initial_metadata.count;
+ ops[0].data.send_initial_metadata.metadata =
+ ctx->send_initial_metadata.metadata;
ops[1].op = GRPC_OP_SEND_MESSAGE;
ctx->send_message = string_to_byte_buffer(send_buffer, send_buffer_len);
@@ -389,9 +472,11 @@ GPR_EXPORT void GPR_CALLTYPE
grpcsharp_call_blocking_unary(grpc_call *call,
grpc_completion_queue *dedicated_cq,
callback_funcptr callback,
- const char *send_buffer, size_t send_buffer_len) {
+ const char *send_buffer, size_t send_buffer_len,
+ grpc_metadata_array *initial_metadata) {
GPR_ASSERT(grpcsharp_call_start_unary(call, callback, send_buffer,
- send_buffer_len) == GRPC_CALL_OK);
+ send_buffer_len,
+ initial_metadata) == GRPC_CALL_OK);
/* TODO: we would like to use pluck, but we don't know the tag */
GPR_ASSERT(grpcsharp_completion_queue_next_with_callback(dedicated_cq) ==
@@ -403,17 +488,19 @@ grpcsharp_call_blocking_unary(grpc_call *call,
GPR_EXPORT grpc_call_error GPR_CALLTYPE
grpcsharp_call_start_client_streaming(grpc_call *call,
- callback_funcptr callback) {
+ callback_funcptr callback,
+ grpc_metadata_array *initial_metadata) {
/* TODO: don't use magic number */
grpc_op ops[4];
grpcsharp_batch_context *ctx = grpcsharp_batch_context_create();
ctx->callback = callback;
- /* TODO: implement sending the metadata... */
ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
- /* ctx->send_initial_metadata is already zeroed out. */
- ops[0].data.send_initial_metadata.count = 0;
- ops[0].data.send_initial_metadata.metadata = NULL;
+ grpcsharp_metadata_array_move(&(ctx->send_initial_metadata),
+ initial_metadata);
+ ops[0].data.send_initial_metadata.count = ctx->send_initial_metadata.count;
+ ops[0].data.send_initial_metadata.metadata =
+ ctx->send_initial_metadata.metadata;
ops[1].op = GRPC_OP_RECV_INITIAL_METADATA;
ops[1].data.recv_initial_metadata = &(ctx->recv_initial_metadata);
@@ -435,21 +522,20 @@ grpcsharp_call_start_client_streaming(grpc_call *call,
return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx);
}
-GPR_EXPORT grpc_call_error GPR_CALLTYPE
-grpcsharp_call_start_server_streaming(grpc_call *call,
- callback_funcptr callback,
- const char *send_buffer,
- size_t send_buffer_len) {
+GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_start_server_streaming(
+ grpc_call *call, callback_funcptr callback, const char *send_buffer,
+ size_t send_buffer_len, grpc_metadata_array *initial_metadata) {
/* TODO: don't use magic number */
grpc_op ops[5];
grpcsharp_batch_context *ctx = grpcsharp_batch_context_create();
ctx->callback = callback;
- /* TODO: implement sending the metadata... */
ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
- /* ctx->send_initial_metadata is already zeroed out. */
- ops[0].data.send_initial_metadata.count = 0;
- ops[0].data.send_initial_metadata.metadata = NULL;
+ grpcsharp_metadata_array_move(&(ctx->send_initial_metadata),
+ initial_metadata);
+ ops[0].data.send_initial_metadata.count = ctx->send_initial_metadata.count;
+ ops[0].data.send_initial_metadata.metadata =
+ ctx->send_initial_metadata.metadata;
ops[1].op = GRPC_OP_SEND_MESSAGE;
ctx->send_message = string_to_byte_buffer(send_buffer, send_buffer_len);
@@ -476,17 +562,19 @@ grpcsharp_call_start_server_streaming(grpc_call *call,
GPR_EXPORT grpc_call_error GPR_CALLTYPE
grpcsharp_call_start_duplex_streaming(grpc_call *call,
- callback_funcptr callback) {
+ callback_funcptr callback,
+ grpc_metadata_array *initial_metadata) {
/* TODO: don't use magic number */
grpc_op ops[3];
grpcsharp_batch_context *ctx = grpcsharp_batch_context_create();
ctx->callback = callback;
- /* TODO: implement sending the metadata... */
ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
- /* ctx->send_initial_metadata is already zeroed out. */
- ops[0].data.send_initial_metadata.count = 0;
- ops[0].data.send_initial_metadata.metadata = NULL;
+ grpcsharp_metadata_array_move(&(ctx->send_initial_metadata),
+ initial_metadata);
+ ops[0].data.send_initial_metadata.count = ctx->send_initial_metadata.count;
+ ops[0].data.send_initial_metadata.metadata =
+ ctx->send_initial_metadata.metadata;
ops[1].op = GRPC_OP_RECV_INITIAL_METADATA;
ops[1].data.recv_initial_metadata = &(ctx->recv_initial_metadata);