blob: 40b15f284272bff0c1b3df1445a57223b7a0b662 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
/*****************************************************************************/
/* */
/* Message */
/* */
/*****************************************************************************/
/**
* Constructs a proton.Message instance.
* @classdesc This class is a mutable holder of message content that may be used
* to generate and encode or decode and access AMQP formatted message data.
* @constructor proton.Message
* @property {object} instructions delivery instructions for the message.
* @property {object} annotations infrastructure defined message annotations.
* @property {object} properties application defined message properties.
* @property {object} body message body as a native JavaScript Object.
* @property {object} data message body as a proton.Data Object.
*/
Module['Message'] = function() { // Message Constructor.
this._message = _pn_message();
this._id = new Data(_pn_message_id(this._message));
this._correlationId = new Data(_pn_message_correlation_id(this._message));
// ************************* Public properties ****************************
// Intitialise with an empty Object so we can set properties in a natural way.
// message.properties.prop1 = "foo";
// message.properties.prop2 = "bar";
this['properties'] = {};
/**
// The properties may be used, but are initially undefined.
this['instructions'];
this['annotations'];
this['body'];
this['data'];
*/
};
// Expose constructor as package scope variable to make internal calls less verbose.
var Message = Module['Message'];
// Expose prototype as a variable to make method declarations less verbose.
var _Message_ = Message.prototype;
// ************************** Class properties ********************************
Message['DEFAULT_PRIORITY'] = 4; /** Default priority for messages.*/
// ************************* Protected methods ********************************
// We use the dot notation rather than associative array form for protected
// methods so they are visible to this "package", but the Closure compiler will
// minify and obfuscate names, effectively making a defacto "protected" method.
/**
* This helper method checks the supplied error code, converts it into an
* exception and throws the exception. This method will try to use the message
* populated in pn_message_error(), if present, but if not it will fall
* back to using the basic error code rendering from pn_code().
* @param code the error code to check.
*/
_Message_._check = function(code) {
if (code < 0) {
var errno = this['getErrno']();
var message = errno ? this['getError']() : Pointer_stringify(_pn_code(code));
throw new Module['MessageError'](message);
} else {
return code;
}
};
/**
* Encode the Message prior to sending on the wire.
*/
_Message_._preEncode = function() {
// A Message Object may be reused so we create new Data instances and clear
// the state for them each time put() gets called.
var inst = new Data(_pn_message_instructions(this._message));
var ann = new Data(_pn_message_annotations(this._message));
var props = new Data(_pn_message_properties(this._message));
var body = new Data(_pn_message_body(this._message));
inst.clear();
if (this['instructions'] !== undefined) {
inst['putObject'](this['instructions']);
}
ann.clear();
if (this['annotations'] !== undefined) {
ann['putObject'](this['annotations']);
}
props.clear();
if (this['properties'] !== undefined) {
props['putObject'](this['properties']);
}
body.clear();
if (this['body'] !== undefined) {
var contentType = this['getContentType']();
if (contentType) {
var value = this['body'];
if (contentType === 'application/json' && JSON) { // Optionally encode body as JSON.
var json = JSON.stringify(value);
value = new Data['Binary'](json);
} else if (!(value instanceof Data['Binary'])) { // Construct a Binary from the body
value = new Data['Binary'](value);
}
// As content-type is set we send as an opaque AMQP data section.
this['setInferred'](true);
body['putBINARY'](value);
} else { // By default encode body using the native AMQP type system.
this['setInferred'](false);
body['putObject'](this['body']);
}
}
};
/**
* Decode the Message after receiving off the wire.
* @param {boolean} decodeBinaryAsString if set decode any AMQP Binary payload
* objects as strings. This can be useful as the data in Binary objects
* will be overwritten with subsequent calls to get, so they must be
* explicitly copied. Needless to say it is only safe to set this flag if
* you know that the data you are dealing with is actually a string, for
* example C/C++ applications often seem to encode strings as AMQP binary,
* a common cause of interoperability problems.
*/
_Message_._postDecode = function(decodeBinaryAsString) {
var inst = new Data(_pn_message_instructions(this._message));
var ann = new Data(_pn_message_annotations(this._message));
var props = new Data(_pn_message_properties(this._message));
var body = new Data(_pn_message_body(this._message), decodeBinaryAsString);
if (inst.next()) {
this['instructions'] = inst['getObject']();
} else {
delete this['instructions'];
}
if (ann.next()) {
this['annotations'] = ann['getObject']();
} else {
delete this['annotations'];
}
if (props.next()) {
this['properties'] = props['getObject']();
} else {
this['properties'] = {};
}
if (body.next()) {
this['data'] = body;
this['body'] = body['getObject']();
var contentType = this['getContentType']();
if (contentType) {
if (contentType === 'application/json' && JSON) {
var json = this['body'].toString(); // Convert Binary to String.
this['body'] = JSON.parse(json);
} else if (contentType.indexOf('text/') === 0) { // It's a text/* MIME type
this['body'] = this['body'].toString(); // Convert Binary to String.
}
}
} else {
// If no body is present ensure that the properties are undefined.
delete this['data'];
delete this['body'];
}
};
// *************************** Public methods *********************************
/**
* Free the Message.
* <p>
* N.B. This method has to be called explicitly in JavaScript as we can't
* intercept finalisers, so we need to remember to free before removing refs.
* @method free
* @memberof! proton.Message#
*/
_Message_['free'] = function() {
_pn_message_free(this._message);
};
/**
* @method getErrno
* @memberof! proton.Message#
* @returns {number the most recent error message code.
*/
_Message_['getErrno'] = function() {
return _pn_message_errno(this._message);
};
/**
* @method getError
* @memberof! proton.Message#
* @returns {string} the most recent error message as a String.
*/
_Message_['getError'] = function() {
return Pointer_stringify(_pn_error_text(_pn_message_error(this._message)));
};
/**
* Clears the contents of the Message. All fields will be reset to their default values.
* @method clear
* @memberof! proton.Message#
*/
_Message_['clear'] = function() {
_pn_message_clear(this._message);
this['properties'] = {};
delete this['instructions'];
delete this['annotations'];
delete this['body'];
delete this['data'];
};
/**
* Get the inferred flag for a message.
* <p>
* The inferred flag for a message indicates how the message content
* is encoded into AMQP sections. If inferred is true then binary and
* list values in the body of the message will be encoded as AMQP DATA
* and AMQP SEQUENCE sections, respectively. If inferred is false,
* then all values in the body of the message will be encoded as AMQP
* VALUE sections regardless of their type. Use
* {@link proton.Message.setInferred} to set the value.
* @method isInferred
* @memberof! proton.Message#
* @returns {boolean} true iff the inferred flag for the message is set.
*/
_Message_['isInferred'] = function() {
return (_pn_message_is_inferred(this._message) > 0);
};
/**
* Set the inferred flag for a message. See {@link proton.Message.isInferred}
* for a description of what the inferred flag is.
* @method setInferred
* @memberof! proton.Message#
* @param {boolean} inferred the new value of the inferred flag.
*/
_Message_['setInferred'] = function(inferred) {
this._check(_pn_message_set_inferred(this._message, inferred));
};
/**
* Get the durable flag for a message.
* <p>
* The durable flag indicates that any parties taking responsibility
* for the message must durably store the content. Use
* {@link proton.Message.setDurable} to set the value.
* @method isDurable
* @memberof! proton.Message#
* @returns {boolean} true iff the durable flag for the message is set.
*/
_Message_['isDurable'] = function() {
return (_pn_message_is_durable(this._message) > 0);
};
/**
* Set the durable flag for a message. See {@link proton.Message.isDurable}
* for a description of what the durable flag is.
* @method setDurable
* @memberof! proton.Message#
* @param {boolean} durable the new value of the durable flag.
*/
_Message_['setDurable'] = function(durable) {
this._check(_pn_message_set_durable(this._message, durable));
};
/**
* Get the priority for a message.
* <p>
* The priority of a message impacts ordering guarantees. Within a
* given ordered context, higher priority messages may jump ahead of
* lower priority messages. Priority range is 0..255
* @method getPriority
* @memberof! proton.Message#
* @returns {number} the priority of the Message.
*/
_Message_['getPriority'] = function() {
return _pn_message_get_priority(this._message) & 0xFF; // & 0xFF converts to unsigned.
};
/**
* Set the priority of the Message. See {@link proton.Message.getPriority}
* for details on message priority.
* @method setPriority
* @memberof! proton.Message#
* @param {number} priority the address we want to send the Message to.
*/
_Message_['setPriority'] = function(priority) {
this._check(_pn_message_set_priority(this._message, priority));
};
/**
* Get the ttl for a message.
* <p>
* The ttl for a message determines how long a message is considered
* live. When a message is held for retransmit, the ttl is
* decremented. Once the ttl reaches zero, the message is considered
* dead. Once a message is considered dead it may be dropped. Use
* {@link proton.Message.setTTL} to set the ttl for a message.
* @method getTTL
* @memberof! proton.Message#
* @returns {number} the ttl in milliseconds.
*/
_Message_['getTTL'] = function() {
return _pn_message_get_ttl(this._message);
};
/**
* Set the ttl for a message. See {@link proton.Message.getTTL}
* for a detailed description of message ttl.
* @method setTTL
* @memberof! proton.Message#
* @param {number} ttl the new value for the message ttl in milliseconds.
*/
_Message_['setTTL'] = function(ttl) {
this._check(_pn_message_set_ttl(this._message, ttl));
};
/**
* Get the first acquirer flag for a message.
* <p>
* When set to true, the first acquirer flag for a message indicates
* that the recipient of the message is the first recipient to acquire
* the message, i.e. there have been no failed delivery attempts to
* other acquirers. Note that this does not mean the message has not
* been delivered to, but not acquired, by other recipients.
* @method isFirstAcquirer
* @memberof! proton.Message#
* @returns {boolean} true iff the first acquirer flag for the message is set.
*/
_Message_['isFirstAcquirer'] = function() {
return (_pn_message_is_first_acquirer(this._message) > 0);
};
/**
* Set the first acquirer flag for a message. See {@link proton.Message.isFirstAcquirer}
* for details on the first acquirer flag.
* @method setFirstAcquirer
* @memberof! proton.Message#
* @param {boolean} first the new value of the first acquirer flag.
*/
_Message_['setFirstAcquirer'] = function(first) {
this._check(_pn_message_set_first_acquirer(this._message, first));
};
/**
* Get the delivery count for a message.
* <p>
* The delivery count field tracks how many attempts have been made to
* deliver a message. Use {@link proton.Message.setDeliveryCount} to set
* the delivery count for a message.
* @method getDeliveryCount
* @memberof! proton.Message#
* @returns {number} the delivery count for the message.
*/
_Message_['getDeliveryCount'] = function() {
return _pn_message_get_delivery_count(this._message);
};
/**
* Set the delivery count for a message. See {@link proton.Message.getDeliveryCount}
* for details on what the delivery count means.
* @method setDeliveryCount
* @memberof! proton.Message#
* @param {number} count the new delivery count.
*/
_Message_['setDeliveryCount'] = function(count) {
this._check(_pn_message_set_delivery_count(this._message, count));
};
/**
* Get the id for a message.
* <p>
* The message id provides a globally unique identifier for a message.
* A message id can be an a string, an unsigned long, a uuid or a binary value.
* @method getID
* @memberof! proton.Message#
* @returns {(number|string|proton.Data.Long|proton.Data.Uuid|proton.Data.Binary)} the message id.
*/
_Message_['getID'] = function() {
return this._id['getObject']();
};
/**
* Set the id for a message. See {@link proton.Message.getID}
* for more details on the meaning of the message id. Note that only string,
* unsigned long, uuid, or binary values are permitted.
* @method setID
* @memberof! proton.Message#
* @param {(number|string|proton.Data.Long|proton.Data.Uuid|proton.Data.Binary)} id the
* new value of the message id.
*/
_Message_['setID'] = function(id) {
this._id['rewind']();
if (Data.isNumber(id)) {
this._id['putULONG'](id);
} else {
this._id['putObject'](id);
}
};
/**
* Get the user id of the message creator.
* <p>
* The underlying raw data of the returned {@link proton.Data.Binary} will be
* valid until any one of the following operations occur:
* <pre>
* - {@link proton.Message.free}
* - {@link proton.Message.clear}
* - {@link proton.Message.setUserID}
* </pre>
* @method getUserID
* @memberof! proton.Message#
* @returns {proton.Data.Binary} the message's user id.
*/
_Message_['getUserID'] = function() {
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_t bytes = pn_message_get_user_id(message);
// Here's the quirky bit, pn_message_get_user_id 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_message_get_user_id.
var bytes = allocate(8, 'i8', ALLOC_STACK);
_pn_message_get_user_id(bytes, this._message);
// 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;
};
/**
* Set the user id for a message. This method takes a {@link proton.Data.Binary}
* consuming the underlying raw data in the process. For convenience this method
* also accepts a {@link proton.Data.Uuid}, number or string, converting them to a
* Binary internally. N.B. getUserID always returns a {@link proton.Data.Binary}
* even if a string or {@link proton.Data.Uuid} has been passed to setUserID.
* @method setUserID
* @memberof! proton.Message#
* @param {(string|proton.Data.Uuid)} id the new user id for the message.
*/
_Message_['setUserID'] = function(id) {
// If the id parameter is a proton.Data.Binary use it otherwise create a Binary
// using the string form of the parameter that was passed.
id = (id instanceof Data['Binary']) ? id : new Data['Binary']('' + id);
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_message_set_user_id(message, pn_bytes(id.size, id.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 pn_bytes.
var bytes = allocate(8, 'i8', ALLOC_STACK);
_pn_bytes(bytes, id.size, id.start);
// The compiled pn_message_set_user_id takes the pn_bytes_t by reference not value.
this._check(_pn_message_set_user_id(this._message, bytes));
// After calling _pn_message_set_user_id the underlying Message 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.
id['free']();
Runtime.stackRestore(sp);
};
/**
* Get the address for a message.
* @method getAddress
* @memberof! proton.Message#
* @returns {string} the address of the Message.
*/
_Message_['getAddress'] = function() {
return Pointer_stringify(_pn_message_get_address(this._message));
};
/**
* Set the address of the Message.
* @method setAddress
* @memberof! proton.Message#
* @param {string} address the address we want to send the Message to.
*/
_Message_['setAddress'] = function(address) {
var sp = Runtime.stackSave();
this._check(_pn_message_set_address(this._message, allocate(intArrayFromString(address), 'i8', ALLOC_STACK)));
Runtime.stackRestore(sp);
};
/**
* Get the subject for a message.
* @method getSubject
* @memberof! proton.Message#
* @returns {string} the subject of the Message.
*/
_Message_['getSubject'] = function() {
return Pointer_stringify(_pn_message_get_subject(this._message));
};
/**
* Set the subject of the Message.
* @method setSubject
* @memberof! proton.Message#
* @param {string} subject the subject we want to set for the Message.
*/
_Message_['setSubject'] = function(subject) {
var sp = Runtime.stackSave();
this._check(_pn_message_set_subject(this._message, allocate(intArrayFromString(subject), 'i8', ALLOC_STACK)));
Runtime.stackRestore(sp);
};
/**
* Get the reply to for a message.
* @method getReplyTo
* @memberof! proton.Message#
* @returns {string} the reply to of the Message.
*/
_Message_['getReplyTo'] = function() {
return Pointer_stringify(_pn_message_get_reply_to(this._message));
};
/**
* Set the reply to for a message.
* @method setReplyTo
* @memberof! proton.Message#
* @param {string} reply the reply to we want to set for the Message.
*/
_Message_['setReplyTo'] = function(reply) {
var sp = Runtime.stackSave();
this._check(_pn_message_set_reply_to(this._message, allocate(intArrayFromString(reply), 'i8', ALLOC_STACK)));
Runtime.stackRestore(sp);
};
/**
* Get the correlation id for a message.
* <p>
* A correlation id can be an a string, an unsigned long, a uuid or a binary value.
* @method getCorrelationID
* @memberof! proton.Message#
* @returns {(number|string|proton.Data.Long|proton.Data.Uuid|proton.Data.Binary)} the message id.
*/
_Message_['getCorrelationID'] = function() {
return this._correlationId['getObject']();
};
/**
* Set the correlation id for a message. See {@link proton.Message.getCorrelationID}
* for more details on the meaning of the correlation id. Note that only string,
* unsigned long, uuid, or binary values are permitted.
* @method setCorrelationID
* @memberof! proton.Message#
* @param {(number|string|proton.Data.Long|proton.Data.Uuid|proton.Data.Binary)} id the
* new value of the correlation id.
*/
_Message_['setCorrelationID'] = function(id) {
this._correlationId['rewind']();
if (Data.isNumber(id)) {
this._correlationId['putULONG'](id);
} else {
this._correlationId['putObject'](id);
}
};
/**
* Get the content type for a message.
* @method getContentType
* @memberof! proton.Message#
* @returns {string} the content type of the Message.
*/
_Message_['getContentType'] = function() {
return Pointer_stringify(_pn_message_get_content_type(this._message));
};
/**
* Set the content type for a message.
* @method setContentType
* @memberof! proton.Message#
* @param {string} type the content type we want to set for the Message.
*/
_Message_['setContentType'] = function(type) {
var sp = Runtime.stackSave();
this._check(_pn_message_set_content_type(this._message, allocate(intArrayFromString(type), 'i8', ALLOC_STACK)));
Runtime.stackRestore(sp);
};
/**
* Get the content encoding for a message.
* @method getContentEncoding
* @memberof! proton.Message#
* @returns {string} the content encoding of the Message.
*/
_Message_['getContentEncoding'] = function() {
return Pointer_stringify(_pn_message_get_content_encoding(this._message));
};
/**
* Set the content encoding for a message.
* @method setContentEncoding
* @memberof! proton.Message#
* @param {string} encoding the content encoding we want to set for the Message.
*/
_Message_['setContentEncoding'] = function(encoding) {
var sp = Runtime.stackSave();
this._check(_pn_message_set_content_encoding(this._message, allocate(intArrayFromString(encoding), 'i8', ALLOC_STACK)));
Runtime.stackRestore(sp);
};
/**
* Get the expiry time for a message.
* A zero value for the expiry time indicates that the message will
* never expire. This is the default value.
* @method getExpiryTime
* @memberof! proton.Message#
* @returns {Date} the expiry time for the message.
*/
_Message_['getExpiryTime'] = function() {
// Getting the timestamp is a little tricky as it is a 64 bit number. The way
// emscripten handles this is to return the low 32 bits directly and pass
// the high 32 bits via the tempRet0 variable. We use Data.Long to hold
// the 64 bit number and Data.Long.toNumber() to convert it back into a
// JavaScript number.
var low = _pn_message_get_expiry_time(this._message);
var high = Runtime.getTempRet0();
var long = new Data.Long(low, high);
long = long.toNumber();
return new Date(long);
};
/**
* Set the expiry time for a message.
* @method setExpiryTime
* @memberof! proton.Message#
* @param {(number|Date)} time the new expiry time for the message.
*/
_Message_['setExpiryTime'] = function(time) {
// Note that a timestamp is a 64 bit number so we have to use a proton.Data.Long.
var timestamp = Data.Long.fromNumber(time.valueOf());
this._check(_pn_message_set_expiry_time(this._message, timestamp.getLowBitsUnsigned(), timestamp.getHighBits()));
};
/**
* Get the creation time for a message.
* A zero value for the creation time indicates that the creation time
* has not been set. This is the default value.
* @method getCreationTime
* @memberof! proton.Message#
* @returns {Date} the creation time for the message.
*/
_Message_['getCreationTime'] = function() {
// Getting the timestamp is a little tricky as it is a 64 bit number. The way
// emscripten handles this is to return the low 32 bits directly and pass
// the high 32 bits via the tempRet0 variable. We use Data.Long to hold
// the 64 bit number and Data.Long.toNumber() to convert it back into a
// JavaScript number.
var low = _pn_message_get_creation_time(this._message);
var high = Runtime.getTempRet0();
var long = new Data.Long(low, high);
long = long.toNumber();
return new Date(long);
};
/**
* Set the creation time for a message.
* @method setCreationTime
* @memberof! proton.Message#
* @param {(number|Date)} time the new creation time for the message.
*/
_Message_['setCreationTime'] = function(time) {
// Note that a timestamp is a 64 bit number so we have to use a proton.Data.Long.
var timestamp = Data.Long.fromNumber(time.valueOf());
this._check(_pn_message_set_creation_time(this._message, timestamp.getLowBitsUnsigned(), timestamp.getHighBits()));
};
/**
* Get the group id for a message.
* @method getGroupID
* @memberof! proton.Message#
* @returns {string} the group id of the Message.
*/
_Message_['getGroupID'] = function() {
return Pointer_stringify(_pn_message_get_group_id(this._message));
};
/**
* Set the group id for a message.
* @method setGroupID
* @memberof! proton.Message#
* @param {string} id the group id we want to set for the Message.
*/
_Message_['setGroupID'] = function(id) {
var sp = Runtime.stackSave();
this._check(_pn_message_set_group_id(this._message, allocate(intArrayFromString(id), 'i8', ALLOC_STACK)));
Runtime.stackRestore(sp);
};
/**
* Get the group sequence for a message.
* <p>
* The group sequence of a message identifies the relative ordering of
* messages within a group. The default value for the group sequence
* of a message is zero.
* @method getGroupSequence
* @memberof! proton.Message#
* @returns {number} the group sequence for the message.
*/
_Message_['getGroupSequence'] = function() {
return _pn_message_get_group_sequence(this._message);
};
/**
* Set the group sequence for a message. See {@link proton.Message.getGroupSequence}
* for details on what the group sequence means.
* @method setGroupSequence
* @memberof! proton.Message#
* @param {number} n the new group sequence for the message.
*/
_Message_['setGroupSequence'] = function(n) {
this._check(_pn_message_set_group_sequence(this._message, n));
};
/**
* Get the reply to group id for a message.
* @method getReplyToGroupID
* @memberof! proton.Message#
* @returns {string} the reply to group id of the Message.
*/
_Message_['getReplyToGroupID'] = function() {
return Pointer_stringify(_pn_message_get_reply_to_group_id(this._message));
};
/**
* Set the reply to group id for a message.
* @method setReplyToGroupID
* @memberof! proton.Message#
* @param {string} id the reply to group id we want to set for the Message.
*/
_Message_['setReplyToGroupID'] = function(id) {
var sp = Runtime.stackSave();
this._check(_pn_message_set_reply_to_group_id(this._message, allocate(intArrayFromString(id), 'i8', ALLOC_STACK)));
Runtime.stackRestore(sp);
};
/**
* Return a Binary representation of the message encoded in AMQP format. N.B. the
* returned {@link proton.Data.Binary} "owns" the underlying raw data and is thus
* responsible for freeing it or passing it to a method that consumes a Binary
* such as {@link proton.Message.decode}.
* @method encode
* @memberof! proton.Message#
* @returns {proton.Data.Binary} a representation of the message encoded in AMQP format.
*/
_Message_['encode'] = function() {
this._preEncode();
var sp = Runtime.stackSave();
var sizeptr = allocate(4, 'i32', ALLOC_STACK);
var size = 1024;
while (true) {
setValue(sizeptr, size, 'i32'); // Set pass by reference variable.
var bytes = _malloc(size); // Allocate storage from emscripten heap.
var err = _pn_message_encode(this._message, bytes, sizeptr);
var size = getValue(sizeptr, 'i32'); // Dereference the real size value;
if (err === Module['Error']['OVERFLOW']) {
_free(bytes);
size *= 2;
} else if (err >= 0) {
// Tidy up the memory that we allocated on emscripten's stack.
Runtime.stackRestore(sp);
return new Data['Binary'](size, bytes);
} else {
// Tidy up the memory that we allocated on emscripten's stack.
Runtime.stackRestore(sp);
_free(bytes);
this._check(err);
return;
}
}
};
/**
* Decodes and loads the message content from supplied Binary AMQP data N.B.
* this method "consumes" data from a {@link proton.Data.Binary} in other words
* it takes responsibility for the underlying data and frees the raw data from
* the Binary.
* @method decode
* @memberof! proton.Message#
* @param {proton.Data.Binary} encoded the AMQP encoded binary message.
*/
_Message_['decode'] = function(encoded) {
var err = _pn_message_decode(this._message, encoded.start, encoded.size);
encoded['free'](); // Free the original Binary.
if (err >= 0) {
this._postDecode();
}
this._check(err);
};