From 399f22901dadecc8132aa86cc638c7a379bc61b2 Mon Sep 17 00:00:00 2001 From: Anton Antonov Date: Wed, 20 Apr 2016 02:05:32 +0300 Subject: [PATCH] Add Nodejs 4/5 support --- README.md | 10 +- addon.cc | 3 +- package.json | 4 +- protobuf_for_node.cc | 249 +++++++++++++++++++++---------------------- 4 files changed, 131 insertions(+), 135 deletions(-) diff --git a/README.md b/README.md index a8ccdc9..defedc5 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ -Node v0.11.13 Now Supported +Node v4.x.x/5.x.x Now Supported --------------------------- Many thanks to [Mário Freitas/imkira](https://github.com/imkira) for his work. +Currently maintained by [Anton Antonov/syndbg](https://github.com/syndbg). Protobuf @@ -9,7 +10,12 @@ Protobuf This is a fork of http://code.google.com/p/protobuf-for-node/ -It now works with the NodeJS 0.8.x and 0.10.x series. +Works/worked with NodeJS versions: + +* 0.8.x, +* 0.10.x, +* 4.x.x, +* 5.x.x To install, just type: diff --git a/addon.cc b/addon.cc index 0943ed5..026042f 100644 --- a/addon.cc +++ b/addon.cc @@ -3,8 +3,7 @@ #include "protobuf_for_node.h" void init(v8::Handle target) { - target->Set(NanNew("Schema"), protobuf_for_node::SchemaConstructor()); + target->Set(Nan::New("Schema").ToLocalChecked(), protobuf_for_node::SchemaConstructor()); } NODE_MODULE(protobuf_for_node, init) - diff --git a/package.json b/package.json index 1322ffc..de501e8 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ }, "main": "./build/Release/protobuf_for_node", "engines": { - "node": ">= 0.8.0 < 0.12" + "node": ">= 0.8.0" }, "repository": { "type": "git", @@ -17,6 +17,6 @@ "test": "node test/unittest.js" }, "dependencies": { - "nan": "~1.0.0" + "nan": "~2.1.0" } } diff --git a/protobuf_for_node.cc b/protobuf_for_node.cc index a39673c..dccab0d 100644 --- a/protobuf_for_node.cc +++ b/protobuf_for_node.cc @@ -39,7 +39,7 @@ using google::protobuf::Reflection; using google::protobuf::Service; using google::protobuf::ServiceDescriptor; -using node::ObjectWrap; +using Nan::ObjectWrap; using std::map; using std::string; @@ -69,20 +69,20 @@ namespace protobuf_for_node { const char E_NO_OBJECT[] = "Not an object"; const char E_UNKNOWN_ENUM[] = "Unknown enum value"; - Persistent SchemaTemplate; - Persistent ServiceSchemaTemplate; - Persistent ServiceTemplate; - Persistent MethodTemplate; - Persistent TypeTemplate; - Persistent ParseTemplate; - Persistent SerializeTemplate; + Nan::Persistent SchemaTemplate; + Nan::Persistent ServiceSchemaTemplate; + Nan::Persistent ServiceTemplate; + Nan::Persistent MethodTemplate; + Nan::Persistent TypeTemplate; + Nan::Persistent ParseTemplate; + Nan::Persistent SerializeTemplate; - class Schema : public ObjectWrap { + class Schema : public Nan::ObjectWrap { public: - Schema(Handle self, const DescriptorPool* pool) + Schema(Local self, const DescriptorPool* pool) : pool_(pool) { factory_.SetDelegateToGeneratedFactory(true); - self->SetInternalField(1, NanNew()); + self->SetInternalField(1, Nan::New()); Wrap(self); } @@ -91,7 +91,7 @@ namespace protobuf_for_node { delete pool_; } - class Type : public ObjectWrap { + class Type : public Nan::ObjectWrap { public: Schema* schema_; const Descriptor* descriptor_; @@ -100,16 +100,16 @@ namespace protobuf_for_node { return schema_->NewMessage(descriptor_); } - Handle Constructor() const { - Local handle = NanObjectWrapHandle(const_cast(this)); + Local Constructor() const { + Local handle = const_cast(this)->handle(); return handle->GetInternalField(2).As(); } - Local NewObject(Handle properties) const { + Local NewObject(Local properties) const { return Constructor()->NewInstance(1, &properties); } - Type(Schema* schema, const Descriptor* descriptor, Handle self) + Type(Schema* schema, const Descriptor* descriptor, Local self) : schema_(schema), descriptor_(descriptor) { // Generate functions for bulk conversion between a JS object // and an array in descriptor order: @@ -135,29 +135,29 @@ namespace protobuf_for_node { to << " ]; })"; // managed type->schema link - self->SetInternalField(1, NanObjectWrapHandle(schema_)); + self->SetInternalField(1, schema_->handle()); - Handle constructor = - Script::Compile(NanNew(from.str().c_str()))->Run().As(); - constructor->SetHiddenValue(NanNew("type"), self); + Local constructor = + Script::Compile(Nan::New(from.str()).ToLocalChecked())->Run().As(); + constructor->SetHiddenValue(Nan::New("type").ToLocalChecked(), self); - Handle bind = - Script::Compile(NanNew( + Local bind = + Script::Compile(Nan::New( "(function(self) {" " var f = this;" " return function(arg) {" " return f.call(self, arg);" " };" - "})"))->Run().As(); - Handle arg = self; + "})").ToLocalChecked())->Run().As(); + Local arg = self; - Local parseTemplate = NanNew(ParseTemplate); - Local serializeTemplate = NanNew(SerializeTemplate); + Local parseTemplate = Nan::New(ParseTemplate); + Local serializeTemplate = Nan::New(SerializeTemplate); - constructor->Set(NanNew("parse"), bind->Call(parseTemplate->GetFunction(), 1, &arg)); - constructor->Set(NanNew("serialize"), bind->Call(serializeTemplate->GetFunction(), 1, &arg)); + constructor->Set(Nan::New("parse").ToLocalChecked(), bind->Call(parseTemplate->GetFunction(), 1, &arg)); + constructor->Set(Nan::New("serialize").ToLocalChecked(), bind->Call(serializeTemplate->GetFunction(), 1, &arg)); self->SetInternalField(2, constructor); - self->SetInternalField(3, Script::Compile(NanNew(to.str().c_str()))->Run()); + self->SetInternalField(3, Script::Compile(Nan::New(to.str()).ToLocalChecked())->Run()); Wrap(self); } @@ -167,7 +167,7 @@ namespace protobuf_for_node { reflection->GetRepeated##TYPE(instance, field, index) : \ reflection->Get##TYPE(instance, field)) - static Handle ToJs(const Message& instance, + static Local ToJs(const Message& instance, const Reflection* reflection, const FieldDescriptor* field, const Type* message_type, @@ -178,52 +178,51 @@ namespace protobuf_for_node { case FieldDescriptor::CPPTYPE_STRING: { const string& value = GET(String); if (field->type() == FieldDescriptor::TYPE_BYTES) { - return NanNewBufferHandle(const_cast(value.data()), - value.length()); + return Nan::CopyBuffer(const_cast(value.data()), value.length()).ToLocalChecked(); } else { - return NanNew(value.data(), value.length()); + return Nan::New(value.data(), value.length()).ToLocalChecked(); } } case FieldDescriptor::CPPTYPE_INT32: - return NanNew(GET(Int32)); + return Nan::New(GET(Int32)); case FieldDescriptor::CPPTYPE_UINT32: - return NanNew(GET(UInt32)); + return Nan::New(GET(UInt32)); case FieldDescriptor::CPPTYPE_INT64: { std::ostringstream ss; ss << GET(Int64); string s = ss.str(); - return NanNew(s.data(), s.length()); + return Nan::New(s.data(), s.length()).ToLocalChecked(); } case FieldDescriptor::CPPTYPE_UINT64: { std::ostringstream ss; ss << GET(UInt64); string s = ss.str(); - return NanNew(s.data(), s.length()); + return Nan::New(s.data(), s.length()).ToLocalChecked(); } case FieldDescriptor::CPPTYPE_FLOAT: - return NanNew(GET(Float)); + return Nan::New(GET(Float)); case FieldDescriptor::CPPTYPE_DOUBLE: - return NanNew(GET(Double)); + return Nan::New(GET(Double)); case FieldDescriptor::CPPTYPE_BOOL: if (GET(Bool)) { - return NanTrue(); + return Nan::True(); } - return NanFalse(); + return Nan::False(); case FieldDescriptor::CPPTYPE_ENUM: - return NanNew(GET(Enum)->name().c_str()); + return Nan::New(GET(Enum)->name().c_str()).ToLocalChecked(); } - return NanUndefined(); // NOTREACHED + return Nan::Undefined(); // NOTREACHED } #undef GET - Handle ToJs(const Message& instance) const { + Local ToJs(const Message& instance) const { const Reflection* reflection = instance.GetReflection(); const Descriptor* descriptor = instance.GetDescriptor(); - Handle properties = NanNew(descriptor->field_count()); + Local properties = Nan::New(descriptor->field_count()); for (int i = 0; i < descriptor->field_count(); i++) { - NanScope(); + Nan::HandleScope scope; const FieldDescriptor* field = descriptor->field(i); bool repeated = field->is_repeated(); @@ -234,10 +233,10 @@ namespace protobuf_for_node { (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) ? schema_->GetType(field->message_type()) : NULL; - Handle value; + Local value; if (field->is_repeated()) { int size = reflection->FieldSize(instance, field); - Handle array = NanNew(size); + Local array = Nan::New(size); for (int j = 0; j < size; j++) { array->Set(j, ToJs(instance, reflection, field, child_type, j)); } @@ -253,26 +252,24 @@ namespace protobuf_for_node { } static NAN_METHOD(Parse) { - NanScope(); - - if ((args.Length() < 1) || (!node::Buffer::HasInstance(args[0]))) { - return NanThrowTypeError("Argument should be a buffer"); + if ((info.Length() < 1) || (!node::Buffer::HasInstance(info[0]))) { + return Nan::ThrowTypeError("Argument should be a buffer"); } - Local buffer_obj = args[0]->ToObject(); + Local buffer_obj = info[0]->ToObject(); - Type *type = Unwrap(args.This()); + Type *type = Unwrap(info.This()); Message* message = type->NewMessage(); bool success = message->ParseFromArray(node::Buffer::Data(buffer_obj), node::Buffer::Length(buffer_obj)); if (!success) { - return NanThrowError("Malformed message"); + return Nan::ThrowError("Malformed message"); } - Handle result = Handle(type->ToJs(*message)); + Local result = type->ToJs(*message); delete message; - NanReturnValue(result); + info.GetReturnValue().Set(result); } #define SET(TYPE, EXPR) \ @@ -281,10 +278,10 @@ namespace protobuf_for_node { static const char* ToProto(Message* instance, const FieldDescriptor* field, - Handle value, + Local value, const Type* type, bool repeated) { - NanScope(); + Nan::HandleScope scope; const Reflection* reflection = instance->GetReflection(); switch (field->cpp_type()) { @@ -357,14 +354,14 @@ namespace protobuf_for_node { } #undef SET - const char* ToProto(Message* instance, Handle src) const { - Local handle = NanObjectWrapHandle(const_cast(this)); - Handle to_array = handle->GetInternalField(3).As(); - Handle properties = to_array->Call(src, 0, NULL).As(); + const char* ToProto(Message* instance, Local src) const { + Local handle = const_cast(this)->handle(); + Local to_array = handle->GetInternalField(3).As(); + Local properties = to_array->Call(src, 0, NULL).As(); const char* error = NULL; for (int i = 0; !error && i < descriptor_->field_count(); i++) { - Handle value = properties->Get(i); + Local value = properties->Get(i); if (value->IsUndefined() || value->IsNull()) continue; @@ -378,7 +375,7 @@ namespace protobuf_for_node { continue; } - Handle array = value.As(); + Local array = value.As(); int length = array->Length(); for (int j = 0; !error && j < length; j++) { @@ -392,35 +389,31 @@ namespace protobuf_for_node { } static NAN_METHOD(Serialize) { - NanScope(); - - if ((args.Length() < 1) || (!args[0]->IsObject())) { - return NanThrowTypeError("Not an object"); + if ((info.Length() < 1) || (!info[0]->IsObject())) { + return Nan::ThrowTypeError("Not an object"); } - Type *type = Unwrap(args.This()); + Type *type = Unwrap(info.This()); Message* message = type->NewMessage(); - const char* error = type->ToProto(message, args[0].As()); + const char* error = type->ToProto(message, info[0].As()); Local result; if (!error) { - result = NanNewBufferHandle(message->ByteSize()); + result = Nan::NewBuffer(message->ByteSize()).ToLocalChecked(); message->SerializeWithCachedSizesToArray( (google::protobuf::uint8*)node::Buffer::Data(result)); } delete message; if (error) { - return NanThrowError(error); + return Nan::ThrowError(error); } - NanReturnValue(result); + info.GetReturnValue().Set(result); } static NAN_METHOD(ToString) { - NanScope(); - - Type *type = Unwrap(args.This()); - NanReturnValue(NanNew(type->descriptor_->full_name().c_str())); + Type *type = Unwrap(info.This()); + info.GetReturnValue().Set(Nan::New(type->descriptor_->full_name()).ToLocalChecked()); } }; @@ -432,15 +425,15 @@ namespace protobuf_for_node { Type* result = types_[descriptor]; if (result) return result; - Local typeTemplate = NanNew(TypeTemplate); + Local typeTemplate = Nan::New(TypeTemplate); result = types_[descriptor] = new Type(this, descriptor, typeTemplate->GetFunction()->NewInstance()); // managed schema->[type] link // - Local handle = NanObjectWrapHandle(const_cast(this)); - Handle types = handle->GetInternalField(1).As(); - types->Set(types->Length(), NanObjectWrapHandle(result)); + Local handle = const_cast(this)->handle(); + Local types = handle->GetInternalField(1).As(); + types->Set(types->Length(), result->handle()); return result; } @@ -449,40 +442,38 @@ namespace protobuf_for_node { DynamicMessageFactory factory_; static NAN_PROPERTY_GETTER(GetType) { - NanScope(); - - Schema *schema = Unwrap(args.This()); + Schema *schema = Unwrap(info.This()); const Descriptor* descriptor = schema->pool_->FindMessageTypeByName(*String::Utf8Value(property)); if (descriptor != NULL) { - NanReturnValue(schema->GetType(descriptor)->Constructor()); + info.GetReturnValue().Set(schema->GetType(descriptor)->Constructor()); + return; } - NanReturnValue(Handle()); + info.GetReturnValue().SetUndefined(); } static NAN_METHOD(NewSchema) { - NanScope(); - Schema *schema; - if (args.Length() < 1) { - schema = new Schema(args.This(), DescriptorPool::generated_pool()); - NanReturnValue(NanObjectWrapHandle(schema)); + if (info.Length() < 1) { + schema = new Schema(info.This(), DescriptorPool::generated_pool()); + info.GetReturnValue().Set(schema->handle()); + return; } - if (!node::Buffer::HasInstance(args[0])) { - return NanThrowTypeError("Argument should be a buffer"); + if (!node::Buffer::HasInstance(info[0])) { + return Nan::ThrowTypeError("Argument should be a buffer"); } - Local buffer_obj = args[0]->ToObject(); + Local buffer_obj = info[0]->ToObject(); char *buffer_data = node::Buffer::Data(buffer_obj); size_t buffer_length = node::Buffer::Length(buffer_obj); FileDescriptorSet descriptors; if (!descriptors.ParseFromArray(buffer_data, buffer_length)) { - return NanThrowError("Malformed descriptor"); + return Nan::ThrowError("Malformed descriptor"); } DescriptorPool* pool = new DescriptorPool; @@ -490,29 +481,29 @@ namespace protobuf_for_node { pool->BuildFile(descriptors.file(i)); } - schema = new Schema(args.This(), pool); - NanReturnValue(NanObjectWrapHandle(schema)); + schema = new Schema(info.This(), pool); + info.GetReturnValue().Set(schema->handle()); } }; // services /* - class WrappedService : public ObjectWrap { + class WrappedService : public Nan::ObjectWrap { public: static Handle Invoke(const Arguments& args) { WrappedService* self = UnwrapThis(args); - MethodDescriptor* method = static_cast(External::Unwrap(args[0])); - Schema* schema = ObjectWrap::Unwrap(self->handle_->GetInternalField(1).As()); + MethodDescriptor* method = static_cast(External::Unwrap(info[0])); + Schema* schema = Nan::ObjectWrap::Unwrap(self->handle_->GetInternalField(1).As()); Schema::Type* input_type = schema->GetType(method->input_type()); Schema::Type* output_type = schema->GetType(method->output_type()); Message* request = self->service_->GetRequestPrototype(method).New(); Message* response = self->service_->GetResponsePrototype(method).New(); - input_type->ToProto(request, args[1].As()); + input_type->ToProto(request, info[1].As()); - if (args.Length() > 2) { - AsyncInvocation::Start(self, method, request, response, output_type, args[2].As()); + if (info.Length() > 2) { + AsyncInvocation::Start(self, method, request, response, output_type, info[2].As()); return v8::Undefined(); } else { bool done = false; @@ -542,7 +533,7 @@ namespace protobuf_for_node { handle_->SetInternalField(1, schema->handle_); Handle bind = - Script::Compile(NanNew( + Script::Compile(Nan::New( "(function(m) {" " var f = this;" " return function(arg1, arg2) {" @@ -552,7 +543,7 @@ namespace protobuf_for_node { for (int i = 0; i < descriptor->method_count(); i++) { const MethodDescriptor* method = descriptor->method(i); Handle arg = External::Wrap(const_cast(method)); - handle_->Set(NanNew(method->name().c_str()), + handle_->Set(Nan::New(method->name().c_str()), bind->Call(MethodTemplate->GetFunction(), 1, &arg)); } } @@ -664,11 +655,11 @@ namespace protobuf_for_node { // all outstanding callbacks delivered if (!head) { uv_close((uv_handle_t*) &ev_done, NULL); - } + } } static void InvokeCallback(AsyncInvocation* self) { - NanScope(); + Nan::HandleScope scope; Handle result = self->response_type_->ToJs(*(self->response_)); self->cb_->Call(Context::GetCurrent()->Global(), 1, &result); delete self; @@ -695,56 +686,56 @@ namespace protobuf_for_node { Local t; - t = NanNew(); - t->SetClassName(NanNew("Type")); + t = Nan::New(); + t->SetClassName(Nan::New("Type").ToLocalChecked()); // native self // owning schema (so GC can manage our lifecyle) // constructor // toArray t->InstanceTemplate()->SetInternalFieldCount(4); - NanAssignPersistent(TypeTemplate, t); + TypeTemplate.Reset(t); - t = NanNew(Schema::NewSchema); - t->SetClassName(NanNew("Schema")); + t = Nan::New(Schema::NewSchema); + t->SetClassName(Nan::New("Schema").ToLocalChecked()); // native self // array of types (so GC can manage our lifecyle) t->InstanceTemplate()->SetInternalFieldCount(2); - t->InstanceTemplate()->SetNamedPropertyHandler(Schema::GetType); - NanAssignPersistent(SchemaTemplate, t); + Nan::SetNamedPropertyHandler(t->InstanceTemplate(), Schema::GetType); + SchemaTemplate.Reset(t); - t = NanNew(); - t->SetClassName(NanNew("Schema")); + t = Nan::New(); + t->SetClassName(Nan::New("Schema").ToLocalChecked()); // native self // array of types (so GC can manage our lifecyle) t->InstanceTemplate()->SetInternalFieldCount(2); - t->InstanceTemplate()->SetNamedPropertyHandler(Schema::GetType); - NanAssignPersistent(ServiceSchemaTemplate, t); + Nan::SetNamedPropertyHandler(t->InstanceTemplate(), Schema::GetType); + ServiceSchemaTemplate.Reset(t); - t = NanNew(); - t->SetClassName(NanNew("Service")); + t = Nan::New(); + t->SetClassName(Nan::New("Service").ToLocalChecked()); t->InstanceTemplate()->SetInternalFieldCount(2); - NanAssignPersistent(ServiceTemplate, t); + ServiceTemplate.Reset(t); //MethodTemplate = Persistent::New(FunctionTemplate::New(WrappedService::Invoke)); - t = NanNew(Schema::Type::Parse); - NanAssignPersistent(ParseTemplate, t); + t = Nan::New(Schema::Type::Parse); + ParseTemplate.Reset(t); - t = NanNew(Schema::Type::Serialize); - NanAssignPersistent(SerializeTemplate, t); + t = Nan::New(Schema::Type::Serialize); + SerializeTemplate.Reset(t); //WrappedService::Init(); } Local SchemaConstructor() { Init(); - Local schemaTemplate = NanNew(SchemaTemplate); + Local schemaTemplate = Nan::New(SchemaTemplate); return schemaTemplate->GetFunction(); } - void ExportService(Handle target, const char* name, Service* service) { + void ExportService(Local target, const char* name, Service* service) { Init(); - //target->Set(NanNew(name), (new WrappedService(service))->handle_); + //target->Set(Nan::New(name), (new WrappedService(service))->handle_).ToLocalChecked(); } } // namespace protobuf_for_node