From 74002bbccb5f054ac51329738185c2ea67c57b0c Mon Sep 17 00:00:00 2001 From: Peter Griess Date: Thu, 27 May 2010 09:42:50 -0500 Subject: [PATCH] Expose # bytes left in buffer after unpack. - If msgpack.unpack() does not consume the entire buffer, expose the number of bytes remaining as the 'msgpack.unpack.bytes_remaining' property. --- src/msgpack.cc | 22 ++++++++++++++++++---- test/test-unpack-extra.js | 22 ++++++++++++++++++++++ test.js => test/test.js | 0 3 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 test/test-unpack-extra.js rename test.js => test/test.js (100%) diff --git a/src/msgpack.cc b/src/msgpack.cc index 5481822..f835a41 100644 --- a/src/msgpack.cc +++ b/src/msgpack.cc @@ -10,6 +10,9 @@ using namespace v8; using namespace node; static Persistent msgpack_tag_symbol; +static Persistent msgpack_bytes_remaining_symbol; + +static Persistent msgpack_unpack_template; // An exception class that wraps a textual message class MsgpackException { @@ -280,11 +283,12 @@ unpack(const Arguments &args) { switch (msgpack_unpack(buf->data(), buf->length(), &off, &mz._mz, &mo)) { case MSGPACK_UNPACK_EXTRA_BYTES: - fprintf(stderr, "msgpack::unpack() got %lu extra bytes\n", off); - /* fall through */ - case MSGPACK_UNPACK_SUCCESS: try { + msgpack_unpack_template->GetFunction()->Set( + msgpack_bytes_remaining_symbol, + Integer::New(buf->length() - off) + ); return scope.Close(msgpack_to_v8(&mo)); } catch (MsgpackException e) { return e.getThrownException(); @@ -301,9 +305,19 @@ init(Handle target) { HandleScope scope; NODE_SET_METHOD(target, "pack", pack); - NODE_SET_METHOD(target, "unpack", unpack); + + // Go through this mess rather than call NODE_SET_METHOD so that we can set + // a field on the function for 'bytes_remaining'. + msgpack_unpack_template = Persistent::New( + FunctionTemplate::New(unpack) + ); + target->Set( + String::NewSymbol("unpack"), + msgpack_unpack_template->GetFunction() + ); msgpack_tag_symbol = NODE_PSYMBOL("msgpack::tag"); + msgpack_bytes_remaining_symbol = NODE_PSYMBOL("bytes_remaining"); } // vim:ts=4 sw=4 et diff --git a/test/test-unpack-extra.js b/test/test-unpack-extra.js new file mode 100644 index 0000000..4b83ed2 --- /dev/null +++ b/test/test-unpack-extra.js @@ -0,0 +1,22 @@ +// Verify that unpacking a buffer with extra bytes doesn't lose the extra data + +var assert = require('assert'); +var msgpack = require('msgpack'); +var buffer = require('buffer'); + +// Object to test with +var o = [1, 2, 3]; + +// Create two buffers full of packed data, 'b' and 'bb', with the latter +// containing 3 extra bytes +var b = msgpack.pack(o); +var bb = new buffer.Buffer(b.length + 3); +b.copy(bb, 0, 0, b.length); + +// Expect no remaining bytes when unpacking 'b' +assert.deepEqual(msgpack.unpack(b), o); +assert.deepEqual(msgpack.unpack.bytes_remaining, 0); + +// Expect 3 remaining bytes when unpacking 'bb' +assert.deepEqual(msgpack.unpack(bb), o); +assert.equal(msgpack.unpack.bytes_remaining, 3); diff --git a/test.js b/test/test.js similarity index 100% rename from test.js rename to test/test.js