diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2f17d8a --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +build/ +*.node +.lock-wscript diff --git a/README.md b/README.md index d5c817c..82c33ea 100644 --- a/README.md +++ b/README.md @@ -6,30 +6,37 @@ This is fork of [protobuf-for-node](http://code.google.com/p/protobuf-for-node/) Make sure you have installed following libraries: -* libprotobuf-dev (>= 2.3.0) -* libprotobuf-lite6 (>= 2.3.0) -* libprotobuf6 (>= 2.3.0) -* protobuf-compiler (>= 2.3.0) +* libprotobuf-dev (>= 2.4.0a) +* libprotobuf7 (>= 2.4.0a) +* protobuf-compiler (>= 2.4.0a) ## Installation ### 1. Latest node.js -`protobuf-for-node` requires latest version of node (0.5.5). +`protobuf-for-node` requires latest version of node (0.6.1). #### Ubuntu and deb-based distributions Installation of latest node is fairly straightforward, and can be done from precompiled deb packages. -Since in main Ubuntu repository contains only stable version of node, you have to add `chris-lea/node.js-devel` PPA (https://launchpad.net/~chris-lea/+archive/node.js-devel) to `/etc/apt/sources.list`. For example for Ubuntu 11.04: +Since in main Ubuntu repository contains only stable version of node, you have to add `chris-lea/node.js-devel` PPA (https://launchpad.net/~chris-lea/+archive/node.js-devel) to `/etc/apt/sources.list`. For example for Ubuntu 11.10: - deb http://ppa.launchpad.net/chris-lea/node.js-devel/ubuntu natty main - deb-src http://ppa.launchpad.net/chris-lea/node.js-devel/ubuntu natty main + deb http://ppa.launchpad.net/chris-lea/node.js-devel/ubuntu oneiric main + deb-src http://ppa.launchpad.net/chris-lea/node.js-devel/ubuntu oneiric main Now execute following: sudo apt-get update sudo apt-get install nodejs nodejs-dev +Installation of the protobuf tools needed is also quite easy as long as you have Ubuntu 11.10. +Previous versions didn't have a new enough version of protobuf in the repository. + +Just execute: + + sudo apt-get install protobuf-compiler libprotobuf-dev + + #### Other distributions For other distributions, following https://github.com/joyent/node/wiki/Installation is recommended. @@ -68,4 +75,4 @@ Usage examples are described here: http://code.google.com/p/protobuf-for-node/ ## Credits Author: Matthias Ernst -Contributors: Igor Gumenyuk, Dawid Fatyga \ No newline at end of file +Contributors: Igor Gumenyuk, Dawid Fatyga diff --git a/makefile b/makefile index 54faf61..d8ac5c2 100644 --- a/makefile +++ b/makefile @@ -8,3 +8,8 @@ all: build install clean: @rm -rf ./build + +test: + @nodeunit test + +.PHONY: all test diff --git a/protobuf_for_node.cc b/protobuf_for_node.cc index e4dcc3b..68bdc7b 100644 --- a/protobuf_for_node.cc +++ b/protobuf_for_node.cc @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include @@ -54,6 +54,7 @@ using v8::AccessorInfo; using v8::Arguments; using v8::Boolean; using v8::Context; +using v8::Exception; using v8::External; using v8::Function; using v8::FunctionTemplate; @@ -69,6 +70,7 @@ using v8::ObjectTemplate; using v8::Persistent; using v8::Script; using v8::String; +using v8::ThrowException; using v8::Value; using v8::V8; @@ -141,11 +143,11 @@ namespace protobuf_for_node { from << "var x = arr[" << i << "]; " "if(x !== undefined) this['" << - descriptor->field(i)->name() << + descriptor->field(i)->camelcase_name() << "'] = x; "; if (i > 0) to << ", "; - to << "this['" << descriptor->field(i)->name() << "']"; + to << "this['" << descriptor->field(i)->camelcase_name() << "']"; } from << " }})"; @@ -190,7 +192,12 @@ namespace protobuf_for_node { return message_type->ToJs(GET(Message)); case FieldDescriptor::CPPTYPE_STRING: { const string& value = GET(String); - return String::New(value.data(), value.length()); + if (field->type() == FieldDescriptor::TYPE_BYTES) { + return Buffer::New(const_cast(value.data()), + value.length())->handle_; + } else { + return String::New(value.data(), value.length()); + } } case FieldDescriptor::CPPTYPE_INT32: return Integer::New(GET(Int32)); @@ -251,11 +258,15 @@ namespace protobuf_for_node { static Handle Parse(const Arguments& args) { Type* type = UnwrapThis(args); - Local buf = args[0]->ToObject(); + if (!Buffer::HasInstance(args[0])) { + return ThrowException(Exception::TypeError( + String::New("Argument should be a buffer"))); + } + Local buffer_obj = args[0]->ToObject(); Message* message = type->NewMessage(); - bool success = - message->ParseFromArray(Buffer::Data(buf), Buffer::Length(buf)); + bool success = + message->ParseFromArray(Buffer::Data(buffer_obj), Buffer::Length(buffer_obj)); Handle result = success ? Handle(type->ToJs(*message)) : v8::ThrowException( @@ -288,8 +299,14 @@ namespace protobuf_for_node { value.As()); break; case FieldDescriptor::CPPTYPE_STRING: { - String::AsciiValue ascii(value); - SET(String, string(*ascii, ascii.length())); + // Shortcutting Utf8value(buffer.toString()) + if (Buffer::HasInstance(value)) { + Local buf = value->ToObject(); + SET(String, string(Buffer::Data(buf), Buffer::Length(buf))); + } else { + String::Utf8Value utf8(value); + SET(String, string(*utf8, utf8.length())); + } break; } case FieldDescriptor::CPPTYPE_INT32: @@ -427,10 +444,16 @@ namespace protobuf_for_node { DescriptorPool::generated_pool()))->handle_; } - Local buf = args[0]->ToObject(); + if (!Buffer::HasInstance(args[0])) { + return ThrowException(Exception::TypeError( + String::New("Argument should be a buffer"))); + } + Local buffer_obj = args[0]->ToObject(); + char *buffer_data = Buffer::Data(buffer_obj); + size_t buffer_length = Buffer::Length(buffer_obj); FileDescriptorSet descriptors; - if (!descriptors.ParseFromArray(Buffer::Data(buf), Buffer::Length(buf))) { + if (!descriptors.ParseFromArray(buffer_data, buffer_length)) { return v8::ThrowException( v8::Exception::Error(String::New("Malformed descriptor"))); } diff --git a/test/test.desc b/test/test.desc index e2594ab..0bcb582 100644 --- a/test/test.desc +++ b/test/test.desc @@ -1,11 +1,14 @@ -£ +Ç -test.proto node_protobuf"… +test.proto node_protobuf"© TestMessage test ( int32 ( string ( 2 -repeated ( 2 .node_protobuf.TestMessage.Inner +repeated ( 2 .node_protobuf.TestMessage.Inner +buffer (  + +camel_case (  Inner test ( \ No newline at end of file diff --git a/test/test.proto b/test/test.proto index b1f91f1..59b1301 100644 --- a/test/test.proto +++ b/test/test.proto @@ -11,4 +11,8 @@ message TestMessage { } repeated Inner repeated = 4; + + optional bytes buffer = 5; + + optional string camel_case = 6; //will be camelCased } \ No newline at end of file diff --git a/test/test_parsing.js b/test/test_parsing.js index 0d33e7c..1c33aea 100644 --- a/test/test_parsing.js +++ b/test/test_parsing.js @@ -4,10 +4,19 @@ var assert = require('assert'); var fs = require('fs'); // Load schema -var Schema = require('protobuf').Schema; -var TestSchema = new Schema(fs.readFileSync('./test.desc')); +var Schema = require('../protobuf').Schema; +var TestSchema = new Schema(fs.readFileSync('./test/test.desc')); var TestMessage = TestSchema['node_protobuf.TestMessage']; +/* hack to make the tests pass with node v0.3.0's new Buffer model */ +/* copied from http://github.com/bnoordhuis/node-iconv/blob/master/test.js */ +bufferEqual = function(test, a, b) { + test.equal( + a.inspect().replace(/^