Implement proton.Data.Binary and check end to end binary transfer, looks like 
it works OK but more testing needed

git-svn-id: 
https://svn.apache.org/repos/asf/qpid/proton/branches/fadams-javascript-binding@1588790
 13f79535-47bb-0310-9956-ffa450edef68


Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/aa766d06
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/aa766d06
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/aa766d06

Branch: refs/heads/master
Commit: aa766d067e31c72fb988c3d7f0b1614ca487e293
Parents: 2448135
Author: fadams <fadams@unknown>
Authored: Sun Apr 20 16:46:08 2014 +0000
Committer: fadams <fadams@unknown>
Committed: Sun Apr 20 16:46:08 2014 +0000

----------------------------------------------------------------------
 proton-c/bindings/javascript/CMakeLists.txt |   3 +-
 proton-c/bindings/javascript/binding.js     | 180 +++++++++--------------
 proton-c/bindings/javascript/spout.js       |  10 +-
 3 files changed, 81 insertions(+), 112 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/aa766d06/proton-c/bindings/javascript/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/proton-c/bindings/javascript/CMakeLists.txt 
b/proton-c/bindings/javascript/CMakeLists.txt
index 19dc0a0..966d0ba 100644
--- a/proton-c/bindings/javascript/CMakeLists.txt
+++ b/proton-c/bindings/javascript/CMakeLists.txt
@@ -225,7 +225,8 @@ set_target_properties(
   LINK_FLAGS "-s \"EXPORT_NAME='proton'\" -s 
\"WEBSOCKET_SUBPROTOCOL='AMQPWSB10'\" -O2 --pre-js 
${CMAKE_CURRENT_SOURCE_DIR}/binding-open.js --pre-js 
${CMAKE_CURRENT_SOURCE_DIR}/binding.js --post-js 
${CMAKE_CURRENT_SOURCE_DIR}/binding-close.js --js-library 
${CMAKE_CURRENT_SOURCE_DIR}/my-library.js -s 
DEFAULT_LIBRARY_FUNCS_TO_INCLUDE=\"[]\" -s EXPORTED_FUNCTIONS=\"['_test', 
'_uuid_generate', '_pn_bytes', '_pn_error_text', '_pn_code', '_pn_messenger', 
'_pn_messenger_name', '_pn_messenger_set_blocking', '_pn_messenger_free', 
'_pn_messenger_errno', '_pn_messenger_error', 
'_pn_messenger_get_outgoing_window', '_pn_messenger_set_outgoing_window', 
'_pn_messenger_get_incoming_window', '_pn_messenger_set_incoming_window', 
'_pn_messenger_start', '_pn_messenger_stop', '_pn_messenger_stopped', 
'_pn_messenger_subscribe', '_pn_messenger_put', '_pn_messenger_status', 
'_pn_messenger_buffered', '_pn_messenger_settle', 
'_pn_messenger_outgoing_tracker', '_pn_messenger_work', '_pn_messenger_recv', 
'_pn_m
 essenger_receiving', '_pn_messenger_get', '_pn_messenger_incoming_tracker', 
'_pn_messenger_incoming_subscription', '_pn_messenger_accept', 
'_pn_messenger_reject', '_pn_messenger_outgoing', '_pn_messenger_incoming',  
'_pn_messenger_route', '_pn_messenger_rewrite', '_pn_subscription_get_context', 
'_pn_subscription_set_context', '_pn_subscription_address', '_pn_message', 
'_pn_message_free', '_pn_message_get_address', '_pn_message_errno', 
'_pn_message_error', '_pn_message_set_address', '_pn_message_get_subject', 
'_pn_message_set_subject', '_pn_message_instructions', 
'_pn_message_annotations', '_pn_message_properties', '_pn_message_body', 
'_pn_data', '_pn_data_free', '_pn_data_error', '_pn_data_errno', 
'_pn_data_clear', '_pn_data_rewind', '_pn_data_next', '_pn_data_prev', 
'_pn_data_enter', '_pn_data_exit', '_pn_data_lookup', '_pn_data_narrow', 
'_pn_data_widen', '_pn_data_type', '_pn_data_encode', '_pn_data_decode', 
'_pn_data_put_list', '_pn_data_put_map', '_pn_data_put_array', '_pn_data_
 put_described', '_pn_data_put_null', '_pn_data_put_bool', 
'_pn_data_put_ubyte', '_pn_data_put_byte', '_pn_data_put_ushort', 
'_pn_data_put_short', '_pn_data_put_uint', '_pn_data_put_int', 
'_pn_data_put_char', '_pn_data_put_ulong', '_pn_data_put_long', 
'_pn_data_put_timestamp', '_pn_data_put_float', '_pn_data_put_double', 
'_pn_data_put_decimal32', '_pn_data_put_decimal64', '_pn_data_put_decimal128', 
'_pn_data_put_uuid', '_pn_data_put_binary', '_pn_data_put_string', 
'_pn_data_put_symbol', '_pn_data_get_list', '_pn_data_get_map', 
'_pn_data_get_array', '_pn_data_is_described', '_pn_data_is_null', 
'_pn_data_get_bool', '_pn_data_get_ubyte', '_pn_data_get_byte', 
'_pn_data_get_ushort', '_pn_data_get_short', '_pn_data_get_uint', 
'_pn_data_get_int', '_pn_data_get_char', '_pn_data_get_ulong', 
'_pn_data_get_long', '_pn_data_get_timestamp', '_pn_data_get_float', 
'_pn_data_get_double', '_pn_data_get_decimal32', '_pn_data_get_decimal64', 
'_pn_data_get_decimal128', '_pn_data_get_uuid', '_pn_data_get
 _binary', '_pn_data_get_string', '_pn_data_get_symbol', '_pn_data_copy', 
'_pn_data_format', '_pn_data_dump']\""
   )
 
