/*
 * 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.
 *
 */

/*****************************************************************************/
/*                                                                           */
/*                                    Data                                   */
/*                                                                           */
/*****************************************************************************/

/**
 * Constructs a proton.Data instance.
 * @classdesc
 * The Data class provides an interface for decoding, extracting, creating, and
 * encoding arbitrary AMQP data. A Data object contains a tree of AMQP values.
 * Leaf nodes in this tree correspond to scalars in the AMQP type system such as
 * ints<INT> or strings<STRING>. Non-leaf nodes in this tree correspond to compound
 * values in the AMQP type system such as lists<LIST>, maps<MAP>, arrays<ARRAY>,
 * or described values<DESCRIBED>. The root node of the tree is the Data object
 * itself and can have an arbitrary number of children.
 * <p>
 * A Data object maintains the notion of the current sibling node and a current
 * parent node. Siblings are ordered within their parent. Values are accessed
 * and/or added by using the next, prev, enter, and exit methods to navigate to
 * the desired location in the tree and using the supplied variety of put* and
 * get* methods to access or add a value of the desired type.
 * <p>
 * The put* methods will always add a value after the current node in the tree.
 * If the current node has a next sibling the put* method will overwrite the value
 * on this node. If there is no current node or the current node has no next
 * sibling then one will be added. The put* methods always set the added/modified
 * node to the current node. The get* methods read the value of the current node
 * and do not change which node is current.
 * @constructor proton.Data
 * @param {number} data an optional pointer to a pn_data_t instance. If supplied
 *        the underlying data is "owned" by another object (for example a Message)
 *        and that object is assumed to be responsible for freeing the data if
 *        necessary. If no data is supplied then the Data is stand-alone and the
 *        client application is responsible for freeing the underlying data via
 *        a call to free().
 * @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.
 */
Module['Data'] = function(data, decodeBinaryAsString) { // Data Constructor.
    if (!data) {
        this._data = _pn_data(16); // Default capacity is 16
        this['free'] = function() {
            _pn_data_free(this._data);
            // Set free to a null function to prevent possibility of a "double free".
            this['free'] = function() {};
        };
    } else {
        this._data = data;
        this['free'] = function() {};
    }
    this._decodeBinaryAsString = decodeBinaryAsString;
};

// Expose constructor as package scope variable to make internal calls less verbose.
var Data = Module['Data'];

// Expose prototype as a variable to make method declarations less verbose.
var _Data_ = Data.prototype;

// ************************** Class properties ********************************

Data['NULL']       = 1;
Data['BOOL']       = 2;
Data['UBYTE']      = 3;
Data['BYTE']       = 4;
Data['USHORT']     = 5;
Data['SHORT']      = 6;
Data['UINT']       = 7;
Data['INT']        = 8;
Data['CHAR']       = 9;
Data['ULONG']      = 10;
Data['LONG']       = 11;
Data['TIMESTAMP']  = 12;
Data['FLOAT']      = 13;
Data['DOUBLE']     = 14;
Data['DECIMAL32']  = 15;
Data['DECIMAL64']  = 16;
Data['DECIMAL128'] = 17;
Data['UUID']       = 18;
Data['BINARY']     = 19;
Data['STRING']     = 20;
Data['SYMBOL']     = 21;
Data['DESCRIBED']  = 22;
Data['ARRAY']      = 23;
Data['LIST']       = 24;
Data['MAP']        = 25;

/**
 * Look-up table mapping proton-c types to the accessor method used to
 * deserialise the type. N.B. this is a simple Array and not a map because the
 * types that we get back from pn_data_type are integers from the pn_type_t enum.
 * @property {Array<String>} TypeNames ['NULL', 'NULL', 'BOOL', 'UBYTE', 'BYTE',
 * 'USHORT', 'SHORT', 'UINT', 'INT', 'CHAR', 'ULONG', 'LONG', 'TIMESTAMP',
 * 'FLOAT', 'DOUBLE', 'DECIMAL32', 'DECIMAL64', 'DECIMAL128', 'UUID',
 * 'BINARY', 'STRING', 'SYMBOL', 'DESCRIBED', 'ARRAY', 'LIST', 'MAP']
 * @memberof! proton.Data
 */
Data['TypeNames'] = [
    'NULL',       // 0
    'NULL',       // PN_NULL       = 1
    'BOOL',       // PN_BOOL       = 2
    'UBYTE',      // PN_UBYTE      = 3
    'BYTE',       // PN_BYTE       = 4
    'USHORT',     // PN_USHORT     = 5
    'SHORT',      // PN_SHORT      = 6
    'UINT',       // PN_UINT       = 7
    'INT',        // PN_INT        = 8
    'CHAR',       // PN_CHAR       = 9
    'ULONG',      // PN_ULONG      = 10
    'LONG',       // PN_LONG       = 11
    'TIMESTAMP',  // PN_TIMESTAMP  = 12
    'FLOAT',      // PN_FLOAT      = 13
    'DOUBLE',     // PN_DOUBLE     = 14
    'DECIMAL32',  // PN_DECIMAL32  = 15
    'DECIMAL64',  // PN_DECIMAL64  = 16
    'DECIMAL128', // PN_DECIMAL128 = 17
    'UUID',       // PN_UUID       = 18
    'BINARY',     // PN_BINARY     = 19
    'STRING',     // PN_STRING     = 20
    'SYMBOL',     // PN_SYMBOL     = 21
    'DESCRIBED',  // PN_DESCRIBED  = 22
    'ARRAY',      // PN_ARRAY      = 23
    'LIST',       // PN_LIST       = 24
    'MAP'         // PN_MAP        = 25
];

// *************************** Class methods **********************************

/**
 * Test if a given Object is a JavaScript Array.
 * @method isArray
 * @memberof! proton.Data
 * @param {object} o the Object that we wish to test.
 * @returns {boolean} true iff the Object is a JavaScript Array.
 */
