diff options
Diffstat (limited to 'src/ruby/ext/grpc/rb_call.c')
-rw-r--r-- | src/ruby/ext/grpc/rb_call.c | 93 |
1 files changed, 47 insertions, 46 deletions
diff --git a/src/ruby/ext/grpc/rb_call.c b/src/ruby/ext/grpc/rb_call.c index 67a42af619..0179bd9e9b 100644 --- a/src/ruby/ext/grpc/rb_call.c +++ b/src/ruby/ext/grpc/rb_call.c @@ -121,8 +121,8 @@ static size_t md_ary_datasize(const void *p) { size_t i, datasize = sizeof(grpc_metadata_array); for (i = 0; i < ary->count; ++i) { const grpc_metadata *const md = &ary->metadata[i]; - datasize += strlen(md->key); - datasize += md->value_length; + datasize += GRPC_SLICE_LENGTH(md->key); + datasize += GRPC_SLICE_LENGTH(md->value); } datasize += ary->capacity * sizeof(grpc_metadata); return datasize; @@ -386,23 +386,23 @@ static int grpc_rb_md_ary_fill_hash_cb(VALUE key, VALUE val, VALUE md_ary_obj) { grpc_metadata_array *md_ary = NULL; long array_length; long i; - char *key_str; - size_t key_len; - char *value_str; - size_t value_len; + grpc_slice key_slice; + grpc_slice value_slice; + char* tmp_str; if (TYPE(key) == T_SYMBOL) { - key_str = (char *)rb_id2name(SYM2ID(key)); - key_len = strlen(key_str); - } else { /* StringValueCStr does all other type exclusions for us */ - key_str = StringValueCStr(key); - key_len = RSTRING_LEN(key); + key_slice = grpc_slice_from_static_string(rb_id2name(SYM2ID(key))); + } else if (TYPE(key) == T_STRING) { + key_slice = grpc_slice_from_copied_buffer(RSTRING_PTR(key), RSTRING_LEN(key)); + } else { + rb_raise(rb_eTypeError, "grpc_rb_md_ary_fill_hash_cb: bad type for key parameter"); } - if (!grpc_header_key_is_legal(key_str, key_len)) { + if (!grpc_header_key_is_legal(key_slice)) { + tmp_str = grpc_slice_to_c_string(key_slice); rb_raise(rb_eArgError, "'%s' is an invalid header key, must match [a-z0-9-_.]+", - key_str); + tmp_str); return ST_STOP; } @@ -414,33 +414,31 @@ static int grpc_rb_md_ary_fill_hash_cb(VALUE key, VALUE val, VALUE md_ary_obj) { array_length = RARRAY_LEN(val); /* If the value is an array, add capacity for each value in the array */ for (i = 0; i < array_length; i++) { - value_str = RSTRING_PTR(rb_ary_entry(val, i)); - value_len = RSTRING_LEN(rb_ary_entry(val, i)); - if (!grpc_is_binary_header(key_str, key_len) && - !grpc_header_nonbin_value_is_legal(value_str, value_len)) { + value_slice = grpc_slice_from_copied_buffer(RSTRING_PTR(rb_ary_entry(val, i)), RSTRING_LEN(rb_ary_entry(val, i))); + if (!grpc_is_binary_header(key_slice) && + !grpc_header_nonbin_value_is_legal(value_slice)) { // The value has invalid characters + tmp_str = grpc_slice_to_c_string(value_slice); rb_raise(rb_eArgError, - "Header value '%s' has invalid characters", value_str); + "Header value '%s' has invalid characters", tmp_str); return ST_STOP; } - md_ary->metadata[md_ary->count].key = key_str; - md_ary->metadata[md_ary->count].value = value_str; - md_ary->metadata[md_ary->count].value_length = value_len; + md_ary->metadata[md_ary->count].key = key_slice; + md_ary->metadata[md_ary->count].value = value_slice; md_ary->count += 1; } } else if (TYPE(val) == T_STRING) { - value_str = RSTRING_PTR(val); - value_len = RSTRING_LEN(val); - if (!grpc_is_binary_header(key_str, key_len) && - !grpc_header_nonbin_value_is_legal(value_str, value_len)) { + value_slice = grpc_slice_from_copied_buffer(RSTRING_PTR(val), RSTRING_LEN(val)); + if (!grpc_is_binary_header(key_slice) && + !grpc_header_nonbin_value_is_legal(value_slice)) { // The value has invalid characters + tmp_str = grpc_slice_to_c_string(value_slice); rb_raise(rb_eArgError, - "Header value '%s' has invalid characters", value_str); + "Header value '%s' has invalid characters", tmp_str); return ST_STOP; } - md_ary->metadata[md_ary->count].key = key_str; - md_ary->metadata[md_ary->count].value = value_str; - md_ary->metadata[md_ary->count].value_length = value_len; + md_ary->metadata[md_ary->count].key = key_slice; + md_ary->metadata[md_ary->count].value = value_slice; md_ary->count += 1; } else { rb_raise(rb_eArgError, @@ -506,22 +504,19 @@ VALUE grpc_rb_md_ary_to_h(grpc_metadata_array *md_ary) { size_t i; for (i = 0; i < md_ary->count; i++) { - key = rb_str_new2(md_ary->metadata[i].key); + key = grpc_rb_slice_to_ruby_string(md_ary->metadata[i].key); value = rb_hash_aref(result, key); if (value == Qnil) { - value = rb_str_new(md_ary->metadata[i].value, - md_ary->metadata[i].value_length); + value = grpc_rb_slice_to_ruby_string(md_ary->metadata[i].value); rb_hash_aset(result, key, value); } else if (TYPE(value) == T_ARRAY) { /* Add the string to the returned array */ - rb_ary_push(value, rb_str_new(md_ary->metadata[i].value, - md_ary->metadata[i].value_length)); + rb_ary_push(value, grpc_rb_slice_to_ruby_string(md_ary->metadata[i].value)); } else { /* Add the current value with this key and the new one to an array */ new_ary = rb_ary_new(); rb_ary_push(new_ary, value); - rb_ary_push(new_ary, rb_str_new(md_ary->metadata[i].value, - md_ary->metadata[i].value_length)); + rb_ary_push(new_ary, grpc_rb_slice_to_ruby_string(md_ary->metadata[i].value)); rb_hash_aset(result, key, new_ary); } } @@ -563,6 +558,7 @@ static int grpc_rb_call_check_op_keys_hash_cb(VALUE key, VALUE val, */ static void grpc_rb_op_update_status_from_server(grpc_op *op, grpc_metadata_array *md_ary, + grpc_slice *send_status_details, VALUE status) { VALUE code = rb_struct_aref(status, sym_code); VALUE details = rb_struct_aref(status, sym_details); @@ -579,8 +575,11 @@ static void grpc_rb_op_update_status_from_server(grpc_op *op, rb_obj_classname(code)); return; } + + *send_status_details = grpc_slice_from_copied_buffer(RSTRING_PTR(details), RSTRING_LEN(details)); + op->data.send_status_from_server.status = NUM2INT(code); - op->data.send_status_from_server.status_details = StringValueCStr(details); + op->data.send_status_from_server.status_details = send_status_details; grpc_rb_md_ary_convert(metadata_hash, md_ary); op->data.send_status_from_server.trailing_metadata_count = md_ary->count; op->data.send_status_from_server.trailing_metadata = md_ary->metadata; @@ -603,9 +602,9 @@ typedef struct run_batch_stack { grpc_metadata_array recv_trailing_metadata; int recv_cancelled; grpc_status_code recv_status; - char *recv_status_details; - size_t recv_status_details_capacity; + grpc_slice recv_status_details; unsigned write_flag; + grpc_slice send_status_details; } run_batch_stack; /* grpc_run_batch_stack_init ensures the run_batch_stack is properly @@ -631,8 +630,12 @@ static void grpc_run_batch_stack_cleanup(run_batch_stack *st) { grpc_metadata_array_destroy(&st->recv_metadata); grpc_metadata_array_destroy(&st->recv_trailing_metadata); - if (st->recv_status_details != NULL) { - gpr_free(st->recv_status_details); + if (GRPC_SLICE_START_PTR(st->send_status_details) != NULL) { + grpc_slice_unref(st->send_status_details); + } + + if (GRPC_SLICE_START_PTR(st->recv_status_details) != NULL) { + grpc_slice_unref(st->recv_status_details); } if (st->recv_message != NULL) { @@ -683,7 +686,7 @@ static void grpc_run_batch_stack_fill_ops(run_batch_stack *st, VALUE ops_hash) { /* N.B. later there is no need to explicitly delete the metadata keys * and values, they are references to data in ruby objects. */ grpc_rb_op_update_status_from_server( - &st->ops[st->op_num], &st->send_trailing_metadata, this_value); + &st->ops[st->op_num], &st->send_trailing_metadata, &st->send_status_details, this_value); break; case GRPC_OP_RECV_INITIAL_METADATA: st->ops[st->op_num].data.recv_initial_metadata = &st->recv_metadata; @@ -698,8 +701,6 @@ static void grpc_run_batch_stack_fill_ops(run_batch_stack *st, VALUE ops_hash) { &st->recv_status; st->ops[st->op_num].data.recv_status_on_client.status_details = &st->recv_status_details; - st->ops[st->op_num].data.recv_status_on_client.status_details_capacity = - &st->recv_status_details_capacity; break; case GRPC_OP_RECV_CLOSE_ON_SERVER: st->ops[st->op_num].data.recv_close_on_server.cancelled = @@ -747,9 +748,9 @@ static VALUE grpc_run_batch_stack_build_result(run_batch_stack *st) { rb_struct_aset( result, sym_status, rb_struct_new(grpc_rb_sStatus, UINT2NUM(st->recv_status), - (st->recv_status_details == NULL + (GRPC_SLICE_START_PTR(st->recv_status_details) == NULL ? Qnil - : rb_str_new2(st->recv_status_details)), + : grpc_rb_slice_to_ruby_string(st->recv_status_details)), grpc_rb_md_ary_to_h(&st->recv_trailing_metadata), NULL)); break; |