-
+# If the docs target is specified and the jsdoc3 package for node.js has been
+# installed then build the JavaScript API documentation.
 if (NODE_JSDOC_FOUND)
     message(STATUS "Documentation Enabled")
     add_custom_target(docs-js COMMAND ${JSDOC_EXE}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/aa766d06/proton-c/bindings/javascript/binding.js
----------------------------------------------------------------------
diff --git a/proton-c/bindings/javascript/binding.js 
b/proton-c/bindings/javascript/binding.js
index 6559f11..41020e6 100644
--- a/proton-c/bindings/javascript/binding.js
+++ b/proton-c/bindings/javascript/binding.js
@@ -49,56 +49,6 @@ var Module = {
 };
 
 
-
-/**
- * This class is a buffer for use with the emscripten based port of zlib. It 
allows creation management of a 
- * buffer in the virtual heap space of the zlib library hiding the 
implementation detail from client code.
- */
-/*
-var Buffer = function(size) {
-    var _public = {};
-    var asize = 0; // The allocated size of the input buffer.
-    var ptr   = 0; // Handle to the input buffer.
-
-    // Private methods.
-    function freeBuffer() {
-        if (ptr !== 0) {
-            _free(ptr);
-        }
-    };
-
-    // Public methods
-    _public.destroy = function() {
-        freeBuffer();
-    };
-
-    _public.setSize = function(size) {
-        if (size > asize) {
-            freeBuffer();
-            ptr = _malloc(size); // Get output buffer from emscripten.
-            asize = size;
-        }
-        _public.size = size;
-    };
-
-    _public.getRaw = function() {
-        return ptr;
-    };
-
-    _public.getBuffer = function() {
-        // Get a Uint8Array view on the input buffer.
-        return new Uint8Array(HEAPU8.buffer, ptr, _public.size);
-    };
-
-    if (size) {
-        _public.setSize(size);
-    }
-
-    return _public;
-};
-*/
-
-
 /*****************************************************************************/
 /*                                                                           */
 /*                                   Status                                  */
@@ -1515,6 +1465,18 @@ Data.Long.prototype.toString = function() {
  * @param {number} start an optional data pointer to the start of the Binary 
data buffer.
  */
 Data['Binary'] = function(size, start) { // Data.Binary Constructor.
+    /*
+     * If the start pointer is specified then the underlying binary data is 
owned
+     * by another object, so we set the call to free to be a null function. If
+     * the start pointer is not passed then we allocate storage of the 
specified
+     * size on the emscripten heap and set the call to free to free the data 
from
+     * the emscripten heap. We have made the call to free a protected method 
that
+     * is only visible within the scope of the binding closure, clients should
+     * not have to call free themselves as the data is either already "owned" 
by
+     * a Data object or is destined to be passed to a Data object, which will 
in
+     * turn take responsibility for calling free once it has taken ownership of
+     * the underlying binary data.
+     */
     if (start) {
         this.free = function() {};
     } else {
@@ -1528,7 +1490,7 @@ Data['Binary'] = function(size, start) { // Data.Binary 
Constructor.
 
 /*
  * Get a Uint8Array view of the data. N.B. this is just a *view* of the data,
- * which will out of scope on the next call to {@link proton.Messenger.get}. If
+ * which will go out of scope on the next call to {@link 
proton.Messenger.get}. If
  * a client wants to retain the data then copyBuffer should be used to 
explicitly
  * create a copy of the data which the client then owns to do with as it 
wishes.
  * @method getBuffer
@@ -1956,11 +1918,34 @@ _Data_['putUUID'] = function(u) {
  * Puts a binary value.
  * @method putBinary
  * @memberof! proton.Data#
- * @param b a binary value.
+ * @param {proton.Data.Binary} b a binary value.
  */
-_Data_['putBinary'] = function(d) {
-console.log("putBinary not properly implemented yet");
-    this._check(_pn_data_put_binary(this._data, b));
+_Data_['putBinary'] = function(b) {
+console.log("putBinary");
+
+    var sp = Runtime.stackSave();
+    // The implementation here is a bit "quirky" due to some low-level details
+    // of the interaction between emscripten and LLVM and the use of pn_bytes.
+    // The JavaScript code below is basically a binding to:
+    //
+    // pn_data_put_binary(data, pn_bytes(b.size, b.start));
+
+    // Here's the quirky bit, pn_bytes actually returns pn_bytes_t *by value* 
but
+    // the low-level code handles this *by pointer* so we first need to 
allocate
+    // 8 bytes storage for {size, start} on the emscripten stack and then we
+    // pass the pointer to that storage as the first parameter to the compiled
+    // pn_bytes.
+    var bytes = allocate(8, 'i8', ALLOC_STACK);
+    _pn_bytes(bytes, b.size, b.start);
+
+    // The compiled pn_data_put_binary takes the pn_bytes_t by reference not 
value.
+    this._check(_pn_data_put_binary(this._data, bytes));
+
+    // After calling _pn_data_put_binary the underlying data object "owns" the
+    // binary data, so we can call free on the proton.Data.Binary instance to
+    // release any storage it has acquired back to the emscripten heap.
+    b.free();
+    Runtime.stackRestore(sp);
 };
 
 /**
@@ -2282,8 +2267,34 @@ _Data_['getUUID'] = function() {
  * @returns {proton.Data.Binary} value if the current node is a Binary, 
returns null otherwise.
  */
 _Data_['getBinary'] = function() {
-console.log("getBinary not properly implemented yet");
-    //this._check(_pn_data_put_binary(this._data, b));
+console.log("getBinary");
+    var sp = Runtime.stackSave();
+    // The implementation here is a bit "quirky" due to some low-level details
+    // of the interaction between emscripten and LLVM and the use of pn_bytes.
+    // The JavaScript code below is basically a binding to:
+    //
+    // pn_bytes bytes = pn_data_get_binary(data);
+
+    // Here's the quirky bit, pn_data_get_binary actually returns pn_bytes_t 
+    // *by value* but the low-level code handles this *by pointer* so we first
+    // need to allocate 8 bytes storage for {size, start} on the emscripten 
stack
+    // and then we pass the pointer to that storage as the first parameter to 
the
+    // compiled pn_data_get_binary.
+    var bytes = allocate(8, 'i8', ALLOC_STACK);
+    _pn_data_get_binary(bytes, this._data);
+
+    // The bytes variable is really of type pn_bytes_t* so we use emscripten's
+    // getValue() call to retrieve the size and then the start pointer.
+    var size  = getValue(bytes, 'i32');
+    var start = getValue(bytes + 4, '*');
+
+    // Create a proton.Data.Binary from the pn_bytes_t information.
+    var binary = new Data['Binary'](size, start);
+
+    // Tidy up the memory that we allocated on emscripten's stack.
+    Runtime.stackRestore(sp);
+
+    return binary;
 };
 
 /**
@@ -2484,6 +2495,8 @@ console.log("obj is quoted String " + quoted);
         }   
     } else if (obj instanceof Data['UUID']) {
         this['putUUID'](obj);
+    } else if (obj instanceof Data['Binary']) {
+        this['putBinary'](obj);
     } else if (obj instanceof Data['Symbol']) {
         this['putSymbol'](obj);
     } else if (Data.isNumber(obj)) {
@@ -2548,56 +2561,3 @@ _Data_.getObject = _Data_['getObject'];
 
 
 
-
-
-
-
-
-
-
-
-
-
-/*
-Module['Inflate'] = function(size) {
-    var _public = {};
-    var stream = _inflateInitialise();
-    var inputBuffer  = Buffer(size);
-    var outputBuffer = Buffer(size);
-
-    // Public methods
-    _public['destroy'] = function() {
-        _inflateDestroy(stream);
-        inputBuffer.destroy();
-        outputBuffer.destroy();
-    };
-
-    _public['reset'] = function() {
-        _inflateReset(stream);
-    };
-
-    _public['inflate'] = function(ptr) {
-        ptr = ptr ? ptr : outputBuffer.getRaw();
-        var inflatedSize; // Pass by reference variable - need to use 
Module.setValue to initialise it.
-        setValue(inflatedSize, outputBuffer.size, 'i32');
-        var err = _zinflate(stream, ptr, inflatedSize, inputBuffer.getRaw(), 
inputBuffer.size);
-        inflatedSize = getValue(inflatedSize, 'i32'); // Dereference the real 
inflatedSize value;
-        outputBuffer.setSize(inflatedSize);
-        return ((err < 0) ? err : inflatedSize); // Return the inflated size, 
or error code if inflation fails.
-    };
-
-    // Export methods from the input and output buffers for use by client code.
-    _public['setInputBufferSize'] = inputBuffer.setSize;
-    _public['getRawInputBuffer'] = inputBuffer.getRaw;
-    _public['getInputBuffer'] = inputBuffer.getBuffer;
-
-    _public['setOutputBufferSize'] = outputBuffer.setSize;
-    _public['getRawOutBuffer'] = outputBuffer.getRaw;
-    _public['getOutputBuffer'] = outputBuffer.getBuffer;
-
-    return _public;
-};
-*/
-
-
-

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/aa766d06/proton-c/bindings/javascript/spout.js
----------------------------------------------------------------------
diff --git a/proton-c/bindings/javascript/spout.js 
b/proton-c/bindings/javascript/spout.js
index 8bb8542..7d3cc58 100644
--- a/proton-c/bindings/javascript/spout.js
+++ b/proton-c/bindings/javascript/spout.js
@@ -70,6 +70,14 @@ console.log("exiting");
     //message.body = msgtext;
     //message.body = new proton.Data.UUID();
     //message.body = new proton.Data.Symbol("My Symbol");
+    message.body = new proton.Data.Binary(4);
+    var buffer = message.body.getBuffer();
+    buffer[0] = 65;
+    buffer[1] = 77;
+    buffer[2] = 81;
+    buffer[3] = 80;
+
+
     //message.body = true;
     //message.body = "   \"127.0\"  ";
 
@@ -80,7 +88,7 @@ console.log("exiting");
     //message.body = 2147483647.000001; // double
 
     //message.body = ['Rod', 'Jane', 'Freddy'];
-    message.body = ['Rod', 'Jane', 'Freddy', {cat: true, donkey: 'hee haw'}];
+    //message.body = ['Rod', 'Jane', 'Freddy', {cat: true, donkey: 'hee haw'}];
 
 
     tracker = messenger.put(message);


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to