Data.isArray = Array.isArray || function(o) {
    return Object.prototype.toString.call(o) === '[object Array]';
};

/**
 * Test if a given Object is a JavaScript Number.
 * @method isNumber
 * @memberof! proton.Data
 * @param {object} o the Object that we wish to test.
 * @returns {boolean} true iff the Object is a JavaScript Number.
 */
Data.isNumber = function(o) {
    return typeof o === 'number' || 
          (typeof o === 'object' && Object.prototype.toString.call(o) === '[object Number]');
};

/**
 * Test if a given Object is a JavaScript String.
 * @method isString
 * @memberof! proton.Data
 * @param {object} o the Object that we wish to test.
 * @returns {boolean} true iff the Object is a JavaScript String.
 */
Data.isString = function(o) {
    return typeof o === 'string' ||
          (typeof o === 'object' && Object.prototype.toString.call(o) === '[object String]');
};

/**
 * Test if a given Object is a JavaScript Boolean.
 * @method isBoolean
 * @memberof! proton.Data
 * @param {object} o the Object that we wish to test.
 * @returns {boolean} true iff the Object is a JavaScript Boolean.
 */
Data.isBoolean = function(o) {
    return typeof o === 'boolean' ||
          (typeof o === 'object' && Object.prototype.toString.call(o) === '[object Boolean]');
};


// ************************* 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_data_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.
 */
_Data_._check = function(code) {
    if (code < 0) {
        var errno = this['getErrno']();
        var message = errno ? this['getError']() : Pointer_stringify(_pn_code(code));

        throw new Module['DataError'](message);
    } else {
        return code;
    }
};


// *************************** Public methods *********************************

/**
 * @method getErrno
 * @memberof! proton.Data#
 * @returns {number} the most recent error message code.
 */
_Data_['getErrno'] = function() {
    return _pn_data_errno(this._data);
};

/**
 * @method getError
 * @memberof! proton.Data#
 * @returns {string} the most recent error message as a String.
 */
_Data_['getError'] = function() {
    return Pointer_stringify(_pn_error_text(_pn_data_error(this._data)));
};

/**
 * Clears the data object.
 * @method clear
 * @memberof! proton.Data#
 */
_Data_['clear'] = function() {
    _pn_data_clear(this._data);
};

/**
 * Clears current node and sets the parent to the root node.  Clearing the current
 * node sets it _before_ the first node, calling next() will advance to the first node.
 * @method rewind
 * @memberof! proton.Data#
 */
_Data_['rewind'] = function() {
    _pn_data_rewind(this._data);
};

/**
 * Advances the current node to its next sibling and returns its type. If there
 * is no next sibling the current node remains unchanged and null is returned.
 * @method next
 * @memberof! proton.Data#
 * @returns {number} the type of the next sibling or null.
 */
_Data_['next'] = function() {
    var found = _pn_data_next(this._data);
    if (found) {
        return this.type();
    } else {
        return null;
    }
};

/**
 * Advances the current node to its previous sibling and returns its type. If there
 * is no previous sibling the current node remains unchanged and null is returned.
 * @method prev
 * @memberof! proton.Data#
 * @returns {number} the type of the previous sibling or null.
 */
_Data_['prev'] = function() {
    var found = _pn_data_prev(this._data);
    if (found) {
        return this.type();
    } else {
        return null;  
    }
};

/**
 * Sets the parent node to the current node and clears the current node. Clearing
 * the current node sets it _before_ the first child, next() advances to the first child.
 * @method enter
 * @memberof! proton.Data#
 */
_Data_['enter'] = function() {
    return (_pn_data_enter(this._data) > 0);
};

/**
 * Sets the current node to the parent node and the parent node to its own parent.
 * @method exit
 * @memberof! proton.Data#
 */
_Data_['exit'] = function() {
    return (_pn_data_exit(this._data) > 0);
};

/**
 * Look up a value by name. N.B. Need to use getObject() to retrieve the actual
 * value after lookup suceeds.
 * @method lookup
 * @memberof! proton.Data#
 * @param {string} name the name of the property to look up.
 * @returns {boolean} true iff the lookup succeeded.
 */
_Data_['lookup'] = function(name) {
    var sp = Runtime.stackSave();
    var lookup = _pn_data_lookup(this._data, allocate(intArrayFromString(name), 'i8', ALLOC_STACK));
    Runtime.stackRestore(sp);
    return (lookup > 0);
};

// TODO document - not quite sure what these are for?
_Data_['narrow'] = function() {
    _pn_data_narrow(this._data);
};

_Data_['widen'] = function() {
    _pn_data_widen(this._data);
};

/**
 * @method type
 * @memberof! proton.Data#
 * @returns {number} the type of the current node or null if the type is unknown.
 */
_Data_['type'] = function() {
    var dtype = _pn_data_type(this._data);
    if (dtype === -1) {
        return null;
    } else {
        return dtype;
    }
};

/**
 * Return a Binary representation of the data 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.Data.decode} or {@link proton.Data.putBINARY}.
 * @method encode
 * @memberof! proton.Data#
 * @returns {proton.Data.Binary} a representation of the data encoded in AMQP format.
 */
_Data_['encode'] = function() {
    var size = 1024;
    while (true) {
        var bytes = _malloc(size); // Allocate storage from emscripten heap.
        var cd = _pn_data_encode(this._data, bytes, size);

        if (cd === Module['Error']['OVERFLOW']) {
            _free(bytes);
            size *= 2;
        } else if (cd >= 0) {
            return new Data['Binary'](cd, bytes);
        } else {
            _free(bytes);
            this._check(cd);
            return;
        }
    }
};

