/**
* @copyright 2015 Tridium, Inc. All Rights Reserved.
* @author Gareth Johnson
*/
/**
* Defines {@link baja.Long}.
* @module baja/obj/Long
*/
define([ 'bajaScript/sys',
'bajaScript/baja/obj/Simple',
'bajaScript/baja/obj/numberUtil',
'bajaScript/baja/obj/objUtil' ], function (
baja,
Simple,
numberUtil,
objUtil) {
'use strict';
var subclass = baja.subclass,
callSuper = baja.callSuper,
strictArg = baja.strictArg,
integralToString = numberUtil.integralToString,
cacheDecode = objUtil.cacheDecode,
cacheEncode = objUtil.cacheEncode,
uncacheConstantEncodeDecode = objUtil.uncacheConstantEncodeDecode;
// TODO: Long can't really be represented in JavaScript. This needs more investigation
/**
* Represents a `baja:Long` in BajaScript.
*
* Boxes JavaScript `Number` to represent a `baja:Long`.
*
* When creating a `Simple`, always use the `make()` method instead of
* creating a new Object.
*
* @class
* @alias baja.Long
* @extends baja.Simple
*/
var Long = function Long(val) {
callSuper(Long, this, arguments);
this.$val = strictArg(val, Number);
};
subclass(Long, Simple);
/**
* Make a `Long`.
*
* @param {Number} val - the number value.
*
* @returns {baja.Long}
*/
Long.make = function (val) {
if (val === 0 || isNaN(val)) {
return Long.DEFAULT;
}
if (val >= Long.MAX_VALUE.valueOf() || val === Number.MAX_VALUE) {
return Long.MAX_VALUE;
}
if (val <= Long.MIN_VALUE.valueOf() || val === Number.MIN_VALUE) {
return Long.MIN_VALUE;
}
val = Math.floor(val);
if (val === 0) {
return Long.DEFAULT;
}
return new Long(val);
};
/**
* Make a `Long`.
*
* @param {Number} val - the number value.
*
* @returns {baja.Long}
*/
Long.prototype.make = function (val) {
return Long.make(val);
};
/**
* Decode a `Long` from a `String`.
*
* @param {String} str
*
* @returns {baja.Long}
*/
Long.prototype.decodeFromString = function (str) {
switch (str) {
case "0": return Long.DEFAULT;
// Min and max limits
case "max": return Long.MAX_VALUE;
case "min": return Long.MIN_VALUE;
default: return Long.make(Number(str));
}
};
/**
* Encode the `Long` (itself) to a `String`.
*
* @returns {String}
*/
Long.prototype.encodeToString = function () {
// Check range limits and NAN
if (isNaN(this.$val)) {
return "0";
}
if (this.$val >= Long.MAX_VALUE.valueOf()) {
return "max";
}
if (this.$val <= Long.MIN_VALUE.valueOf()) {
return "min";
}
return Math.floor(this.$val).toFixed(0);
};
/**
* Default `Long` instance.
* @type {baja.Long}
*/
Long.DEFAULT = uncacheConstantEncodeDecode(new Long(0));
/**
* `Long` Max Value.
* @type {baja.Long}
*/
Long.MAX_VALUE = uncacheConstantEncodeDecode(new Long(9223372036854775807));
/**
* `Long` Min Value.
* @type {baja.Long}
*/
Long.MIN_VALUE = uncacheConstantEncodeDecode(new Long(-9223372036854775808));
Long.prototype.decodeFromString = cacheDecode(Long.prototype.decodeFromString);
Long.prototype.encodeToString = cacheEncode(Long.prototype.encodeToString);
/**
* Return the data type symbol.
*
* Used for encoding this data type (primarily for facets).
*
* @returns {String}
*/
Long.prototype.getDataTypeSymbol = function () {
return "l";
};
/**
* Equality test.
*
* @param obj
*
* @returns {Boolean}
*/
Long.prototype.equals = function (obj) {
return objUtil.valueOfEquals(this, obj);
};
/**
* Return the `Number` encapsulated in the `Long` (itself).
*
* @returns {Number}
*/
Long.prototype.valueOf = function () {
return this.$val;
};
/**
* Returns the `String` representation of the `Long` (itself).
*
* @param {baja.Facets|Object} [cx] - used to specify formatting facets. The
* argument can also be an Object Literal.
*
* @param {Boolean} [cx.forceSign] - specifying 'true' will concatenate a '+'
* to the beginning of the number if positive.
*
* @param {Boolean} [cx.showSeparators] - include separators.
*
* @param {Number} [cx.radix] - specify the number base of the return string.
*
* @param {baja.Unit} [cx.units] - the baja Unit to apply to the return
* string.
*
* @param {baja.Enum|Number|String} [cx.unitConversion] - the
* `baja:UnitConversion` enum, an ordinal, or tag.
*
* @param {Number} [cx.zeroPad] - the minimum number of the whole-number
* digits to be displayed, filling in zeroes when necessary.
*
* @returns {String|Promise.<String>} returns a Promise if a cx is passed in.
*/
Long.prototype.toString = function (cx) {
if (cx) {
return integralToString(this, cx);
}
return this.encodeToString();
};
return Long;
});