Ejemplo n.º 1
0
FrameSerializer.prototype.serializeSignedLongLong = function(buffer, longLong) {
	if (longLong !== undefined) {
		if (typeof longLong === 'string') {
			buffer.write(longLong, buffer.used, 'hex');
		} else {
			moreints.writeInt64BE(buffer, longLong, buffer.used);
		}
		buffer.used += 8;
	} else {
		this.serializeSignedLongLong(buffer, 0);
	}
};
function encodeFieldValue(buffer, value, offset) {
    var start = offset;
    var type = typeof value, val = value;
    // A trapdoor for specifying a type, e.g., timestamp
    if (value && type === 'object' && value.hasOwnProperty('!')) {
        val = value.value;
        type = value['!'];
    }

    function tag(t) { buffer.write(t, offset); offset++; }

    switch (type) {
    case 'string': // no shortstr in field tables
        var len = Buffer.byteLength(val, 'utf8');
        tag('S');
        buffer.writeUInt32BE(len, offset); offset += 4;
        buffer.write(val, offset, 'utf8'); offset += len;
        break;
    case 'object':
        if (val === null) {
            tag('V');
        }
        else if (Array.isArray(val)) {
            tag('A');
            offset += encodeArray(buffer, val, offset);
        }
        else if (Buffer.isBuffer(val)) {
            tag('x');
            buffer.writeUInt32BE(val.length, offset); offset += 4;
            val.copy(buffer, offset); offset += val.length;
        }
        else {
            tag('F');
            offset += encodeTable(buffer, val, offset);
        }
        break;
    case 'boolean':
        tag('t');
        buffer.writeUInt8((val) ? 1 : 0, offset); offset++;
        break;
    case 'number':
        // Making assumptions about the kind of number (floating point
        // v integer, signed, unsigned, size) desired is dangerous in
        // general; however, in practice RabbitMQ uses only
        // longstrings and unsigned integers in its arguments, and
        // other clients generally conflate number types anyway. So
        // the only distinction we care about is floating point vs
        // integers, preferring integers since those can be promoted
        // if necessary. If floating point is required, we may as well
        // use double precision.
        if (isFloatingPoint(val)) {
            tag('d');
            buffer.writeDoubleBE(val, offset);
            offset += 8;
        }
        else { // only signed values are used in tables by RabbitMQ,
               // except for 'byte's which are only unsigned. (The
               // errata on the RabbitMQ website is wrong on this --
               // see rabbit_binary_generator.erl)
            if (val < 256 && val >= 0) {
                tag('b');
                buffer.writeUInt8(val, offset); offset++;
            }
            else if (val >= -0x8000 && val < 0x8000) { //  short
                tag('s');
                buffer.writeInt16BE(val, offset); offset += 2;
            }
            else if (val >= -0x80000000 && val < 0x80000000) { // int
                tag('I');
                buffer.writeInt32BE(val, offset); offset += 4;
            }
            else { // long
                tag('l');
                ints.writeInt64BE(buffer, val, offset); offset += 8;
            }
        }
        break;
    // Now for exotic types, those can only be denoted by using
    // `{'!': type, value: val}
    case 'timestamp':
        tag('T');
        ints.writeUInt64BE(buffer, val, offset); offset += 8;
        break;
    case 'float':
        tag('f');
        buffer.writeFloatBE(val, offset); offset += 4;
        break;
    case 'decimal':
        tag('D');
        if (val.hasOwnProperty('places') && val.hasOwnProperty('digits')
            && val.places >= 0 && val.places < 256) {
            buffer[offset] = val.places; offset++;
            buffer.writeUInt32BE(val.digits, offset); offset += 4;
        }
        else throw new TypeError(
            "Decimal value must be {'places': 0..255, 'digits': uint32}, " +
                "got " + JSON.stringify(val));
        break;
    default:
        throw new TypeError('Unknown type to encode: ' + type);
    }
    return offset - start;
}