diff options
Diffstat (limited to 'src/node/ext')
-rw-r--r-- | src/node/ext/call.cc | 59 | ||||
-rw-r--r-- | src/node/ext/event.cc | 61 |
2 files changed, 72 insertions, 48 deletions
diff --git a/src/node/ext/call.cc b/src/node/ext/call.cc index 6434c2f0d5..3261b780f7 100644 --- a/src/node/ext/call.cc +++ b/src/node/ext/call.cc @@ -33,6 +33,7 @@ #include <node.h> +#include "grpc/support/log.h" #include "grpc/grpc.h" #include "grpc/support/time.h" #include "byte_buffer.h" @@ -173,31 +174,43 @@ NAN_METHOD(Call::AddMetadata) { return NanThrowTypeError("addMetadata can only be called on Call objects"); } Call *call = ObjectWrap::Unwrap<Call>(args.This()); - for (int i = 0; !args[i]->IsUndefined(); i++) { - if (!args[i]->IsObject()) { + if (!args[0]->IsObject()) { + return NanThrowTypeError("addMetadata's first argument must be an object"); + } + Handle<Object> metadata = args[0]->ToObject(); + Handle<Array> keys(metadata->GetOwnPropertyNames()); + for (unsigned int i = 0; i < keys->Length(); i++) { + Handle<String> current_key(keys->Get(i)->ToString()); + if (!metadata->Get(current_key)->IsArray()) { return NanThrowTypeError( - "addMetadata arguments must be objects with key and value"); + "addMetadata's first argument's values must be arrays"); } - Handle<Object> item = args[i]->ToObject(); - Handle<Value> key = item->Get(NanNew("key")); - if (!key->IsString()) { - return NanThrowTypeError( - "objects passed to addMetadata must have key->string"); - } - Handle<Value> value = item->Get(NanNew("value")); - if (!Buffer::HasInstance(value)) { - return NanThrowTypeError( - "objects passed to addMetadata must have value->Buffer"); - } - grpc_metadata metadata; - NanUtf8String utf8_key(key); - metadata.key = *utf8_key; - metadata.value = Buffer::Data(value); - metadata.value_length = Buffer::Length(value); - grpc_call_error error = - grpc_call_add_metadata(call->wrapped_call, &metadata, 0); - if (error != GRPC_CALL_OK) { - return NanThrowError("addMetadata failed", error); + NanUtf8String utf8_key(current_key); + Handle<Array> values = Local<Array>::Cast(metadata->Get(current_key)); + for (unsigned int j = 0; j < values->Length(); j++) { + Handle<Value> value = values->Get(j); + grpc_metadata metadata; + grpc_call_error error; + metadata.key = *utf8_key; + if (Buffer::HasInstance(value)) { + metadata.value = Buffer::Data(value); + metadata.value_length = Buffer::Length(value); + error = grpc_call_add_metadata(call->wrapped_call, &metadata, 0); + } else if (value->IsString()) { + Handle<String> string_value = value->ToString(); + NanUtf8String utf8_value(string_value); + metadata.value = *utf8_value; + metadata.value_length = string_value->Length(); + gpr_log(GPR_DEBUG, "adding metadata: %s, %s, %d", metadata.key, + metadata.value, metadata.value_length); + error = grpc_call_add_metadata(call->wrapped_call, &metadata, 0); + } else { + return NanThrowTypeError( + "addMetadata values must be strings or buffers"); + } + if (error != GRPC_CALL_OK) { + return NanThrowError("addMetadata failed", error); + } } } NanReturnUndefined(); diff --git a/src/node/ext/event.cc b/src/node/ext/event.cc index 2ca38b7448..fcf046b697 100644 --- a/src/node/ext/event.cc +++ b/src/node/ext/event.cc @@ -31,6 +31,8 @@ * */ +#include <map> + #include <node.h> #include <nan.h> #include "grpc/grpc.h" @@ -43,6 +45,7 @@ namespace grpc { namespace node { +using ::node::Buffer; using v8::Array; using v8::Date; using v8::Handle; @@ -53,6 +56,36 @@ using v8::Persistent; using v8::String; using v8::Value; +Handle<Value> ParseMetadata(grpc_metadata *metadata_elements, size_t length) { + NanEscapableScope(); + std::map<char*, size_t> size_map; + std::map<char*, size_t> index_map; + + for (unsigned int i = 0; i < length; i++) { + char *key = metadata_elements[i].key; + if (size_map.count(key)) { + size_map[key] += 1; + } + index_map[key] = 0; + } + Handle<Object> metadata_object = NanNew<Object>(); + for (unsigned int i = 0; i < length; i++) { + grpc_metadata* elem = &metadata_elements[i]; + Handle<String> key_string = String::New(elem->key); + Handle<Array> array; + if (metadata_object->Has(key_string)) { + array = Handle<Array>::Cast(metadata_object->Get(key_string)); + } else { + array = NanNew<Array>(size_map[elem->key]); + metadata_object->Set(key_string, array); + } + array->Set(index_map[elem->key], + NanNewBufferHandle(elem->value, elem->value_length)); + index_map[elem->key] += 1; + } + return NanEscapeScope(metadata_object); +} + Handle<Value> GetEventData(grpc_event *event) { NanEscapableScope(); size_t count; @@ -72,18 +105,7 @@ Handle<Value> GetEventData(grpc_event *event) { case GRPC_CLIENT_METADATA_READ: count = event->data.client_metadata_read.count; items = event->data.client_metadata_read.elements; - metadata = NanNew<Array>(static_cast<int>(count)); - for (unsigned int i = 0; i < count; i++) { - Handle<Object> item_obj = NanNew<Object>(); - item_obj->Set(NanNew<String, const char *>("key"), - NanNew<String, char *>(items[i].key)); - item_obj->Set( - NanNew<String, const char *>("value"), - NanNew<String, char *>(items[i].value, - static_cast<int>(items[i].value_length))); - metadata->Set(i, item_obj); - } - return NanEscapeScope(metadata); + return NanEscapeScope(ParseMetadata(items, count)); case GRPC_FINISHED: status = NanNew<Object>(); status->Set(NanNew("code"), NanNew<Number>(event->data.finished.status)); @@ -93,18 +115,7 @@ Handle<Value> GetEventData(grpc_event *event) { } count = event->data.finished.metadata_count; items = event->data.finished.metadata_elements; - metadata = NanNew<Array>(static_cast<int>(count)); - for (unsigned int i = 0; i < count; i++) { - Handle<Object> item_obj = NanNew<Object>(); - item_obj->Set(NanNew<String, const char *>("key"), - NanNew<String, char *>(items[i].key)); - item_obj->Set( - NanNew<String, const char *>("value"), - NanNew<String, char *>(items[i].value, - static_cast<int>(items[i].value_length))); - metadata->Set(i, item_obj); - } - status->Set(NanNew("metadata"), metadata); + status->Set(NanNew("metadata"), ParseMetadata(items, count)); return NanEscapeScope(status); case GRPC_SERVER_RPC_NEW: rpc_new = NanNew<Object>(); @@ -133,7 +144,7 @@ Handle<Value> GetEventData(grpc_event *event) { static_cast<int>(items[i].value_length))); metadata->Set(i, item_obj); } - rpc_new->Set(NanNew<String, const char *>("metadata"), metadata); + rpc_new->Set(NanNew("metadata"), ParseMetadata(items, count)); return NanEscapeScope(rpc_new); default: return NanEscapeScope(NanNull()); |