/**
 * Decodes the first value from supplied Binary AMQP data and returns a new
 * {@link proton.Data.Binary} containing the remainder of the data or null if
 * all the supplied data has been consumed. 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.Data#
 * @param {proton.Data.Binary} encoded the AMQP encoded binary data.
 * @returns {proton.Data.Binary} a Binary containing the remaining bytes or null
 *          if all the data has been consumed.
 */
_Data_['decode'] = function(encoded) {
    var start = encoded.start;
    var size = encoded.size;
    var consumed = this._check(_pn_data_decode(this._data, start, size));

    size = size - consumed;
    start = _malloc(size); // Allocate storage from emscripten heap.
    _memcpy(start, encoded.start + consumed, size);

    encoded['free'](); // Free the original Binary.
    return size > 0 ? new Data['Binary'](size, start) : null;
};

/**
 * Puts a list node. Elements may be filled by entering the list
 * node and putting element values.
 * <pre>
 *  var data = new proton.Data();
 *  data.putLISTNODE();
 *  data.enter();
 *  data.putINT(1);
 *  data.putINT(2);
 *  data.putINT(3);
 *  data.exit();
 * </pre>
 * @method putLISTNODE
 * @memberof! proton.Data#
 */
_Data_['putLISTNODE'] = function() {
    this._check(_pn_data_put_list(this._data));
};

/**
 * Puts a map node. Elements may be filled by entering the map node
 * and putting alternating key value pairs.
 * <pre>
 *  var data = new proton.Data();
 *  data.putMAPNODE();
 *  data.enter();
 *  data.putSTRING('key');
 *  data.putSTRING('value');
 *  data.exit();
 * </pre>
 * @method putMAPNODE
 * @memberof! proton.Data#
 */
_Data_['putMAPNODE'] = function() {
    this._check(_pn_data_put_map(this._data));
};

/**
 * Puts an array node. Elements may be filled by entering the array node and
 * putting the element values. The values must all be of the specified array
 * element type. If an array is described then the first child value of the array
 * is the descriptor and may be of any type.
 * <pre>
 *  var data = new proton.Data();
 *  data.putARRAYNODE(false, proton.Data.INT);
 *  data.enter();
 *  data.putINT(1);
 *  data.putINT(2);
 *  data.putINT(3);
 *  data.exit();
 *
 *  data.putARRAYNODE(true, proton.Data.DOUBLE);
 *  data.enter();
 *  data.putSYMBOL('array-descriptor');
 *  data.putDOUBLE(1.1);
 *  data.putDOUBLE(1.2);
 *  data.putDOUBLE(1.3);
 *  data.exit();
 * </pre>
 * @method putARRAYNODE
 * @param {boolean} described specifies whether the array is described.
 * @param {number} type the type of the array elements.
 * @memberof! proton.Data#
 */
_Data_['putARRAYNODE'] = function(described, type) {
    this._check(_pn_data_put_array(this._data, described, type));
};

/**
 * Puts a described node. A described node has two children, the descriptor and
 * value. These are specified by entering the node and putting the desired values.
 * <pre>
 *  var data = new proton.Data();
 *  data.putDESCRIBEDNODE();
 *  data.enter();
 *  data.putSYMBOL('value-descriptor');
 *  data.putSTRING('the value');
 *  data.exit();
 * </pre>
 * @method putDESCRIBEDNODE
 * @memberof! proton.Data#
 */
_Data_['putDESCRIBEDNODE'] = function() {
    this._check(_pn_data_put_described(this._data));
};

/**
 * Puts a null value.
 * @method putNULL
 * @memberof! proton.Data#
 */
_Data_['putNULL'] = function() {
    this._check(_pn_data_put_null(this._data));
};

/**
 * Puts a boolean value.
 * @method putBOOL
 * @memberof! proton.Data#
 * @param {boolean} b a boolean value.
 */
_Data_['putBOOL'] = function(b) {
    this._check(_pn_data_put_bool(this._data, b));
};

/**
 * Puts a unsigned byte value.
 * @method putUBYTE
 * @memberof! proton.Data#
 * @param {number} ub an integral value.
 */
_Data_['putUBYTE'] = function(ub) {
    this._check(_pn_data_put_ubyte(this._data, ub));
};

/**
 * Puts a signed byte value.
 * @method putBYTE
 * @memberof! proton.Data#
 * @param {number} b an integral value.
 */
_Data_['putBYTE'] = function(b) {
    this._check(_pn_data_put_byte(this._data, b));
};

/**
 * Puts a unsigned short value.
 * @method putUSHORT
 * @memberof! proton.Data#
 * @param {number} us an integral value.
 */
_Data_['putUSHORT'] = function(us) {
    this._check(_pn_data_put_ushort(this._data, us));
};

/**
 * Puts a signed short value.
 * @method putSHORT
 * @memberof! proton.Data#
 * @param {number} s an integral value.
 */
_Data_['putSHORT'] = function(s) {
    this._check(_pn_data_put_short(this._data, s));
};

/**
 * Puts a unsigned integer value.
 * @method putUINT
 * @memberof! proton.Data#
 * @param {number} ui an integral value.
 */
_Data_['putUINT'] = function(ui) {
    this._check(_pn_data_put_uint(this._data, ui));
};

/**
 * Puts a signed integer value.
 * @method putINT
 * @memberof! proton.Data#
 * @param {number} i an integral value.
 */
_Data_['putINT'] = function(i) {
    this._check(_pn_data_put_int(this._data, i));
};

/**
 * Puts a signed char value.
 * @method putCHAR
 * @memberof! proton.Data#
 * @param {(string|number)} c a single character expressed either as a string or a number.
 */
_Data_['putCHAR'] = function(c) {
    c = Data.isString(c) ? c.charCodeAt(0) : c;
    this._check(_pn_data_put_char(this._data, c));
};

/**
 * Puts a unsigned long value. N.B. large values can suffer from a loss of
 * precision as JavaScript numbers are restricted to 64 bit double values.
 * @method putULONG
 * @memberof! proton.Data#
 * @param {number} ul an integral value.
 */
