4 module.exports = conversions;
10 function evenRound(x) {
11 // Round x to the nearest integer, choosing the even integer if it lies halfway between two.
12 if ((x % 1) === 0.5 && (x & 1) === 0) { // [even number].5; round down (i.e. floor)
19 function createNumberConversion(bitLength, typeOpts) {
20 if (!typeOpts.unsigned) {
23 const lowerBound = typeOpts.unsigned ? 0 : -Math.pow(2, bitLength);
24 const upperBound = Math.pow(2, bitLength) - 1;
26 const moduloVal = typeOpts.moduloBitLength ? Math.pow(2, typeOpts.moduloBitLength) : Math.pow(2, bitLength);
27 const moduloBound = typeOpts.moduloBitLength ? Math.pow(2, typeOpts.moduloBitLength - 1) : Math.pow(2, bitLength - 1);
29 return function(V, opts) {
34 if (opts.enforceRange) {
35 if (!Number.isFinite(x)) {
36 throw new TypeError("Argument is not a finite number");
39 x = sign(x) * Math.floor(Math.abs(x));
40 if (x < lowerBound || x > upperBound) {
41 throw new TypeError("Argument is not in byte range");
47 if (!isNaN(x) && opts.clamp) {
50 if (x < lowerBound) x = lowerBound;
51 if (x > upperBound) x = upperBound;
55 if (!Number.isFinite(x) || x === 0) {
59 x = sign(x) * Math.floor(Math.abs(x));
62 if (!typeOpts.unsigned && x >= moduloBound) {
64 } else if (typeOpts.unsigned) {
67 } else if (x === -0) { // don't return negative zero
76 conversions["void"] = function () {
80 conversions["boolean"] = function (val) {
84 conversions["byte"] = createNumberConversion(8, { unsigned: false });
85 conversions["octet"] = createNumberConversion(8, { unsigned: true });
87 conversions["short"] = createNumberConversion(16, { unsigned: false });
88 conversions["unsigned short"] = createNumberConversion(16, { unsigned: true });
90 conversions["long"] = createNumberConversion(32, { unsigned: false });
91 conversions["unsigned long"] = createNumberConversion(32, { unsigned: true });
93 conversions["long long"] = createNumberConversion(32, { unsigned: false, moduloBitLength: 64 });
94 conversions["unsigned long long"] = createNumberConversion(32, { unsigned: true, moduloBitLength: 64 });
96 conversions["double"] = function (V) {
99 if (!Number.isFinite(x)) {
100 throw new TypeError("Argument is not a finite floating-point value");
106 conversions["unrestricted double"] = function (V) {
110 throw new TypeError("Argument is NaN");
116 // not quite valid, but good enough for JS
117 conversions["float"] = conversions["double"];
118 conversions["unrestricted float"] = conversions["unrestricted double"];
120 conversions["DOMString"] = function (V, opts) {
121 if (!opts) opts = {};
123 if (opts.treatNullAsEmptyString && V === null) {
130 conversions["ByteString"] = function (V, opts) {
133 for (let i = 0; (c = x.codePointAt(i)) !== undefined; ++i) {
135 throw new TypeError("Argument is not a valid bytestring");
142 conversions["USVString"] = function (V) {
146 for (let i = 0; i < n; ++i) {
147 const c = S.charCodeAt(i);
148 if (c < 0xD800 || c > 0xDFFF) {
149 U.push(String.fromCodePoint(c));
150 } else if (0xDC00 <= c && c <= 0xDFFF) {
151 U.push(String.fromCodePoint(0xFFFD));
154 U.push(String.fromCodePoint(0xFFFD));
156 const d = S.charCodeAt(i + 1);
157 if (0xDC00 <= d && d <= 0xDFFF) {
160 U.push(String.fromCodePoint((2 << 15) + (2 << 9) * a + b));
163 U.push(String.fromCodePoint(0xFFFD));
172 conversions["Date"] = function (V, opts) {
173 if (!(V instanceof Date)) {
174 throw new TypeError("Argument is not a Date object");
183 conversions["RegExp"] = function (V, opts) {
184 if (!(V instanceof RegExp)) {