|
|
"use strict";
var conversions = {}; module.exports = conversions;
function sign(x) { return x < 0 ? -1 : 1; }
function evenRound(x) { // Round x to the nearest integer, choosing the even integer if it lies halfway between two.
if ((x % 1) === 0.5 && (x & 1) === 0) { // [even number].5; round down (i.e. floor)
return Math.floor(x); } else { return Math.round(x); } }
function createNumberConversion(bitLength, typeOpts) { if (!typeOpts.unsigned) { --bitLength; } const lowerBound = typeOpts.unsigned ? 0 : -Math.pow(2, bitLength); const upperBound = Math.pow(2, bitLength) - 1;
const moduloVal = typeOpts.moduloBitLength ? Math.pow(2, typeOpts.moduloBitLength) : Math.pow(2, bitLength); const moduloBound = typeOpts.moduloBitLength ? Math.pow(2, typeOpts.moduloBitLength - 1) : Math.pow(2, bitLength - 1);
return function(V, opts) { if (!opts) opts = {};
let x = +V;
if (opts.enforceRange) { if (!Number.isFinite(x)) { throw new TypeError("Argument is not a finite number"); }
x = sign(x) * Math.floor(Math.abs(x)); if (x < lowerBound || x > upperBound) { throw new TypeError("Argument is not in byte range"); }
return x; }
if (!isNaN(x) && opts.clamp) { x = evenRound(x);
if (x < lowerBound) x = lowerBound; if (x > upperBound) x = upperBound; return x; }
if (!Number.isFinite(x) || x === 0) { return 0; }
x = sign(x) * Math.floor(Math.abs(x)); x = x % moduloVal;
if (!typeOpts.unsigned && x >= moduloBound) { return x - moduloVal; } else if (typeOpts.unsigned) { if (x < 0) { x += moduloVal; } else if (x === -0) { // don't return negative zero
return 0; } }
return x; } }
conversions["void"] = function () { return undefined; };
conversions["boolean"] = function (val) { return !!val; };
conversions["byte"] = createNumberConversion(8, { unsigned: false }); conversions["octet"] = createNumberConversion(8, { unsigned: true });
conversions["short"] = createNumberConversion(16, { unsigned: false }); conversions["unsigned short"] = createNumberConversion(16, { unsigned: true });
conversions["long"] = createNumberConversion(32, { unsigned: false }); conversions["unsigned long"] = createNumberConversion(32, { unsigned: true });
conversions["long long"] = createNumberConversion(32, { unsigned: false, moduloBitLength: 64 }); conversions["unsigned long long"] = createNumberConversion(32, { unsigned: true, moduloBitLength: 64 });
conversions["double"] = function (V) { const x = +V;
if (!Number.isFinite(x)) { throw new TypeError("Argument is not a finite floating-point value"); }
return x; };
conversions["unrestricted double"] = function (V) { const x = +V;
if (isNaN(x)) { throw new TypeError("Argument is NaN"); }
return x; };
// not quite valid, but good enough for JS
conversions["float"] = conversions["double"]; conversions["unrestricted float"] = conversions["unrestricted double"];
conversions["DOMString"] = function (V, opts) { if (!opts) opts = {};
if (opts.treatNullAsEmptyString && V === null) { return ""; }
return String(V); };
conversions["ByteString"] = function (V, opts) { const x = String(V); let c = undefined; for (let i = 0; (c = x.codePointAt(i)) !== undefined; ++i) { if (c > 255) { throw new TypeError("Argument is not a valid bytestring"); } }
return x; };
conversions["USVString"] = function (V) { const S = String(V); const n = S.length; const U = []; for (let i = 0; i < n; ++i) { const c = S.charCodeAt(i); if (c < 0xD800 || c > 0xDFFF) { U.push(String.fromCodePoint(c)); } else if (0xDC00 <= c && c <= 0xDFFF) { U.push(String.fromCodePoint(0xFFFD)); } else { if (i === n - 1) { U.push(String.fromCodePoint(0xFFFD)); } else { const d = S.charCodeAt(i + 1); if (0xDC00 <= d && d <= 0xDFFF) { const a = c & 0x3FF; const b = d & 0x3FF; U.push(String.fromCodePoint((2 << 15) + (2 << 9) * a + b)); ++i; } else { U.push(String.fromCodePoint(0xFFFD)); } } } }
return U.join(''); };
conversions["Date"] = function (V, opts) { if (!(V instanceof Date)) { throw new TypeError("Argument is not a Date object"); } if (isNaN(V)) { return undefined; }
return V; };
conversions["RegExp"] = function (V, opts) { if (!(V instanceof RegExp)) { V = new RegExp(V); }
return V; };
|