_Data_['putULONG'] = function(ul) {
    // If the supplied number exceeds the range of Data.Long invert it before
    // constructing the Data.Long.
    ul = (ul >= Data.Long.TWO_PWR_63_DBL_) ? (ul = -(Data.Long.TWO_PWR_64_DBL_ - ul)) : ul;
    var long = Data.Long.fromNumber(ul);
    this._check(_pn_data_put_ulong(this._data, long.getLowBitsUnsigned(), long.getHighBits()));
};

/**
 * Puts a signed long value. N.B. large values can suffer from a loss of
 * precision as JavaScript numbers are restricted to 64 bit double values.
 * @method putLONG
 * @memberof! proton.Data#
 * @param {number} i an integral value.
 */
_Data_['putLONG'] = function(l) {
    var long = Data.Long.fromNumber(l);
    this._check(_pn_data_put_long(this._data, long.getLowBitsUnsigned(), long.getHighBits()));
};

/**
 * Puts a timestamp.
 * @method putTIMESTAMP
 * @memberof! proton.Data#
 * @param {(number|Date)} d a Date value.
 */
_Data_['putTIMESTAMP'] = function(d) {
    // Note that a timestamp is a 64 bit number so we have to use a proton.Data.Long.
    var timestamp = Data.Long.fromNumber(d.valueOf());
    this._check(_pn_data_put_timestamp(this._data, timestamp.getLowBitsUnsigned(), timestamp.getHighBits()));
};

/**
 * Puts a float value. N.B. converting between floats and doubles is imprecise
 * so the resulting value might not quite be what you expect.
 * @method putFLOAT
 * @memberof! proton.Data#
 * @param {number} f a floating point value.
 */
_Data_['putFLOAT'] = function(f) {
    this._check(_pn_data_put_float(this._data, f));
};

/**
 * Puts a double value.
 * @method putDOUBLE
 * @memberof! proton.Data#
 * @param {number} d a floating point value.
 */
_Data_['putDOUBLE'] = function(d) {
    this._check(_pn_data_put_double(this._data, d));
};

/**
 * Puts a decimal32 value.
 * @method putDECIMAL32
 * @memberof! proton.Data#
 * @param {number} d a decimal32 value.
 */
_Data_['putDECIMAL32'] = function(d) {
    this._check(_pn_data_put_decimal32(this._data, d));
};

/**
 * Puts a decimal64 value.
 * @method putDECIMAL64
 * @memberof! proton.Data#
 * @param {number} d a decimal64 value.
 */
_Data_['putDECIMAL64'] = function(d) {
    this._check(_pn_data_put_decimal64(this._data, d));
};

/**
 * Puts a decimal128 value.
 * @method putDECIMAL128
 * @memberof! proton.Data#
 * @param {number} d a decimal128 value.
 */
_Data_['putDECIMAL128'] = function(d) {
    this._check(_pn_data_put_decimal128(this._data, d));
};

/**
 * Puts a UUID value.
 * @method putUUID
 * @memberof! proton.Data#
 * @param {proton.Data.Uuid} u a uuid value
 */
_Data_['putUUID'] = function(u) {
    var sp = Runtime.stackSave();
    this._check(_pn_data_put_uuid(this._data, allocate(u['uuid'], 'i8', ALLOC_STACK)));
    Runtime.stackRestore(sp);
};

/**
 * Puts a binary value consuming the underlying raw data in the process.
 * @method putBINARY
 * @memberof! proton.Data#
 * @param {proton.Data.Binary} b a binary value.
 */
_Data_['putBINARY'] = function(b) {
    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 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);
};

/**
 * Puts a unicode string value.
 * @method putSTRING
 * @memberof! proton.Data#
 * @param {string} s a unicode string value.
 */
_Data_['putSTRING'] = function(s) {
    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_string(data, pn_bytes(strlen(text), text));

    // First create an array from the JavaScript String using the intArrayFromString
    // helper function (from emscripten/src/preamble.js). We use this idiom in a
    // few places but here we create array as a separate var as we need its length.
    var array = intArrayFromString(s, true); // The true means don't add NULL.
    // Allocate temporary storage for the array on the emscripten stack.
    var str = allocate(array, 'i8', ALLOC_STACK);

    // 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, array.length, str);

    // The compiled pn_data_put_string takes the pn_bytes_t by reference not value.
    this._check(_pn_data_put_string(this._data, bytes));
    Runtime.stackRestore(sp);
};

/**
 * Puts a symbolic value. According to the AMQP 1.0 Specification Symbols are
 * values from a constrained domain. Although the set of possible domains is
 * open-ended, typically the both number and size of symbols in use for any
 * given application will be small, e.g. small enough that it is reasonable to
 * cache all the distinct values. Symbols are encoded as ASCII characters.
 * @method putSYMBOL
 * @memberof! proton.Data#
 * @param {proton.Data.Symbol|string} s the symbol name.
 */
_Data_['putSYMBOL'] = function(s) {
    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_symbol(data, pn_bytes(strlen(text), text));

    // First create an array from the JavaScript String using the intArrayFromString
    // helper function (from emscripten/src/preamble.js). We use this idiom in a
    // few places but here we create array as a separate var as we need its length.
    var array = intArrayFromString(s, true); // The true means don't add NULL.
    // Allocate temporary storage for the array on the emscripten stack.
    var str = allocate(array, 'i8', ALLOC_STACK);

    // 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, array.length, str);

    // The compiled pn_data_put_symbol takes the pn_bytes_t by reference not value.
    this._check(_pn_data_put_symbol(this._data, bytes));
    Runtime.stackRestore(sp);
};

