Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
build/
*.node
.lock-wscript
25 changes: 16 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Contributors: Igor Gumenyuk, Dawid Fatyga
5 changes: 5 additions & 0 deletions makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,8 @@ all: build install

clean:
@rm -rf ./build

test:
@nodeunit test

.PHONY: all test
45 changes: 34 additions & 11 deletions protobuf_for_node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/service.h>

#include <eio.h>
#include <uv.h>
#include <node_buffer.h>
#include <node_object_wrap.h>

Expand Down Expand Up @@ -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;
Expand All @@ -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;

Expand Down Expand Up @@ -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 << " }})";
Expand Down Expand Up @@ -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<char *>(value.data()),
value.length())->handle_;
} else {
return String::New(value.data(), value.length());
}
}
case FieldDescriptor::CPPTYPE_INT32:
return Integer::New(GET(Int32));
Expand Down Expand Up @@ -251,11 +258,15 @@ namespace protobuf_for_node {

static Handle<Value> Parse(const Arguments& args) {
Type* type = UnwrapThis<Type>(args);
Local<Object> buf = args[0]->ToObject();
if (!Buffer::HasInstance(args[0])) {
return ThrowException(Exception::TypeError(
String::New("Argument should be a buffer")));
}
Local<Object> 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<Value> result = success
? Handle<Value>(type->ToJs(*message))
: v8::ThrowException(
Expand Down Expand Up @@ -288,8 +299,14 @@ namespace protobuf_for_node {
value.As<Object>());
break;
case FieldDescriptor::CPPTYPE_STRING: {
String::AsciiValue ascii(value);
SET(String, string(*ascii, ascii.length()));
// Shortcutting Utf8value(buffer.toString())
if (Buffer::HasInstance(value)) {
Local<Object> 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:
Expand Down Expand Up @@ -427,10 +444,16 @@ namespace protobuf_for_node {
DescriptorPool::generated_pool()))->handle_;
}

Local<Object> buf = args[0]->ToObject();
if (!Buffer::HasInstance(args[0])) {
return ThrowException(Exception::TypeError(
String::New("Argument should be a buffer")));
}
Local<Object> 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")));
}
Expand Down
9 changes: 6 additions & 3 deletions test/test.desc
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@

�
�

test.protonode_protobuf"�
test.protonode_protobuf"�
TestMessage
test (
int32 (
string ( 2
repeated ( 2 .node_protobuf.TestMessage.Inner
repeated ( 2 .node_protobuf.TestMessage.Inner
buffer ( 

camel_case ( 
Inner
test (
Expand Down
4 changes: 4 additions & 0 deletions test/test.proto
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,8 @@ message TestMessage {
}

repeated Inner repeated = 4;

optional bytes buffer = 5;

optional string camel_case = 6; //will be camelCased
}
23 changes: 21 additions & 2 deletions test/test_parsing.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(/^<SlowBuffer/, '<Buffer'),
b.inspect().replace(/^<SlowBuffer/, '<Buffer'));
};


/* Generic roundtrip serialization test */
var shouldSerialize = function(test, message){
// given
Expand Down Expand Up @@ -43,6 +52,16 @@ exports.shouldSerializeDifferentTypes = function(test){
shouldSerialize(test, {string : 'Hello'});
shouldSerialize(test, {int32 : 123});
shouldSerialize(test, {repeated: [{test : 123}]});
shouldSerialize(test, {camelCase: 'Foo'});

test.done();
}

exports.shouldSerializeBytes = function(test){
var message = {buffer: TestMessage.serialize({string:'Hello', int32:0})};
var serialized = TestMessage.serialize(message);
var parsed = TestMessage.parse(serialized);
bufferEqual(test, message.buffer, new Buffer(parsed.buffer, 'binary'));

test.done();
}
8 changes: 7 additions & 1 deletion wscript
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,13 @@ def configure(conf):
if Options.platform == 'darwin':
conf.env.append_value('LINKFLAGS', ['-undefined', 'dynamic_lookup'])
if not conf.env.PROTOBUF_PATH:
Logs.warn("Option --protobuf_path wasn\'t defined. Trying default: %s" % conf.env.DEFAULT_PROTOBUF_PATH)
path = os.path.join('/usr/' 'include', 'google', 'protobuf')
Logs.warn(path)
if os.path.isdir(path):
conf.env.DEFAULT_PROTOBUF_PATH = '/usr'
Logs.warn("Option --protobuf_path wasn\'t defined. Found protobuf in: %s" % conf.env.DEFAULT_PROTOBUF_PATH)
else:
Logs.warn("Option --protobuf_path wasn\'t defined. Trying default: %s" % conf.env.DEFAULT_PROTOBUF_PATH)
conf.env.append_value("CPPPATH_PROTOBUF", "%s/include"%(conf.env.PROTOBUF_PATH))
conf.env.append_value("LIBPATH_PROTOBUF", "%s/lib"%(conf.env.PROTOBUF_PATH))
conf.env.append_value("LIB_PROTOBUF", "protobuf")
Expand Down