massive update, probably broken
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-go / node_modules / webidl-conversions / lib / index.js
1 "use strict";
2
3 var conversions = {};
4 module.exports = conversions;
5
6 function sign(x) {
7     return x < 0 ? -1 : 1;
8 }
9
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)
13         return Math.floor(x);
14     } else {
15         return Math.round(x);
16     }
17 }
18
19 function createNumberConversion(bitLength, typeOpts) {
20     if (!typeOpts.unsigned) {
21         --bitLength;
22     }
23     const lowerBound = typeOpts.unsigned ? 0 : -Math.pow(2, bitLength);
24     const upperBound = Math.pow(2, bitLength) - 1;
25
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);
28
29     return function(V, opts) {
30         if (!opts) opts = {};
31
32         let x = +V;
33
34         if (opts.enforceRange) {
35             if (!Number.isFinite(x)) {
36                 throw new TypeError("Argument is not a finite number");
37             }
38
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");
42             }
43
44             return x;
45         }
46
47         if (!isNaN(x) && opts.clamp) {
48             x = evenRound(x);
49
50             if (x < lowerBound) x = lowerBound;
51             if (x > upperBound) x = upperBound;
52             return x;
53         }
54
55         if (!Number.isFinite(x) || x === 0) {
56             return 0;
57         }
58
59         x = sign(x) * Math.floor(Math.abs(x));
60         x = x % moduloVal;
61
62         if (!typeOpts.unsigned && x >= moduloBound) {
63             return x - moduloVal;
64         } else if (typeOpts.unsigned) {
65             if (x < 0) {
66               x += moduloVal;
67             } else if (x === -0) { // don't return negative zero
68               return 0;
69             }
70         }
71
72         return x;
73     }
74 }
75
76 conversions["void"] = function () {
77     return undefined;
78 };
79
80 conversions["boolean"] = function (val) {
81     return !!val;
82 };
83
84 conversions["byte"] = createNumberConversion(8, { unsigned: false });
85 conversions["octet"] = createNumberConversion(8, { unsigned: true });
86
87 conversions["short"] = createNumberConversion(16, { unsigned: false });
88 conversions["unsigned short"] = createNumberConversion(16, { unsigned: true });
89
90 conversions["long"] = createNumberConversion(32, { unsigned: false });
91 conversions["unsigned long"] = createNumberConversion(32, { unsigned: true });
92
93 conversions["long long"] = createNumberConversion(32, { unsigned: false, moduloBitLength: 64 });
94 conversions["unsigned long long"] = createNumberConversion(32, { unsigned: true, moduloBitLength: 64 });
95
96 conversions["double"] = function (V) {
97     const x = +V;
98
99     if (!Number.isFinite(x)) {
100         throw new TypeError("Argument is not a finite floating-point value");
101     }
102
103     return x;
104 };
105
106 conversions["unrestricted double"] = function (V) {
107     const x = +V;
108
109     if (isNaN(x)) {
110         throw new TypeError("Argument is NaN");
111     }
112
113     return x;
114 };
115
116 // not quite valid, but good enough for JS
117 conversions["float"] = conversions["double"];
118 conversions["unrestricted float"] = conversions["unrestricted double"];
119
120 conversions["DOMString"] = function (V, opts) {
121     if (!opts) opts = {};
122
123     if (opts.treatNullAsEmptyString && V === null) {
124         return "";
125     }
126
127     return String(V);
128 };
129
130 conversions["ByteString"] = function (V, opts) {
131     const x = String(V);
132     let c = undefined;
133     for (let i = 0; (c = x.codePointAt(i)) !== undefined; ++i) {
134         if (c > 255) {
135             throw new TypeError("Argument is not a valid bytestring");
136         }
137     }
138
139     return x;
140 };
141
142 conversions["USVString"] = function (V) {
143     const S = String(V);
144     const n = S.length;
145     const U = [];
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));
152         } else {
153             if (i === n - 1) {
154                 U.push(String.fromCodePoint(0xFFFD));
155             } else {
156                 const d = S.charCodeAt(i + 1);
157                 if (0xDC00 <= d && d <= 0xDFFF) {
158                     const a = c & 0x3FF;
159                     const b = d & 0x3FF;
160                     U.push(String.fromCodePoint((2 << 15) + (2 << 9) * a + b));
161                     ++i;
162                 } else {
163                     U.push(String.fromCodePoint(0xFFFD));
164                 }
165             }
166         }
167     }
168
169     return U.join('');
170 };
171
172 conversions["Date"] = function (V, opts) {
173     if (!(V instanceof Date)) {
174         throw new TypeError("Argument is not a Date object");
175     }
176     if (isNaN(V)) {
177         return undefined;
178     }
179
180     return V;
181 };
182
183 conversions["RegExp"] = function (V, opts) {
184     if (!(V instanceof RegExp)) {
185         V = new RegExp(V);
186     }
187
188     return V;
189 };