/**
 * If the current node is a list node, return the number of elements,
 * otherwise return zero. List elements can be accessed by entering
 * the list.
 * <pre>
 *  var count = data.getLISTNODE();
 *  data.enter();
 *  for (var i = 0; i < count; i++) {
 *      var type = data.next();
 *      if (type === proton.Data.STRING) {
 *          console.log(data.getSTRING());
 *      }
 *  }
 *  data.exit();
 * </pre>
 * @method getLISTNODE
 * @memberof! proton.Data#
 * @returns {number} the number of elements if the current node is a list,
 *          zero otherwise.
 */
_Data_['getLISTNODE'] = function() {
    return _pn_data_get_list(this._data);
};

/**
 * If the current node is a map, return the number of child elements,
 * otherwise return zero. Key value pairs can be accessed by entering
 * the map.
 * <pre>
 *  var count = data.getMAPNODE();
 *  data.enter();
 *  for (var i = 0; i < count/2; i++) {
 *      var type = data.next();
 *      if (type === proton.Data.STRING) {
 *          console.log(data.getSTRING());
 *      }
 *  }
 *  data.exit();
 * </pre>
 * @method getMAPNODE
 * @memberof! proton.Data#
 * @returns {number} the number of elements if the current node is a list,
 *          zero otherwise.
 */
_Data_['getMAPNODE'] = function() {
    return _pn_data_get_map(this._data);
};

/**
 * If the current node is an array, return an object containing the tuple of the
 * element count, a boolean indicating whether the array is described, and the
 * type of each element, otherwise return {count: 0, described: false, type: null).
 * Array data can be accessed by entering the array.
 * <pre>
 *  // Read an array of strings with a symbolic descriptor
 *  var metadata = data.getARRAYNODE();
 *  var count = metadata.count;
 *  data.enter();
 *  data.next();
 *  console.log("Descriptor:" + data.getSYMBOL());
 *  for (var i = 0; i < count; i++) {
 *      var type = data.next();
 *      console.log("Element:" + data.getSTRING());
 *  }
 *  data.exit();
 * </pre>
 * @method getARRAYNODE
 * @memberof! proton.Data#
 * @returns {object} the tuple of the element count, a boolean indicating whether
 *          the array is described, and the type of each element.
 */
_Data_['getARRAYNODE'] = function() {
    var count = _pn_data_get_array(this._data);
    var described = (_pn_data_is_array_described(this._data) > 0);
    var type = _pn_data_get_array_type(this._data);
    type = (type == -1) ? null : type;
    return {'count': count, 'described': described, 'type': type};
};

/**
 * Checks if the current node is a described node. The descriptor and value may
 * be accessed by entering the described node.
 * <pre>
 *  // read a symbolically described string
 *  assert(data.isDESCRIBEDNODE()); // will error if the current node is not described
 *  data.enter();
 *  console.log(data.getSYMBOL());
 *  console.log(data.getSTRING());
 *  data.exit();
 * </pre>
 * @method isDESCRIBEDNODE
 * @memberof! proton.Data#
 * @returns {boolean} true iff the current node is a described, false otherwise.
 */
_Data_['isDESCRIBEDNODE'] = function() {
    return _pn_data_is_described(this._data);
};

/**
 * @method getNULL
 * @memberof! proton.Data#
 * @returns a null value.
 */
_Data_['getNULL'] = function() {
    return null;
};

/**
 * Checks if the current node is a null.
 * @method isNULL
 * @memberof! proton.Data#
 * @returns {boolean} true iff the current node is null.
 */
_Data_['isNULL'] = function() {
    return (_pn_data_is_null(this._data) > 0);
};

/**
 * @method getBOOL
 * @memberof! proton.Data#
 * @returns {boolean} a boolean value if the current node is a boolean, returns
 *          false otherwise.
 */
_Data_['getBOOL'] = function() {
    return (_pn_data_get_bool(this._data) > 0);
};

/**
 * @method getUBYTE
 * @memberof! proton.Data#
 * @returns {number} value if the current node is an unsigned byte, returns 0 otherwise.
 */
_Data_['getUBYTE'] = function() {
    return _pn_data_get_ubyte(this._data) & 0xFF; // & 0xFF converts to unsigned;
};

/**
 * @method getBYTE
 * @memberof! proton.Data#
 * @returns {number} value if the current node is a signed byte, returns 0 otherwise.
 */
_Data_['getBYTE'] = function() {
    return _pn_data_get_byte(this._data);
};

/**
 * @method getUSHORT
 * @memberof! proton.Data#
 * @returns {number} value if the current node is an unsigned short, returns 0 otherwise.
 */
_Data_['getUSHORT'] = function() {
    return _pn_data_get_ushort(this._data) & 0xFFFF; // & 0xFFFF converts to unsigned;
};

/**
 * @method getSHORT
 * @memberof! proton.Data#
 * @returns {number} value if the current node is a signed short, returns 0 otherwise.
 */
_Data_['getSHORT'] = function() {
    return _pn_data_get_short(this._data);
};

/**
 * @method getUINT
 * @memberof! proton.Data#
 * @returns {number} value if the current node is an unsigned int, returns 0 otherwise.
 */
_Data_['getUINT'] = function() {
    var value = _pn_data_get_uint(this._data);
    return (value > 0) ? value : 4294967296 + value; // 4294967296 == 2^32
};

/**
 * @method getINT
 * @memberof! proton.Data#
 * @returns {number} value if the current node is a signed int, returns 0 otherwise.
 */
_Data_['getINT'] = function() {
    return _pn_data_get_int(this._data);
};

/**
 * @method getCHAR
 * @memberof! proton.Data#
 * @returns {string} the character represented by the unicode value of the current node.
 */
_Data_['getCHAR'] = function() {
    return String.fromCharCode(_pn_data_get_char(this._data));
};

