diff --git a/ext/byte_buffer.cc b/ext/byte_buffer.cc index 7d6fb198..fc339fc4 100644 --- a/ext/byte_buffer.cc +++ b/ext/byte_buffer.cc @@ -40,7 +40,6 @@ #include "grpc/slice.h" #include "byte_buffer.h" -#include "slice.h" namespace grpc { namespace node { @@ -55,7 +54,10 @@ using v8::Value; grpc_byte_buffer *BufferToByteBuffer(Local buffer) { Nan::HandleScope scope; - grpc_slice slice = CreateSliceFromBuffer(buffer); + int length = ::node::Buffer::Length(buffer); + char *data = ::node::Buffer::Data(buffer); + grpc_slice slice = grpc_slice_malloc(length); + memcpy(GRPC_SLICE_START_PTR(slice), data, length); grpc_byte_buffer *byte_buffer(grpc_raw_byte_buffer_create(&slice, 1)); grpc_slice_unref(slice); return byte_buffer; diff --git a/ext/call.cc b/ext/call.cc index 9213d5e8..191e763e 100644 --- a/ext/call.cc +++ b/ext/call.cc @@ -48,7 +48,6 @@ #include "completion_queue.h" #include "completion_queue_async_worker.h" #include "call_credentials.h" -#include "slice.h" #include "timeval.h" using std::unique_ptr; @@ -97,7 +96,8 @@ Local nanErrorWithCode(const char *msg, grpc_call_error code) { return scope.Escape(err); } -bool CreateMetadataArray(Local metadata, grpc_metadata_array *array) { +bool CreateMetadataArray(Local metadata, grpc_metadata_array *array, + shared_ptr resources) { HandleScope scope; grpc_metadata_array_init(array); Local keys = Nan::GetOwnPropertyNames(metadata).ToLocalChecked(); @@ -113,25 +113,32 @@ bool CreateMetadataArray(Local metadata, grpc_metadata_array *array) { array->metadata = reinterpret_cast( gpr_malloc(array->capacity * sizeof(grpc_metadata))); for (unsigned int i = 0; i < keys->Length(); i++) { - Local current_key(Nan::To(keys->Get(i)).ToLocalChecked()); + Local current_key(keys->Get(i)->ToString()); + Utf8String *utf8_key = new Utf8String(current_key); + resources->strings.push_back(unique_ptr(utf8_key)); Local values = Local::Cast( Nan::Get(metadata, current_key).ToLocalChecked()); - grpc_slice key_slice = grpc_slice_intern(CreateSliceFromString(current_key)); for (unsigned int j = 0; j < values->Length(); j++) { Local value = Nan::Get(values, j).ToLocalChecked(); grpc_metadata *current = &array->metadata[array->count]; - current->key = key_slice; + current->key = **utf8_key; // Only allow binary headers for "-bin" keys - if (grpc_is_binary_header(key_slice)) { + if (grpc_is_binary_header(current->key, strlen(current->key))) { if (::node::Buffer::HasInstance(value)) { - current->value = CreateSliceFromBuffer(value); + current->value = ::node::Buffer::Data(value); + current->value_length = ::node::Buffer::Length(value); + PersistentValue *handle = new PersistentValue(value); + resources->handles.push_back(unique_ptr(handle)); } else { return false; } } else { if (value->IsString()) { Local string_value = Nan::To(value).ToLocalChecked(); - current->value = CreateSliceFromString(string_value); + Utf8String *utf8_value = new Utf8String(string_value); + resources->strings.push_back(unique_ptr(utf8_value)); + current->value = **utf8_value; + current->value_length = string_value->Length(); } else { return false; } @@ -146,25 +153,40 @@ Local ParseMetadata(const grpc_metadata_array *metadata_array) { EscapableHandleScope scope; grpc_metadata *metadata_elements = metadata_array->metadata; size_t length = metadata_array->count; + std::map size_map; + std::map index_map; + + for (unsigned int i = 0; i < length; i++) { + const char *key = metadata_elements[i].key; + if (size_map.count(key)) { + size_map[key] += 1; + } else { + size_map[key] = 1; + } + index_map[key] = 0; + } Local metadata_object = Nan::New(); for (unsigned int i = 0; i < length; i++) { grpc_metadata* elem = &metadata_elements[i]; - // TODO(murgatroid99): Use zero-copy string construction instead - Local key_string = CopyStringFromSlice(elem->key); + Local key_string = Nan::New(elem->key).ToLocalChecked(); Local array; MaybeLocal maybe_array = Nan::Get(metadata_object, key_string); if (maybe_array.IsEmpty() || !maybe_array.ToLocalChecked()->IsArray()) { - array = Nan::New(0); + array = Nan::New(size_map[elem->key]); Nan::Set(metadata_object, key_string, array); } else { array = Local::Cast(maybe_array.ToLocalChecked()); } - if (grpc_is_binary_header(elem->key)) { - Nan::Set(array, array->Length(), CreateBufferFromSlice(elem->value)); + if (grpc_is_binary_header(elem->key, strlen(elem->key))) { + Nan::Set(array, index_map[elem->key], + MakeFastBuffer( + Nan::CopyBuffer(elem->value, + elem->value_length).ToLocalChecked())); } else { - // TODO(murgatroid99): Use zero-copy string construction instead - Nan::Set(array, array->Length(), CopyStringFromSlice(elem->value)); + Nan::Set(array, index_map[elem->key], + Nan::New(elem->value).ToLocalChecked()); } + index_map[elem->key] += 1; } return scope.Escape(metadata_object); } @@ -183,7 +205,8 @@ class SendMetadataOp : public Op { EscapableHandleScope scope; return scope.Escape(Nan::True()); } - bool ParseOp(Local value, grpc_op *out) { + bool ParseOp(Local value, grpc_op *out, + shared_ptr resources) { if (!value->IsObject()) { return false; } @@ -193,7 +216,7 @@ class SendMetadataOp : public Op { return false; } if (!CreateMetadataArray(maybe_metadata.ToLocalChecked(), - &array)) { + &array, resources)) { return false; } out->data.send_initial_metadata.count = array.count; @@ -223,7 +246,8 @@ class SendMessageOp : public Op { EscapableHandleScope scope; return scope.Escape(Nan::True()); } - bool ParseOp(Local value, grpc_op *out) { + bool ParseOp(Local value, grpc_op *out, + shared_ptr resources) { if (!::node::Buffer::HasInstance(value)) { return false; } @@ -239,6 +263,8 @@ class SendMessageOp : public Op { } send_message = BufferToByteBuffer(value); out->data.send_message = send_message; + PersistentValue *handle = new PersistentValue(value); + resources->handles.push_back(unique_ptr(handle)); return true; } bool IsFinalOp() { @@ -258,7 +284,8 @@ class SendClientCloseOp : public Op { EscapableHandleScope scope; return scope.Escape(Nan::True()); } - bool ParseOp(Local value, grpc_op *out) { + bool ParseOp(Local value, grpc_op *out, + shared_ptr resources) { return true; } bool IsFinalOp() { @@ -272,14 +299,12 @@ class SendClientCloseOp : public Op { class SendServerStatusOp : public Op { public: - ~SendServerStatusOp() { - grpc_slice_unref(details); - } Local GetNodeValue() const { EscapableHandleScope scope; return scope.Escape(Nan::True()); } - bool ParseOp(Local value, grpc_op *out) { + bool ParseOp(Local value, grpc_op *out, + shared_ptr resources) { if (!value->IsObject()) { return false; } @@ -314,15 +339,16 @@ class SendServerStatusOp : public Op { Local details = Nan::To( maybe_details.ToLocalChecked()).ToLocalChecked(); grpc_metadata_array array; - if (!CreateMetadataArray(metadata, &array)) { + if (!CreateMetadataArray(metadata, &array, resources)) { return false; } out->data.send_status_from_server.trailing_metadata_count = array.count; out->data.send_status_from_server.trailing_metadata = array.metadata; out->data.send_status_from_server.status = static_cast(code); - this->details = CreateSliceFromString(details); - out->data.send_status_from_server.status_details = &this->details; + Utf8String *str = new Utf8String(details); + resources->strings.push_back(unique_ptr(str)); + out->data.send_status_from_server.status_details = **str; return true; } bool IsFinalOp() { @@ -332,9 +358,6 @@ class SendServerStatusOp : public Op { std::string GetTypeString() const { return "send_status"; } - - private: - grpc_slice details; }; class GetMetadataOp : public Op { @@ -352,7 +375,8 @@ class GetMetadataOp : public Op { return scope.Escape(ParseMetadata(&recv_metadata)); } - bool ParseOp(Local value, grpc_op *out) { + bool ParseOp(Local value, grpc_op *out, + shared_ptr resources) { out->data.recv_initial_metadata = &recv_metadata; return true; } @@ -384,7 +408,8 @@ class ReadMessageOp : public Op { return scope.Escape(ByteBufferToBuffer(recv_message)); } - bool ParseOp(Local value, grpc_op *out) { + bool ParseOp(Local value, grpc_op *out, + shared_ptr resources) { out->data.recv_message = &recv_message; return true; } @@ -405,16 +430,21 @@ class ClientStatusOp : public Op { public: ClientStatusOp() { grpc_metadata_array_init(&metadata_array); + status_details = NULL; + details_capacity = 0; } ~ClientStatusOp() { grpc_metadata_array_destroy(&metadata_array); + gpr_free(status_details); } - bool ParseOp(Local value, grpc_op *out) { + bool ParseOp(Local value, grpc_op *out, + shared_ptr resources) { out->data.recv_status_on_client.trailing_metadata = &metadata_array; out->data.recv_status_on_client.status = &status; out->data.recv_status_on_client.status_details = &status_details; + out->data.recv_status_on_client.status_details_capacity = &details_capacity; return true; } @@ -423,8 +453,10 @@ class ClientStatusOp : public Op { Local status_obj = Nan::New(); Nan::Set(status_obj, Nan::New("code").ToLocalChecked(), Nan::New(status)); - Nan::Set(status_obj, Nan::New("details").ToLocalChecked(), - CopyStringFromSlice(status_details)); + if (status_details != NULL) { + Nan::Set(status_obj, Nan::New("details").ToLocalChecked(), + Nan::New(status_details).ToLocalChecked()); + } Nan::Set(status_obj, Nan::New("metadata").ToLocalChecked(), ParseMetadata(&metadata_array)); return scope.Escape(status_obj); @@ -439,7 +471,8 @@ class ClientStatusOp : public Op { private: grpc_metadata_array metadata_array; grpc_status_code status; - grpc_slice status_details; + char *status_details; + size_t details_capacity; }; class ServerCloseResponseOp : public Op { @@ -449,7 +482,8 @@ class ServerCloseResponseOp : public Op { return scope.Escape(Nan::New(cancelled)); } - bool ParseOp(Local value, grpc_op *out) { + bool ParseOp(Local value, grpc_op *out, + shared_ptr resources) { out->data.recv_close_on_server.cancelled = &cancelled; return true; } @@ -466,8 +500,9 @@ class ServerCloseResponseOp : public Op { int cancelled; }; -tag::tag(Callback *callback, OpVec *ops, Call *call) : - callback(callback), ops(ops), call(call){ +tag::tag(Callback *callback, OpVec *ops, + shared_ptr resources, Call *call) : + callback(callback), ops(ops), resources(resources), call(call){ } tag::~tag() { @@ -615,24 +650,20 @@ NAN_METHOD(Call::New) { if (channel->GetWrappedChannel() == NULL) { return Nan::ThrowError("Call cannot be created from a closed channel"); } + Utf8String method(info[1]); double deadline = Nan::To(info[2]).FromJust(); grpc_channel *wrapped_channel = channel->GetWrappedChannel(); grpc_call *wrapped_call; if (info[3]->IsString()) { - grpc_slice *host = new grpc_slice; - *host = CreateSliceFromString( - Nan::To(info[3]).ToLocalChecked()); + Utf8String host_override(info[3]); wrapped_call = grpc_channel_create_call( wrapped_channel, parent_call, propagate_flags, - GetCompletionQueue(), CreateSliceFromString( - Nan::To(info[1]).ToLocalChecked()), - host, MillisecondsToTimespec(deadline), NULL); - delete host; + GetCompletionQueue(), *method, + *host_override, MillisecondsToTimespec(deadline), NULL); } else if (info[3]->IsUndefined() || info[3]->IsNull()) { wrapped_call = grpc_channel_create_call( wrapped_channel, parent_call, propagate_flags, - GetCompletionQueue(), CreateSliceFromString( - Nan::To(info[1]).ToLocalChecked()), + GetCompletionQueue(), *method, NULL, MillisecondsToTimespec(deadline), NULL); } else { return Nan::ThrowTypeError("Call's fourth argument must be a string"); @@ -669,6 +700,7 @@ NAN_METHOD(Call::StartBatch) { } Local callback_func = info[1].As(); Call *call = ObjectWrap::Unwrap(info.This()); + shared_ptr resources(new Resources); Local obj = Nan::To(info[0]).ToLocalChecked(); Local keys = Nan::GetOwnPropertyNames(obj).ToLocalChecked(); size_t nops = keys->Length(); @@ -713,7 +745,7 @@ NAN_METHOD(Call::StartBatch) { default: return Nan::ThrowError("Argument object had an unrecognized key"); } - if (!op->ParseOp(obj->Get(type), &ops[i])) { + if (!op->ParseOp(obj->Get(type), &ops[i], resources)) { return Nan::ThrowTypeError("Incorrectly typed arguments to startBatch"); } op_vector->push_back(std::move(op)); @@ -721,7 +753,7 @@ NAN_METHOD(Call::StartBatch) { Callback *callback = new Callback(callback_func); grpc_call_error error = grpc_call_start_batch( call->wrapped_call, &ops[0], nops, new struct tag( - callback, op_vector.release(), call), NULL); + callback, op_vector.release(), resources, call), NULL); if (error != GRPC_CALL_OK) { return Nan::ThrowError(nanErrorWithCode("startBatch failed", error)); } diff --git a/ext/call.h b/ext/call.h index cffff00f..31c6566d 100644 --- a/ext/call.h +++ b/ext/call.h @@ -51,12 +51,20 @@ namespace node { using std::unique_ptr; using std::shared_ptr; +typedef Nan::Persistent> PersistentValue; + v8::Local nanErrorWithCode(const char *msg, grpc_call_error code); v8::Local ParseMetadata(const grpc_metadata_array *metadata_array); +struct Resources { + std::vector > strings; + std::vector > handles; +}; + bool CreateMetadataArray(v8::Local metadata, - grpc_metadata_array *array); + grpc_metadata_array *array, + shared_ptr resources); /* Wrapper class for grpc_call structs. */ class Call : public Nan::ObjectWrap { @@ -98,7 +106,8 @@ class Call : public Nan::ObjectWrap { class Op { public: virtual v8::Local GetNodeValue() const = 0; - virtual bool ParseOp(v8::Local value, grpc_op *out) = 0; + virtual bool ParseOp(v8::Local value, grpc_op *out, + shared_ptr resources) = 0; virtual ~Op(); v8::Local GetOpType() const; virtual bool IsFinalOp() = 0; @@ -109,10 +118,12 @@ class Op { typedef std::vector> OpVec; struct tag { - tag(Nan::Callback *callback, OpVec *ops, Call *call); + tag(Nan::Callback *callback, OpVec *ops, + shared_ptr resources, Call *call); ~tag(); Nan::Callback *callback; OpVec *ops; + shared_ptr resources; Call *call; }; diff --git a/ext/call_credentials.cc b/ext/call_credentials.cc index afcc3631..41f6c29f 100644 --- a/ext/call_credentials.cc +++ b/ext/call_credentials.cc @@ -206,6 +206,7 @@ NAN_METHOD(PluginCallback) { return Nan::ThrowTypeError( "The callback's fourth argument must be an object"); } + shared_ptr resources(new Resources); grpc_status_code code = static_cast( Nan::To(info[0]).FromJust()); Utf8String details_utf8_str(info[1]); @@ -213,7 +214,7 @@ NAN_METHOD(PluginCallback) { grpc_metadata_array array; Local callback_data = Nan::To(info[3]).ToLocalChecked(); if (!CreateMetadataArray(Nan::To(info[2]).ToLocalChecked(), - &array)){ + &array, resources)){ return Nan::ThrowError("Failed to parse metadata"); } grpc_credentials_plugin_metadata_cb cb = diff --git a/ext/channel.cc b/ext/channel.cc index c795ff7f..5bc58b9b 100644 --- a/ext/channel.cc +++ b/ext/channel.cc @@ -280,7 +280,8 @@ NAN_METHOD(Channel::WatchConnectivityState) { channel->wrapped_channel, last_state, MillisecondsToTimespec(deadline), GetCompletionQueue(), new struct tag(callback, - ops.release(), NULL)); + ops.release(), + shared_ptr(nullptr), NULL)); CompletionQueueNext(); } diff --git a/ext/node_grpc.cc b/ext/node_grpc.cc index 95e273f8..614f2e94 100644 --- a/ext/node_grpc.cc +++ b/ext/node_grpc.cc @@ -56,12 +56,9 @@ extern "C" { #include "server.h" #include "completion_queue_async_worker.h" #include "server_credentials.h" -#include "slice.h" #include "timeval.h" #include "completion_queue.h" -using grpc::node::CreateSliceFromString; - using v8::FunctionTemplate; using v8::Local; using v8::Value; @@ -286,8 +283,10 @@ NAN_METHOD(MetadataKeyIsLegal) { "headerKeyIsLegal's argument must be a string"); } Local key = Nan::To(info[0]).ToLocalChecked(); + Nan::Utf8String key_utf8_str(key); + char *key_str = *key_utf8_str; info.GetReturnValue().Set(static_cast( - grpc_header_key_is_legal(CreateSliceFromString(key)))); + grpc_header_key_is_legal(key_str, static_cast(key->Length())))); } NAN_METHOD(MetadataNonbinValueIsLegal) { @@ -296,8 +295,11 @@ NAN_METHOD(MetadataNonbinValueIsLegal) { "metadataNonbinValueIsLegal's argument must be a string"); } Local value = Nan::To(info[0]).ToLocalChecked(); + Nan::Utf8String value_utf8_str(value); + char *value_str = *value_utf8_str; info.GetReturnValue().Set(static_cast( - grpc_header_nonbin_value_is_legal(CreateSliceFromString(value)))); + grpc_header_nonbin_value_is_legal( + value_str, static_cast(value->Length())))); } NAN_METHOD(MetadataKeyIsBinary) { @@ -306,8 +308,10 @@ NAN_METHOD(MetadataKeyIsBinary) { "metadataKeyIsLegal's argument must be a string"); } Local key = Nan::To(info[0]).ToLocalChecked(); + Nan::Utf8String key_utf8_str(key); + char *key_str = *key_utf8_str; info.GetReturnValue().Set(static_cast( - grpc_is_binary_header(CreateSliceFromString(key)))); + grpc_is_binary_header(key_str, static_cast(key->Length())))); } static grpc_ssl_roots_override_result get_ssl_roots_override( diff --git a/ext/server.cc b/ext/server.cc index 4761b286..70d5b96f 100644 --- a/ext/server.cc +++ b/ext/server.cc @@ -46,7 +46,6 @@ #include "grpc/grpc_security.h" #include "grpc/support/log.h" #include "server_credentials.h" -#include "slice.h" #include "timeval.h" namespace grpc { @@ -100,11 +99,10 @@ class NewCallOp : public Op { } Local obj = Nan::New(); Nan::Set(obj, Nan::New("call").ToLocalChecked(), Call::WrapStruct(call)); - // TODO(murgatroid99): Use zero-copy string construction instead Nan::Set(obj, Nan::New("method").ToLocalChecked(), - CopyStringFromSlice(details.method)); + Nan::New(details.method).ToLocalChecked()); Nan::Set(obj, Nan::New("host").ToLocalChecked(), - CopyStringFromSlice(details.host)); + Nan::New(details.host).ToLocalChecked()); Nan::Set(obj, Nan::New("deadline").ToLocalChecked(), Nan::New(TimespecToMilliseconds(details.deadline)) .ToLocalChecked()); @@ -113,7 +111,8 @@ class NewCallOp : public Op { return scope.Escape(obj); } - bool ParseOp(Local value, grpc_op *out) { + bool ParseOp(Local value, grpc_op *out, + shared_ptr resources) { return true; } bool IsFinalOp() { @@ -140,7 +139,8 @@ class ServerShutdownOp : public Op { return Nan::New(reinterpret_cast(server)); } - bool ParseOp(Local value, grpc_op *out) { + bool ParseOp(Local value, grpc_op *out, + shared_ptr resources) { return true; } bool IsFinalOp() { @@ -207,7 +207,8 @@ void Server::ShutdownServer() { grpc_server_shutdown_and_notify( this->wrapped_server, GetCompletionQueue(), - new struct tag(new Callback(**shutdown_callback), ops.release(), NULL)); + new struct tag(new Callback(**shutdown_callback), ops.release(), + shared_ptr(nullptr), NULL)); grpc_server_cancel_all_calls(this->wrapped_server); CompletionQueueNext(); this->wrapped_server = NULL; @@ -260,7 +261,7 @@ NAN_METHOD(Server::RequestCall) { GetCompletionQueue(), GetCompletionQueue(), new struct tag(new Callback(info[0].As()), ops.release(), - NULL)); + shared_ptr(nullptr), NULL)); if (error != GRPC_CALL_OK) { return Nan::ThrowError(nanErrorWithCode("requestCall failed", error)); } @@ -313,7 +314,7 @@ NAN_METHOD(Server::TryShutdown) { grpc_server_shutdown_and_notify( server->wrapped_server, GetCompletionQueue(), new struct tag(new Nan::Callback(info[0].As()), ops.release(), - NULL)); + shared_ptr(nullptr), NULL)); CompletionQueueNext(); } diff --git a/ext/slice.cc b/ext/slice.cc deleted file mode 100644 index 98a80b3d..00000000 --- a/ext/slice.cc +++ /dev/null @@ -1,102 +0,0 @@ -/* - * - * Copyright 2016, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include -#include -#include -#include - -#include "slice.h" -#include "byte_buffer.h" - -namespace grpc { -namespace node { - -using Nan::Persistent; - -using v8::Local; -using v8::String; -using v8::Value; - -namespace { -void SliceFreeCallback(char *data, void *hint) { - grpc_slice *slice = reinterpret_cast(hint); - grpc_slice_unref(*slice); - delete slice; -} - -void string_destroy_func(void *user_data) { - delete reinterpret_cast(user_data); -} - -void buffer_destroy_func(void *user_data) { - delete reinterpret_cast(user_data); -} -} // namespace - -grpc_slice CreateSliceFromString(const Local source) { - Nan::HandleScope scope; - Nan::Utf8String *utf8_value = new Nan::Utf8String(source); - return grpc_slice_new_with_user_data(**utf8_value, source->Length(), - string_destroy_func, utf8_value); -} - -grpc_slice CreateSliceFromBuffer(const Local source) { - // Prerequisite: ::node::Buffer::HasInstance(source) - Nan::HandleScope scope; - return grpc_slice_new_with_user_data(::node::Buffer::Data(source), - ::node::Buffer::Length(source), - buffer_destroy_func, - new PersistentValue(source)); -} -Local CopyStringFromSlice(const grpc_slice slice) { - Nan::EscapableHandleScope scope; - if (GRPC_SLICE_LENGTH(slice) == 0) { - return scope.Escape(Nan::EmptyString()); - } - return scope.Escape(Nan::New( - const_cast(reinterpret_cast(GRPC_SLICE_START_PTR(slice))), - GRPC_SLICE_LENGTH(slice)).ToLocalChecked()); -} - -Local CreateBufferFromSlice(const grpc_slice slice) { - Nan::EscapableHandleScope scope; - grpc_slice *slice_ptr = new grpc_slice; - *slice_ptr = grpc_slice_ref(slice); - return scope.Escape(MakeFastBuffer(Nan::NewBuffer( - const_cast(reinterpret_cast(GRPC_SLICE_START_PTR(*slice_ptr))), - GRPC_SLICE_LENGTH(*slice_ptr), SliceFreeCallback, slice_ptr).ToLocalChecked())); -} - -} // namespace node -} // namespace grpc diff --git a/ext/slice.h b/ext/slice.h deleted file mode 100644 index 7dcb1bd4..00000000 --- a/ext/slice.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * Copyright 2016, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include -#include -#include - -namespace grpc { -namespace node { - -typedef Nan::Persistent> PersistentValue; - -grpc_slice CreateSliceFromString(const v8::Local source); - -grpc_slice CreateSliceFromBuffer(const v8::Local source); - -v8::Local CopyStringFromSlice(const grpc_slice slice); - -v8::Local CreateBufferFromSlice(const grpc_slice slice); - -} // namespace node -} // namespace grpc