/**
 * Retrieve an unsigned long value. N.B. large values can suffer from a loss of
 * precision as JavaScript numbers are restricted to 64 bit double values.
 * @method getULONG
 * @memberof! proton.Data#
 * @returns {proton.Data.Long} value if the current node is an unsigned long, returns 0 otherwise.
 */
_Data_['getULONG'] = function() {
    var low = _pn_data_get_ulong(this._data);
    var high = Runtime.getTempRet0();
    var long = new Data.Long(low, high);
    long = long.toNumber();
    return (long >= 0) ? long : Data.Long.TWO_PWR_64_DBL_ + long;
};

/**
 * Retrieve a signed long value. N.B. large values can suffer from a loss of
 * precision as JavaScript numbers are restricted to 64 bit double values.
 * @method getLONG
 * @memberof! proton.Data#
 * @returns {proton.Data.Long} value if the current node is a signed long, returns 0 otherwise.
 */
_Data_['getLONG'] = function() {
    // Getting the long 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_data_get_long(this._data);
    var high = Runtime.getTempRet0();
    var long = new Data.Long(low, high);
    long = long.toNumber();
    return long;
};

/**
 * @method getTIMESTAMP
 * @memberof! proton.Data#
 * @returns {Date} a native JavaScript Date instance representing the timestamp.
 */
_Data_['getTIMESTAMP'] = 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_data_get_timestamp(this._data);
    var high = Runtime.getTempRet0();
    var long = new Data.Long(low, high);
    long = long.toNumber();
    return new Date(long);
};

/**
 * Retrieves a  float value. N.B. converting between floats and doubles is imprecise
 * so the resulting value might not quite be what you expect.
 * @method getFLOAT
 * @memberof! proton.Data#
 * @returns {number} value if the current node is a float, returns 0 otherwise.
 */
_Data_['getFLOAT'] = function() {
    return _pn_data_get_float(this._data);
};

/**
 * @method getDOUBLE
 * @memberof! proton.Data#
 * @returns {number} value if the current node is a double, returns 0 otherwise.
 */
_Data_['getDOUBLE'] = function() {
    return _pn_data_get_double(this._data);
};

/**
 * @method getDECIMAL32
 * @memberof! proton.Data#
 * @returns {number} value if the current node is a decimal32, returns 0 otherwise.
 */
_Data_['getDECIMAL32'] = function() {
console.log("getDECIMAL32 not properly implemented yet");
    return _pn_data_get_decimal32(this._data);
};

/**
 * @method getDECIMAL64
 * @memberof! proton.Data#
 * @returns {number} value if the current node is a decimal64, returns 0 otherwise.
 */
_Data_['getDECIMAL64'] = function() {
console.log("getDECIMAL64 not properly implemented yet");
    return _pn_data_get_decimal64(this._data);
};

/**
 * @method getDECIMAL128
 * @memberof! proton.Data#
 * @returns {number} value if the current node is a decimal128, returns 0 otherwise.
 */
_Data_['getDECIMAL128'] = function() {
console.log("getDECIMAL128 not properly implemented yet");
    return _pn_data_get_decimal128(this._data);
};

/**
 * @method getUUID
 * @memberof! proton.Data#
 * @returns {proton.Data.Uuid} value if the current node is a UUID, returns null otherwise.
 */
_Data_['getUUID'] = function() {
    var sp = Runtime.stackSave();

    // Here's the quirky bit, pn_data_get_uuid actually returns pn_uuid_t
    // *by value* but the low-level code handles this *by pointer* so we first
    // need to allocate 16 bytes storage for pn_uuid_t on the emscripten stack
    // and then we pass the pointer to that storage as the first parameter to the
    // compiled pn_data_get_uuid.
    var bytes = allocate(16, 'i8', ALLOC_STACK); // pn_uuid_t is 16 bytes.
    _pn_data_get_uuid(bytes, this._data);

    // Create a new UUID from the bytes
    var uuid = new Data['Uuid'](bytes);

    // Tidy up the memory that we allocated on emscripten's stack.
    Runtime.stackRestore(sp);

    return uuid;
};

/**
 * @method getBINARY
 * @memberof! proton.Data#
 * @returns {proton.Data.Binary} value if the current node is a Binary, returns null otherwise.
 */
_Data_['getBINARY'] = 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 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);

    // If _decodeBinaryAsString is set return the stringified form of the Binary.
    if (this._decodeBinaryAsString) {
        return binary.toString();
    } else {
        return binary;
    }
};

/**
 * Gets a unicode String value from the current node.
 * @method getSTRING
 * @memberof! proton.Data#
 * @returns {string} value if the current node is a String, returns "" otherwise.
 */
_Data_['getSTRING'] = 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 bytes = pn_data_get_string(data);

    // Here's the quirky bit, pn_data_get_string 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_string.
    var bytes = allocate(8, 'i8', ALLOC_STACK);
    _pn_data_get_string(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 native JavaScript String from the pn_bytes_t information.
    var string = Pointer_stringify(start, size);

    // Tidy up the memory that we allocated on emscripten's stack.
    Runtime.stackRestore(sp);

    return string;
};

/**
 * Gets a symbolic value. According to the AMQP 1.0 Specification Symbols are
 * values from a constrained domain. Although the set of possible domains is
 * open-ended, typically the both number and size of symbols in use for any
 * given application will be small, e.g. small enough that it is reasonable to
 * cache all the distinct values. Symbols are encoded as ASCII characters.
 * @method getSYMBOL
 * @memberof! proton.Data#
 * @returns {proton.Data.Symbol} value if the current node is a Symbol, returns "" otherwise.
 */
_Data_['getSYMBOL'] = 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 bytes = pn_data_get_symbol(data);

    // Here's the quirky bit, pn_data_get_symbol 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_symbol.
    var bytes = allocate(8, 'i8', ALLOC_STACK);
    _pn_data_get_symbol(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 native JavaScript String from the pn_bytes_t information.
    var string = Pointer_stringify(start, size);

    // Tidy up the memory that we allocated on emscripten's stack.
    Runtime.stackRestore(sp);

    return new Data['Symbol'](string);
};

/**
 * Performs a deep copy of the current {@link proton.Data} instance and returns it
 * @method copy
 * @memberof! proton.Data#
 * @returns {proton.Data} a copy of the current {@link proton.Data} instance.
 */
_Data_['copy'] = function() {
    var copy = new Data();
    this._check(_pn_data_copy(copy._data, this._data));
    return copy;
};

/**
 * Format the encoded AMQP Data into a string representation and return it.
 * @method format
 * @memberof! proton.Data#
 * @returns {string} a formatted string representation of the encoded Data.
 */
_Data_['format'] = function() {
    var sp = Runtime.stackSave();
    var sizeptr = allocate(4, 'i32', ALLOC_STACK);

    var size = 1024; // Pass by reference variable - need to use setValue to initialise it.
    while (true) {
        setValue(sizeptr, size, 'i32'); // Set pass by reference variable.
        var bytes = _malloc(size);   // Allocate storage from emscripten heap.
        var err = _pn_data_format(this._data, bytes, sizeptr);
        var size = getValue(sizeptr, 'i32'); // Dereference the real size value;

        if (err === Module['Error']['OVERFLOW']) {
            _free(bytes);
            size *= 2;
        } else {
            var string = Pointer_stringify(bytes, size);
            _free(bytes);
            // Tidy up the memory that we allocated on emscripten's stack.
            Runtime.stackRestore(sp);
            this._check(err)
            return string;
        }
    }
};

/**
 * Print the internal state of the {@link proton.Data} in human readable form.
 * TODO. This seems to "crash" if compound nodes such as DESCRIBED, MAP or LIST
 * are present in the tree, this is most likely a problem with the underlying C
 * implementation as all the other navigation and format methods work - need to
 * check by testing with some native C code.
 * @method dump
 * @memberof! proton.Data#
 */
_Data_['dump'] = function() {
    _pn_data_dump(this._data);
};

/**
 * Serialise a Native JavaScript Object into an AMQP Map.
 * @method putMAP
 * @memberof! proton.Data#
 * @param {object} object the Native JavaScript Object that we wish to serialise.
 */
_Data_['putMAP'] = function(object) {
    this['putMAPNODE']();
    this['enter']();
    for (var key in object) {
        if (object.hasOwnProperty(key)) {
            this['putObject'](key);
            this['putObject'](object[key]);
        }
    }
    this['exit']();
};

/**
 * Deserialise from an AMQP Map into a Native JavaScript Object.
 * @method getMAP
 * @memberof! proton.Data#
 * @returns {object} the deserialised Native JavaScript Object.
 */
_Data_['getMAP'] = function() {
    if (this['enter']()) {
        var result = {};
        while (this['next']()) {
            var key = this['getObject']();
            var value = null;
            if (this['next']()) {
                value = this['getObject']();
            }
            result[key] = value;
        }
        this['exit']();
        return result;
    }
};

/**
 * Serialise a Native JavaScript Array into an AMQP List.
 * @method putLIST
 * @memberof! proton.Data#
 * @param {Array} array the Native JavaScript Array that we wish to serialise.
 */
_Data_['putLIST'] = function(array) {
    this['putLISTNODE']();
    this['enter']();
    for (var i = 0, len = array.length; i < len; i++) {
        this['putObject'](array[i]);
    }
    this['exit']();
};

/**
 * Deserialise from an AMQP List into a Native JavaScript Array.
 * @method getLIST
 * @memberof! proton.Data#
 * @returns {Array} the deserialised Native JavaScript Array.
 */
_Data_['getLIST'] = function() {
    if (this['enter']()) {
        var result = [];
        while (this['next']()) {
            result.push(this['getObject']());
        }
        this['exit']();
        return result;
    }
};

/**
 * Serialise a proton.Data.Described into an AMQP Described.
 * @method putDESCRIBED
 * @memberof! proton.Data#
 * @param {proton.Data.Described} d the proton.Data.Described that we wish to serialise.
 */
_Data_['putDESCRIBED'] = function(d) {
    this['putDESCRIBEDNODE']();
    this['enter']();
    this['putObject'](d['descriptor']);
    this['putObject'](d['value']);
    this['exit']();
};

/**
 * Deserialise from an AMQP Described into a proton.Data.Described.
 * @method getDESCRIBED
 * @memberof! proton.Data#
 * @returns {proton.Data.Described} the deserialised proton.Data.Described.
 */
_Data_['getDESCRIBED'] = function() {
    if (this['enter']()) {
        this['next']();
        var descriptor = this['getObject']();
        this['next']();
        var value = this['getObject']();
        this['exit']();
        return new Data['Described'](value, descriptor);
    }
};

/**
 * Serialise a proton.Data.Array or JavaScript TypedArray into an AMQP Array.
 * @method putARRAY
 * @memberof! proton.Data#
 * @param {object} a the proton.Data.Array or TypedArray that we wish to serialise.
 */
_Data_['putARRAY'] = function(a) {
    var type = 1;
    var descriptor = 'TypedArray';
    var array = a;

    if (a instanceof Data['Array']) { // Array is a proton.Data.Array
        type = Data[a['type']]; // Find the integer type from its name string.
        descriptor = a['descriptor'];
        array = a['elements'];
    } else { // Array is a Native JavaScript TypedArray so work out the right type.
        if (a instanceof Int8Array) {
            type = Data['BYTE'];
        } else if (a instanceof Uint8Array || a instanceof Uint8ClampedArray) {
            type = Data['UBYTE'];
        } else if (a instanceof Int16Array) {
            type = Data['SHORT'];
        } else if (a instanceof Uint16Array) {
            type = Data['USHORT'];
        } else if (a instanceof Int32Array) {
            type = Data['INT'];
        } else if (a instanceof Uint32Array) {
            type = Data['UINT'];
        } else if (a instanceof Float32Array) {
            type = Data['FLOAT'];
        } else if (a instanceof Float64Array) {
            type = Data['DOUBLE'];
        }
    }

    var described = descriptor != null;

    this['putARRAYNODE'](described, type);
    this['enter']();
    if (described) {
        this['putObject'](descriptor);
    }
    var putter = 'put' + Data['TypeNames'][type];
    for (var i = 0, len = array.length; i < len; i++) {
        var value = array[i];
        value = (value instanceof Data.TypedNumber) ? value.value : value;
        this[putter](value);
    }
    this['exit']();
};

/**
 * Deserialise from an AMQP Array into a proton.Data.Array.
 * @method getARRAY
 * @memberof! proton.Data#
 * @returns {proton.Data.Array} the deserialised proton.Data.Array.
 */
_Data_['getARRAY'] = function() {
    var metadata = this['getARRAYNODE']();
    var count = metadata['count'];
    var described = metadata['described'];
    var type = metadata['type'];

    if (type === null) {
        return null;
    }

    var elements = null;
    if (typeof ArrayBuffer === 'function') {
        if (type === Data['BYTE']) {
            elements = new Int8Array(count);
        } else if (type === Data['UBYTE']) {
            elements = new Uint8Array(count);
        } else if (type === Data['SHORT']) {
            elements = new Int16Array(count);
        } else if (type === Data['USHORT']) {
            elements = new Uint16Array(count);
        } else if (type === Data['INT']) {
            elements = new Int32Array(count);
        } else if (type === Data['UINT']) {
            elements = new Uint32Array(count);
        } else if (type === Data['FLOAT']) {
            elements = new Float32Array(count);
        } else if (type === Data['DOUBLE']) {
            elements = new Float64Array(count);
        } else {
            elements = new Array(count);
        }
    } else {
        elements = new Array(count);
    }

    if (this['enter']()) {
        var descriptor; // Deliberately initialised as undefined not null.
        if (described) {
            this['next']();
            descriptor = this['getObject']();
        }

        for (var i = 0; i < count; i++) {
            this['next']();
            elements[i] = this['getObject']();
        }

        this['exit']();
        if (descriptor === 'TypedArray') {
            return elements;
        } else {
            return new Data['Array'](type, elements, descriptor);
        }
    }
};

/**
 * This method is the entry point for serialising native JavaScript types into
 * AMQP types. In an ideal world there would be a nice clean one to one mapping
 * and we could employ a look-up table but in practice the JavaScript type system
 * doesn't really lend itself to that and we have to employ extra checks,
 * heuristics and inferences.
 * @method putObject
 * @memberof! proton.Data#
 * @param {object} obj the JavaScript Object or primitive to be serialised.
 */
_Data_['putObject'] = function(obj) {
//console.log("Data.putObject " + obj);

    if (obj == null) { // == Checks for null and undefined.
        this['putNULL']();
    } else if (Data.isString(obj)) {
        var quoted = obj.match(/(['"])[^'"]*\1/);
        if (quoted) { // If a quoted string extract the string inside the quotes.
            obj = quoted[0].slice(1, -1);
        }
        this['putSTRING'](obj);
    } else if (obj instanceof Date) {
        this['putTIMESTAMP'](obj);
    } 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 (obj instanceof Data['Described']) {
        this['putDESCRIBED'](obj);
    } else if (obj instanceof Data['Array']) {
        this['putARRAY'](obj);
    } else if (obj.buffer && (typeof ArrayBuffer === 'function') && 
               obj.buffer instanceof ArrayBuffer) {
        this['putARRAY'](obj);
    } else if (obj instanceof Data.TypedNumber) { // Dot notation used for "protected" inner class.
        // Call the appropriate serialisation method based upon the numerical type.
        this['put' + obj.type](obj.value);
    } else if (Data.isNumber(obj)) {
        /**
         * This block encodes standard JavaScript numbers by making some inferences.
         * Encoding JavaScript numbers is surprisingly complex and has several
         * gotchas. The code here tries to do what the author believes is the
         * most "intuitive" encoding of the native JavaScript Number. It first
         * tries to identify if the number is an integer or floating point type
         * by checking if the number modulo 1 is zero (i.e. if it has a remainder
         * then it's a floating point type, which is encoded here as a double).
         * If the number is an integer type a test is made to check if it is a
         * 32 bit Int value. N.B. gotcha - JavaScript automagically coerces floating
         * point numbers with a zero Fractional Part into an *exact* integer so
         * numbers like 1.0, 100.0 etc. will be encoded as int or long here,
         * which is unlikely to be what is wanted. There's no easy "transparent"
         * way around this. The TypedNumber approach above allows applications
         * to express more explicitly what is required, for example (1.0).float()
         * (1).ubyte(), (5).long() etc.
         */
        if (obj % 1 === 0) {
            if (obj === (obj|0)) { // the |0 coerces to a 32 bit value.
                // 32 bit integer - encode as an INT.
                this['putINT'](obj);
            } else { // Longer than 32 bit - encode as a Long.
                this['putLONG'](obj);
            }
        } else { // Floating point type - encode as a Double
            this['putDOUBLE'](obj);
        }
    } else if (Data.isBoolean(obj)) {
        this['putBOOL'](obj);
    } else if (Data.isArray(obj)) { // Native JavaScript Array
        this['putLIST'](obj);
    } else {
        this['putMAP'](obj);
    }
};

/**
 * @method getObject
 * @memberof! proton.Data#
 * @returns {object} the JavaScript Object or primitive being deserialised.
 */
_Data_['getObject'] = function() {
    var type = Data['TypeNames'][this.type()];
    type = type ? type : 'NULL';
    var getter = 'get' + type;
    return this[getter]();
};

