bson 4.1.0 → 4.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/HISTORY.md +48 -1
  2. package/README.md +7 -9
  3. package/bower.json +1 -1
  4. package/bson.d.ts +986 -0
  5. package/dist/bson.browser.esm.js +7811 -5011
  6. package/dist/bson.browser.esm.js.map +1 -0
  7. package/dist/bson.browser.umd.js +7862 -5099
  8. package/dist/bson.browser.umd.js.map +1 -0
  9. package/dist/bson.bundle.js +8723 -9228
  10. package/dist/bson.bundle.js.map +1 -0
  11. package/dist/bson.esm.js +5728 -4951
  12. package/dist/bson.esm.js.map +1 -0
  13. package/etc/prepare.js +19 -0
  14. package/lib/binary.js +218 -398
  15. package/lib/binary.js.map +1 -0
  16. package/lib/bson.js +201 -240
  17. package/lib/bson.js.map +1 -0
  18. package/lib/code.js +41 -41
  19. package/lib/code.js.map +1 -0
  20. package/lib/constants.js +78 -203
  21. package/lib/constants.js.map +1 -0
  22. package/lib/db_ref.js +88 -81
  23. package/lib/db_ref.js.map +1 -0
  24. package/lib/decimal128.js +667 -777
  25. package/lib/decimal128.js.map +1 -0
  26. package/lib/double.js +68 -70
  27. package/lib/double.js.map +1 -0
  28. package/lib/ensure_buffer.js +22 -18
  29. package/lib/ensure_buffer.js.map +1 -0
  30. package/lib/extended_json.js +310 -321
  31. package/lib/extended_json.js.map +1 -0
  32. package/lib/float_parser.js +98 -104
  33. package/lib/float_parser.js.map +1 -0
  34. package/lib/int_32.js +50 -49
  35. package/lib/int_32.js.map +1 -0
  36. package/lib/long.js +881 -16
  37. package/lib/long.js.map +1 -0
  38. package/lib/map.js +130 -122
  39. package/lib/map.js.map +1 -0
  40. package/lib/max_key.js +28 -25
  41. package/lib/max_key.js.map +1 -0
  42. package/lib/min_key.js +28 -25
  43. package/lib/min_key.js.map +1 -0
  44. package/lib/objectid.js +300 -410
  45. package/lib/objectid.js.map +1 -0
  46. package/lib/parser/calculate_size.js +188 -224
  47. package/lib/parser/calculate_size.js.map +1 -0
  48. package/lib/parser/deserializer.js +545 -621
  49. package/lib/parser/deserializer.js.map +1 -0
  50. package/lib/parser/serializer.js +798 -923
  51. package/lib/parser/serializer.js.map +1 -0
  52. package/lib/parser/utils.js +92 -30
  53. package/lib/parser/utils.js.map +1 -0
  54. package/lib/regexp.js +61 -74
  55. package/lib/regexp.js.map +1 -0
  56. package/lib/symbol.js +45 -58
  57. package/lib/symbol.js.map +1 -0
  58. package/lib/timestamp.js +91 -95
  59. package/lib/timestamp.js.map +1 -0
  60. package/lib/uuid.js +48 -0
  61. package/lib/uuid.js.map +1 -0
  62. package/lib/validate_utf8.js +41 -42
  63. package/lib/validate_utf8.js.map +1 -0
  64. package/package.json +53 -31
  65. package/src/binary.ts +272 -0
  66. package/src/bson.ts +326 -0
  67. package/src/code.ts +61 -0
  68. package/src/constants.ts +104 -0
  69. package/src/db_ref.ts +119 -0
  70. package/src/decimal128.ts +803 -0
  71. package/src/double.ts +87 -0
  72. package/src/ensure_buffer.ts +26 -0
  73. package/src/extended_json.ts +395 -0
  74. package/src/float_parser.ts +152 -0
  75. package/src/int_32.ts +66 -0
  76. package/src/long.ts +1002 -0
  77. package/src/map.ts +139 -0
  78. package/src/max_key.ts +37 -0
  79. package/src/min_key.ts +37 -0
  80. package/src/objectid.ts +379 -0
  81. package/src/parser/calculate_size.ts +230 -0
  82. package/src/parser/deserializer.ts +655 -0
  83. package/src/parser/serializer.ts +1069 -0
  84. package/src/parser/utils.ts +93 -0
  85. package/src/regexp.ts +94 -0
  86. package/src/symbol.ts +59 -0
  87. package/src/timestamp.ts +108 -0
  88. package/src/uuid.ts +57 -0
  89. package/src/validate_utf8.ts +47 -0
  90. package/lib/fnv1a.js +0 -48
package/lib/decimal128.js CHANGED
@@ -1,807 +1,697 @@
1
- 'use strict';
2
-
3
- let Long = require('./long');
4
- const Buffer = require('buffer').Buffer;
5
-
6
- const PARSE_STRING_REGEXP = /^(\+|-)?(\d+|(\d*\.\d*))?(E|e)?([-+])?(\d+)?$/;
7
- const PARSE_INF_REGEXP = /^(\+|-)?(Infinity|inf)$/i;
8
- const PARSE_NAN_REGEXP = /^(\+|-)?NaN$/i;
9
-
10
- const EXPONENT_MAX = 6111;
11
- const EXPONENT_MIN = -6176;
12
- const EXPONENT_BIAS = 6176;
13
- const MAX_DIGITS = 34;
14
-
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Decimal128 = void 0;
4
+ var buffer_1 = require("buffer");
5
+ var long_1 = require("./long");
6
+ var PARSE_STRING_REGEXP = /^(\+|-)?(\d+|(\d*\.\d*))?(E|e)?([-+])?(\d+)?$/;
7
+ var PARSE_INF_REGEXP = /^(\+|-)?(Infinity|inf)$/i;
8
+ var PARSE_NAN_REGEXP = /^(\+|-)?NaN$/i;
9
+ var EXPONENT_MAX = 6111;
10
+ var EXPONENT_MIN = -6176;
11
+ var EXPONENT_BIAS = 6176;
12
+ var MAX_DIGITS = 34;
15
13
  // Nan value bits as 32 bit values (due to lack of longs)
16
- const NAN_BUFFER = [
17
- 0x7c,
18
- 0x00,
19
- 0x00,
20
- 0x00,
21
- 0x00,
22
- 0x00,
23
- 0x00,
24
- 0x00,
25
- 0x00,
26
- 0x00,
27
- 0x00,
28
- 0x00,
29
- 0x00,
30
- 0x00,
31
- 0x00,
32
- 0x00
14
+ var NAN_BUFFER = [
15
+ 0x7c,
16
+ 0x00,
17
+ 0x00,
18
+ 0x00,
19
+ 0x00,
20
+ 0x00,
21
+ 0x00,
22
+ 0x00,
23
+ 0x00,
24
+ 0x00,
25
+ 0x00,
26
+ 0x00,
27
+ 0x00,
28
+ 0x00,
29
+ 0x00,
30
+ 0x00
33
31
  ].reverse();
34
32
  // Infinity value bits 32 bit values (due to lack of longs)
35
- const INF_NEGATIVE_BUFFER = [
36
- 0xf8,
37
- 0x00,
38
- 0x00,
39
- 0x00,
40
- 0x00,
41
- 0x00,
42
- 0x00,
43
- 0x00,
44
- 0x00,
45
- 0x00,
46
- 0x00,
47
- 0x00,
48
- 0x00,
49
- 0x00,
50
- 0x00,
51
- 0x00
33
+ var INF_NEGATIVE_BUFFER = [
34
+ 0xf8,
35
+ 0x00,
36
+ 0x00,
37
+ 0x00,
38
+ 0x00,
39
+ 0x00,
40
+ 0x00,
41
+ 0x00,
42
+ 0x00,
43
+ 0x00,
44
+ 0x00,
45
+ 0x00,
46
+ 0x00,
47
+ 0x00,
48
+ 0x00,
49
+ 0x00
52
50
  ].reverse();
53
- const INF_POSITIVE_BUFFER = [
54
- 0x78,
55
- 0x00,
56
- 0x00,
57
- 0x00,
58
- 0x00,
59
- 0x00,
60
- 0x00,
61
- 0x00,
62
- 0x00,
63
- 0x00,
64
- 0x00,
65
- 0x00,
66
- 0x00,
67
- 0x00,
68
- 0x00,
69
- 0x00
51
+ var INF_POSITIVE_BUFFER = [
52
+ 0x78,
53
+ 0x00,
54
+ 0x00,
55
+ 0x00,
56
+ 0x00,
57
+ 0x00,
58
+ 0x00,
59
+ 0x00,
60
+ 0x00,
61
+ 0x00,
62
+ 0x00,
63
+ 0x00,
64
+ 0x00,
65
+ 0x00,
66
+ 0x00,
67
+ 0x00
70
68
  ].reverse();
71
-
72
- const EXPONENT_REGEX = /^([-+])?(\d+)?$/;
73
-
69
+ var EXPONENT_REGEX = /^([-+])?(\d+)?$/;
70
+ // Extract least significant 5 bits
71
+ var COMBINATION_MASK = 0x1f;
72
+ // Extract least significant 14 bits
73
+ var EXPONENT_MASK = 0x3fff;
74
+ // Value of combination field for Inf
75
+ var COMBINATION_INFINITY = 30;
76
+ // Value of combination field for NaN
77
+ var COMBINATION_NAN = 31;
74
78
  // Detect if the value is a digit
75
79
  function isDigit(value) {
76
- return !isNaN(parseInt(value, 10));
80
+ return !isNaN(parseInt(value, 10));
77
81
  }
78
-
79
82
  // Divide two uint128 values
80
83
  function divideu128(value) {
81
- const DIVISOR = Long.fromNumber(1000 * 1000 * 1000);
82
- let _rem = Long.fromNumber(0);
83
-
84
- if (!value.parts[0] && !value.parts[1] && !value.parts[2] && !value.parts[3]) {
84
+ var DIVISOR = long_1.Long.fromNumber(1000 * 1000 * 1000);
85
+ var _rem = long_1.Long.fromNumber(0);
86
+ if (!value.parts[0] && !value.parts[1] && !value.parts[2] && !value.parts[3]) {
87
+ return { quotient: value, rem: _rem };
88
+ }
89
+ for (var i = 0; i <= 3; i++) {
90
+ // Adjust remainder to match value of next dividend
91
+ _rem = _rem.shiftLeft(32);
92
+ // Add the divided to _rem
93
+ _rem = _rem.add(new long_1.Long(value.parts[i], 0));
94
+ value.parts[i] = _rem.div(DIVISOR).low;
95
+ _rem = _rem.modulo(DIVISOR);
96
+ }
85
97
  return { quotient: value, rem: _rem };
86
- }
87
-
88
- for (let i = 0; i <= 3; i++) {
89
- // Adjust remainder to match value of next dividend
90
- _rem = _rem.shiftLeft(32);
91
- // Add the divided to _rem
92
- _rem = _rem.add(new Long(value.parts[i], 0));
93
- value.parts[i] = _rem.div(DIVISOR).low;
94
- _rem = _rem.modulo(DIVISOR);
95
- }
96
-
97
- return { quotient: value, rem: _rem };
98
98
  }
99
-
100
99
  // Multiply two Long values and return the 128 bit value
101
100
  function multiply64x2(left, right) {
102
- if (!left && !right) {
103
- return { high: Long.fromNumber(0), low: Long.fromNumber(0) };
104
- }
105
-
106
- const leftHigh = left.shiftRightUnsigned(32);
107
- const leftLow = new Long(left.getLowBits(), 0);
108
- const rightHigh = right.shiftRightUnsigned(32);
109
- const rightLow = new Long(right.getLowBits(), 0);
110
-
111
- let productHigh = leftHigh.multiply(rightHigh);
112
- let productMid = leftHigh.multiply(rightLow);
113
- let productMid2 = leftLow.multiply(rightHigh);
114
- let productLow = leftLow.multiply(rightLow);
115
-
116
- productHigh = productHigh.add(productMid.shiftRightUnsigned(32));
117
- productMid = new Long(productMid.getLowBits(), 0)
118
- .add(productMid2)
119
- .add(productLow.shiftRightUnsigned(32));
120
-
121
- productHigh = productHigh.add(productMid.shiftRightUnsigned(32));
122
- productLow = productMid.shiftLeft(32).add(new Long(productLow.getLowBits(), 0));
123
-
124
- // Return the 128 bit result
125
- return { high: productHigh, low: productLow };
101
+ if (!left && !right) {
102
+ return { high: long_1.Long.fromNumber(0), low: long_1.Long.fromNumber(0) };
103
+ }
104
+ var leftHigh = left.shiftRightUnsigned(32);
105
+ var leftLow = new long_1.Long(left.getLowBits(), 0);
106
+ var rightHigh = right.shiftRightUnsigned(32);
107
+ var rightLow = new long_1.Long(right.getLowBits(), 0);
108
+ var productHigh = leftHigh.multiply(rightHigh);
109
+ var productMid = leftHigh.multiply(rightLow);
110
+ var productMid2 = leftLow.multiply(rightHigh);
111
+ var productLow = leftLow.multiply(rightLow);
112
+ productHigh = productHigh.add(productMid.shiftRightUnsigned(32));
113
+ productMid = new long_1.Long(productMid.getLowBits(), 0)
114
+ .add(productMid2)
115
+ .add(productLow.shiftRightUnsigned(32));
116
+ productHigh = productHigh.add(productMid.shiftRightUnsigned(32));
117
+ productLow = productMid.shiftLeft(32).add(new long_1.Long(productLow.getLowBits(), 0));
118
+ // Return the 128 bit result
119
+ return { high: productHigh, low: productLow };
126
120
  }
127
-
128
121
  function lessThan(left, right) {
129
- // Make values unsigned
130
- const uhleft = left.high >>> 0;
131
- const uhright = right.high >>> 0;
132
-
133
- // Compare high bits first
134
- if (uhleft < uhright) {
135
- return true;
136
- } else if (uhleft === uhright) {
137
- const ulleft = left.low >>> 0;
138
- const ulright = right.low >>> 0;
139
- if (ulleft < ulright) return true;
140
- }
141
-
142
- return false;
122
+ // Make values unsigned
123
+ var uhleft = left.high >>> 0;
124
+ var uhright = right.high >>> 0;
125
+ // Compare high bits first
126
+ if (uhleft < uhright) {
127
+ return true;
128
+ }
129
+ else if (uhleft === uhright) {
130
+ var ulleft = left.low >>> 0;
131
+ var ulright = right.low >>> 0;
132
+ if (ulleft < ulright)
133
+ return true;
134
+ }
135
+ return false;
143
136
  }
144
-
145
137
  function invalidErr(string, message) {
146
- throw new TypeError(`"${string}" is not a valid Decimal128 string - ${message}`);
138
+ throw new TypeError("\"" + string + "\" is not a valid Decimal128 string - " + message);
147
139
  }
148
-
149
140
  /**
150
141
  * A class representation of the BSON Decimal128 type.
151
- *
152
- * @class
153
- * @param {Buffer} bytes a buffer containing the raw Decimal128 bytes.
154
- * @return {Double}
155
- */
156
- function Decimal128(bytes) {
157
- this.bytes = bytes;
158
- }
159
-
160
- /**
161
- * Create a Decimal128 instance from a string representation
162
- *
163
- * @method
164
- * @param {string} string a numeric string representation.
165
- * @return {Decimal128} returns a Decimal128 instance.
142
+ * @public
166
143
  */
167
- Decimal128.fromString = function(string) {
168
- // Parse state tracking
169
- let isNegative = false;
170
- let sawRadix = false;
171
- let foundNonZero = false;
172
-
173
- // Total number of significant digits (no leading or trailing zero)
174
- let significantDigits = 0;
175
- // Total number of significand digits read
176
- let nDigitsRead = 0;
177
- // Total number of digits (no leading zeros)
178
- let nDigits = 0;
179
- // The number of the digits after radix
180
- let radixPosition = 0;
181
- // The index of the first non-zero in *str*
182
- let firstNonZero = 0;
183
-
184
- // Digits Array
185
- const digits = [0];
186
- // The number of digits in digits
187
- let nDigitsStored = 0;
188
- // Insertion pointer for digits
189
- let digitsInsert = 0;
190
- // The index of the first non-zero digit
191
- let firstDigit = 0;
192
- // The index of the last digit
193
- let lastDigit = 0;
194
-
195
- // Exponent
196
- let exponent = 0;
197
- // loop index over array
198
- let i = 0;
199
- // The high 17 digits of the significand
200
- let significandHigh = [0, 0];
201
- // The low 17 digits of the significand
202
- let significandLow = [0, 0];
203
- // The biased exponent
204
- let biasedExponent = 0;
205
-
206
- // Read index
207
- let index = 0;
208
-
209
- // Naively prevent against REDOS attacks.
210
- // TODO: implementing a custom parsing for this, or refactoring the regex would yield
211
- // further gains.
212
- if (string.length >= 7000) {
213
- throw new TypeError('' + string + ' not a valid Decimal128 string');
214
- }
215
-
216
- // Results
217
- const stringMatch = string.match(PARSE_STRING_REGEXP);
218
- const infMatch = string.match(PARSE_INF_REGEXP);
219
- const nanMatch = string.match(PARSE_NAN_REGEXP);
220
-
221
- // Validate the string
222
- if ((!stringMatch && !infMatch && !nanMatch) || string.length === 0) {
223
- throw new TypeError('' + string + ' not a valid Decimal128 string');
224
- }
225
-
226
- if (stringMatch) {
227
- // full_match = stringMatch[0]
228
- // sign = stringMatch[1]
229
-
230
- let unsignedNumber = stringMatch[2];
231
- // stringMatch[3] is undefined if a whole number (ex "1", 12")
232
- // but defined if a number w/ decimal in it (ex "1.0, 12.2")
233
-
234
- let e = stringMatch[4];
235
- let expSign = stringMatch[5];
236
- let expNumber = stringMatch[6];
237
-
238
- // they provided e, but didn't give an exponent number. for ex "1e"
239
- if (e && expNumber === undefined) invalidErr(string, 'missing exponent power');
240
-
241
- // they provided e, but didn't give a number before it. for ex "e1"
242
- if (e && unsignedNumber === undefined) invalidErr(string, 'missing exponent base');
243
-
244
- if (e === undefined && (expSign || expNumber)) {
245
- invalidErr(string, 'missing e before exponent');
246
- }
247
- }
248
-
249
- // Get the negative or positive sign
250
- if (string[index] === '+' || string[index] === '-') {
251
- isNegative = string[index++] === '-';
252
- }
253
-
254
- // Check if user passed Infinity or NaN
255
- if (!isDigit(string[index]) && string[index] !== '.') {
256
- if (string[index] === 'i' || string[index] === 'I') {
257
- return new Decimal128(Buffer.from(isNegative ? INF_NEGATIVE_BUFFER : INF_POSITIVE_BUFFER));
258
- } else if (string[index] === 'N') {
259
- return new Decimal128(Buffer.from(NAN_BUFFER));
144
+ var Decimal128 = /** @class */ (function () {
145
+ /** @param bytes - a buffer containing the raw Decimal128 bytes in little endian order */
146
+ function Decimal128(bytes) {
147
+ if (!(this instanceof Decimal128))
148
+ return new Decimal128(bytes);
149
+ this.bytes = bytes;
260
150
  }
261
- }
262
-
263
- // Read all the digits
264
- while (isDigit(string[index]) || string[index] === '.') {
265
- if (string[index] === '.') {
266
- if (sawRadix) invalidErr(string, 'contains multiple periods');
267
-
268
- sawRadix = true;
269
- index = index + 1;
270
- continue;
271
- }
272
-
273
- if (nDigitsStored < 34) {
274
- if (string[index] !== '0' || foundNonZero) {
275
- if (!foundNonZero) {
276
- firstNonZero = nDigitsRead;
151
+ /**
152
+ * Create a Decimal128 instance from a string representation
153
+ *
154
+ * @param representation - a numeric string representation.
155
+ */
156
+ Decimal128.fromString = function (representation) {
157
+ // Parse state tracking
158
+ var isNegative = false;
159
+ var sawRadix = false;
160
+ var foundNonZero = false;
161
+ // Total number of significant digits (no leading or trailing zero)
162
+ var significantDigits = 0;
163
+ // Total number of significand digits read
164
+ var nDigitsRead = 0;
165
+ // Total number of digits (no leading zeros)
166
+ var nDigits = 0;
167
+ // The number of the digits after radix
168
+ var radixPosition = 0;
169
+ // The index of the first non-zero in *str*
170
+ var firstNonZero = 0;
171
+ // Digits Array
172
+ var digits = [0];
173
+ // The number of digits in digits
174
+ var nDigitsStored = 0;
175
+ // Insertion pointer for digits
176
+ var digitsInsert = 0;
177
+ // The index of the first non-zero digit
178
+ var firstDigit = 0;
179
+ // The index of the last digit
180
+ var lastDigit = 0;
181
+ // Exponent
182
+ var exponent = 0;
183
+ // loop index over array
184
+ var i = 0;
185
+ // The high 17 digits of the significand
186
+ var significandHigh = new long_1.Long(0, 0);
187
+ // The low 17 digits of the significand
188
+ var significandLow = new long_1.Long(0, 0);
189
+ // The biased exponent
190
+ var biasedExponent = 0;
191
+ // Read index
192
+ var index = 0;
193
+ // Naively prevent against REDOS attacks.
194
+ // TODO: implementing a custom parsing for this, or refactoring the regex would yield
195
+ // further gains.
196
+ if (representation.length >= 7000) {
197
+ throw new TypeError('' + representation + ' not a valid Decimal128 string');
277
198
  }
278
-
279
- foundNonZero = true;
280
-
281
- // Only store 34 digits
282
- digits[digitsInsert++] = parseInt(string[index], 10);
283
- nDigitsStored = nDigitsStored + 1;
284
- }
285
- }
286
-
287
- if (foundNonZero) nDigits = nDigits + 1;
288
- if (sawRadix) radixPosition = radixPosition + 1;
289
-
290
- nDigitsRead = nDigitsRead + 1;
291
- index = index + 1;
292
- }
293
-
294
- if (sawRadix && !nDigitsRead) throw new TypeError('' + string + ' not a valid Decimal128 string');
295
-
296
- // Read exponent if exists
297
- if (string[index] === 'e' || string[index] === 'E') {
298
- // Read exponent digits
299
- const match = string.substr(++index).match(EXPONENT_REGEX);
300
-
301
- // No digits read
302
- if (!match || !match[2]) return new Decimal128(Buffer.from(NAN_BUFFER));
303
-
304
- // Get exponent
305
- exponent = parseInt(match[0], 10);
306
-
307
- // Adjust the index
308
- index = index + match[0].length;
309
- }
310
-
311
- // Return not a number
312
- if (string[index]) return new Decimal128(Buffer.from(NAN_BUFFER));
313
-
314
- // Done reading input
315
- // Find first non-zero digit in digits
316
- firstDigit = 0;
317
-
318
- if (!nDigitsStored) {
319
- firstDigit = 0;
320
- lastDigit = 0;
321
- digits[0] = 0;
322
- nDigits = 1;
323
- nDigitsStored = 1;
324
- significantDigits = 0;
325
- } else {
326
- lastDigit = nDigitsStored - 1;
327
- significantDigits = nDigits;
328
- if (significantDigits !== 1) {
329
- while (string[firstNonZero + significantDigits - 1] === '0') {
330
- significantDigits = significantDigits - 1;
331
- }
332
- }
333
- }
334
-
335
- // Normalization of exponent
336
- // Correct exponent based on radix position, and shift significand as needed
337
- // to represent user input
338
-
339
- // Overflow prevention
340
- if (exponent <= radixPosition && radixPosition - exponent > 1 << 14) {
341
- exponent = EXPONENT_MIN;
342
- } else {
343
- exponent = exponent - radixPosition;
344
- }
345
-
346
- // Attempt to normalize the exponent
347
- while (exponent > EXPONENT_MAX) {
348
- // Shift exponent to significand and decrease
349
- lastDigit = lastDigit + 1;
350
-
351
- if (lastDigit - firstDigit > MAX_DIGITS) {
352
- // Check if we have a zero then just hard clamp, otherwise fail
353
- const digitsString = digits.join('');
354
- if (digitsString.match(/^0+$/)) {
355
- exponent = EXPONENT_MAX;
356
- break;
357
- }
358
-
359
- invalidErr(string, 'overflow');
360
- }
361
- exponent = exponent - 1;
362
- }
363
-
364
- while (exponent < EXPONENT_MIN || nDigitsStored < nDigits) {
365
- // Shift last digit. can only do this if < significant digits than # stored.
366
- if (lastDigit === 0 && significantDigits < nDigitsStored) {
367
- exponent = EXPONENT_MIN;
368
- significantDigits = 0;
369
- break;
370
- }
371
-
372
- if (nDigitsStored < nDigits) {
373
- // adjust to match digits not stored
374
- nDigits = nDigits - 1;
375
- } else {
376
- // adjust to round
377
- lastDigit = lastDigit - 1;
378
- }
379
-
380
- if (exponent < EXPONENT_MAX) {
381
- exponent = exponent + 1;
382
- } else {
383
- // Check if we have a zero then just hard clamp, otherwise fail
384
- const digitsString = digits.join('');
385
- if (digitsString.match(/^0+$/)) {
386
- exponent = EXPONENT_MAX;
387
- break;
388
- }
389
- invalidErr(string, 'overflow');
390
- }
391
- }
392
-
393
- // Round
394
- // We've normalized the exponent, but might still need to round.
395
- if (lastDigit - firstDigit + 1 < significantDigits) {
396
- let endOfString = nDigitsRead;
397
-
398
- // If we have seen a radix point, 'string' is 1 longer than we have
399
- // documented with ndigits_read, so inc the position of the first nonzero
400
- // digit and the position that digits are read to.
401
- if (sawRadix) {
402
- firstNonZero = firstNonZero + 1;
403
- endOfString = endOfString + 1;
404
- }
405
- // if negative, we need to increment again to account for - sign at start.
406
- if (isNegative) {
407
- firstNonZero = firstNonZero + 1;
408
- endOfString = endOfString + 1;
409
- }
410
-
411
- const roundDigit = parseInt(string[firstNonZero + lastDigit + 1], 10);
412
- let roundBit = 0;
413
-
414
- if (roundDigit >= 5) {
415
- roundBit = 1;
416
- if (roundDigit === 5) {
417
- roundBit = digits[lastDigit] % 2 === 1;
418
- for (i = firstNonZero + lastDigit + 2; i < endOfString; i++) {
419
- if (parseInt(string[i], 10)) {
420
- roundBit = 1;
421
- break;
422
- }
199
+ // Results
200
+ var stringMatch = representation.match(PARSE_STRING_REGEXP);
201
+ var infMatch = representation.match(PARSE_INF_REGEXP);
202
+ var nanMatch = representation.match(PARSE_NAN_REGEXP);
203
+ // Validate the string
204
+ if ((!stringMatch && !infMatch && !nanMatch) || representation.length === 0) {
205
+ throw new TypeError('' + representation + ' not a valid Decimal128 string');
423
206
  }
424
- }
425
- }
426
-
427
- if (roundBit) {
428
- let dIdx = lastDigit;
429
-
430
- for (; dIdx >= 0; dIdx--) {
431
- if (++digits[dIdx] > 9) {
432
- digits[dIdx] = 0;
433
-
434
- // overflowed most significant digit
435
- if (dIdx === 0) {
207
+ if (stringMatch) {
208
+ // full_match = stringMatch[0]
209
+ // sign = stringMatch[1]
210
+ var unsignedNumber = stringMatch[2];
211
+ // stringMatch[3] is undefined if a whole number (ex "1", 12")
212
+ // but defined if a number w/ decimal in it (ex "1.0, 12.2")
213
+ var e = stringMatch[4];
214
+ var expSign = stringMatch[5];
215
+ var expNumber = stringMatch[6];
216
+ // they provided e, but didn't give an exponent number. for ex "1e"
217
+ if (e && expNumber === undefined)
218
+ invalidErr(representation, 'missing exponent power');
219
+ // they provided e, but didn't give a number before it. for ex "e1"
220
+ if (e && unsignedNumber === undefined)
221
+ invalidErr(representation, 'missing exponent base');
222
+ if (e === undefined && (expSign || expNumber)) {
223
+ invalidErr(representation, 'missing e before exponent');
224
+ }
225
+ }
226
+ // Get the negative or positive sign
227
+ if (representation[index] === '+' || representation[index] === '-') {
228
+ isNegative = representation[index++] === '-';
229
+ }
230
+ // Check if user passed Infinity or NaN
231
+ if (!isDigit(representation[index]) && representation[index] !== '.') {
232
+ if (representation[index] === 'i' || representation[index] === 'I') {
233
+ return new Decimal128(buffer_1.Buffer.from(isNegative ? INF_NEGATIVE_BUFFER : INF_POSITIVE_BUFFER));
234
+ }
235
+ else if (representation[index] === 'N') {
236
+ return new Decimal128(buffer_1.Buffer.from(NAN_BUFFER));
237
+ }
238
+ }
239
+ // Read all the digits
240
+ while (isDigit(representation[index]) || representation[index] === '.') {
241
+ if (representation[index] === '.') {
242
+ if (sawRadix)
243
+ invalidErr(representation, 'contains multiple periods');
244
+ sawRadix = true;
245
+ index = index + 1;
246
+ continue;
247
+ }
248
+ if (nDigitsStored < 34) {
249
+ if (representation[index] !== '0' || foundNonZero) {
250
+ if (!foundNonZero) {
251
+ firstNonZero = nDigitsRead;
252
+ }
253
+ foundNonZero = true;
254
+ // Only store 34 digits
255
+ digits[digitsInsert++] = parseInt(representation[index], 10);
256
+ nDigitsStored = nDigitsStored + 1;
257
+ }
258
+ }
259
+ if (foundNonZero)
260
+ nDigits = nDigits + 1;
261
+ if (sawRadix)
262
+ radixPosition = radixPosition + 1;
263
+ nDigitsRead = nDigitsRead + 1;
264
+ index = index + 1;
265
+ }
266
+ if (sawRadix && !nDigitsRead)
267
+ throw new TypeError('' + representation + ' not a valid Decimal128 string');
268
+ // Read exponent if exists
269
+ if (representation[index] === 'e' || representation[index] === 'E') {
270
+ // Read exponent digits
271
+ var match = representation.substr(++index).match(EXPONENT_REGEX);
272
+ // No digits read
273
+ if (!match || !match[2])
274
+ return new Decimal128(buffer_1.Buffer.from(NAN_BUFFER));
275
+ // Get exponent
276
+ exponent = parseInt(match[0], 10);
277
+ // Adjust the index
278
+ index = index + match[0].length;
279
+ }
280
+ // Return not a number
281
+ if (representation[index])
282
+ return new Decimal128(buffer_1.Buffer.from(NAN_BUFFER));
283
+ // Done reading input
284
+ // Find first non-zero digit in digits
285
+ firstDigit = 0;
286
+ if (!nDigitsStored) {
287
+ firstDigit = 0;
288
+ lastDigit = 0;
289
+ digits[0] = 0;
290
+ nDigits = 1;
291
+ nDigitsStored = 1;
292
+ significantDigits = 0;
293
+ }
294
+ else {
295
+ lastDigit = nDigitsStored - 1;
296
+ significantDigits = nDigits;
297
+ if (significantDigits !== 1) {
298
+ while (representation[firstNonZero + significantDigits - 1] === '0') {
299
+ significantDigits = significantDigits - 1;
300
+ }
301
+ }
302
+ }
303
+ // Normalization of exponent
304
+ // Correct exponent based on radix position, and shift significand as needed
305
+ // to represent user input
306
+ // Overflow prevention
307
+ if (exponent <= radixPosition && radixPosition - exponent > 1 << 14) {
308
+ exponent = EXPONENT_MIN;
309
+ }
310
+ else {
311
+ exponent = exponent - radixPosition;
312
+ }
313
+ // Attempt to normalize the exponent
314
+ while (exponent > EXPONENT_MAX) {
315
+ // Shift exponent to significand and decrease
316
+ lastDigit = lastDigit + 1;
317
+ if (lastDigit - firstDigit > MAX_DIGITS) {
318
+ // Check if we have a zero then just hard clamp, otherwise fail
319
+ var digitsString = digits.join('');
320
+ if (digitsString.match(/^0+$/)) {
321
+ exponent = EXPONENT_MAX;
322
+ break;
323
+ }
324
+ invalidErr(representation, 'overflow');
325
+ }
326
+ exponent = exponent - 1;
327
+ }
328
+ while (exponent < EXPONENT_MIN || nDigitsStored < nDigits) {
329
+ // Shift last digit. can only do this if < significant digits than # stored.
330
+ if (lastDigit === 0 && significantDigits < nDigitsStored) {
331
+ exponent = EXPONENT_MIN;
332
+ significantDigits = 0;
333
+ break;
334
+ }
335
+ if (nDigitsStored < nDigits) {
336
+ // adjust to match digits not stored
337
+ nDigits = nDigits - 1;
338
+ }
339
+ else {
340
+ // adjust to round
341
+ lastDigit = lastDigit - 1;
342
+ }
436
343
  if (exponent < EXPONENT_MAX) {
437
- exponent = exponent + 1;
438
- digits[dIdx] = 1;
439
- } else {
440
- return new Decimal128(
441
- Buffer.from(isNegative ? INF_NEGATIVE_BUFFER : INF_POSITIVE_BUFFER)
442
- );
344
+ exponent = exponent + 1;
345
+ }
346
+ else {
347
+ // Check if we have a zero then just hard clamp, otherwise fail
348
+ var digitsString = digits.join('');
349
+ if (digitsString.match(/^0+$/)) {
350
+ exponent = EXPONENT_MAX;
351
+ break;
352
+ }
353
+ invalidErr(representation, 'overflow');
443
354
  }
444
- }
445
355
  }
446
- }
447
- }
448
- }
449
-
450
- // Encode significand
451
- // The high 17 digits of the significand
452
- significandHigh = Long.fromNumber(0);
453
- // The low 17 digits of the significand
454
- significandLow = Long.fromNumber(0);
455
-
456
- // read a zero
457
- if (significantDigits === 0) {
458
- significandHigh = Long.fromNumber(0);
459
- significandLow = Long.fromNumber(0);
460
- } else if (lastDigit - firstDigit < 17) {
461
- let dIdx = firstDigit;
462
- significandLow = Long.fromNumber(digits[dIdx++]);
463
- significandHigh = new Long(0, 0);
464
-
465
- for (; dIdx <= lastDigit; dIdx++) {
466
- significandLow = significandLow.multiply(Long.fromNumber(10));
467
- significandLow = significandLow.add(Long.fromNumber(digits[dIdx]));
468
- }
469
- } else {
470
- let dIdx = firstDigit;
471
- significandHigh = Long.fromNumber(digits[dIdx++]);
472
-
473
- for (; dIdx <= lastDigit - 17; dIdx++) {
474
- significandHigh = significandHigh.multiply(Long.fromNumber(10));
475
- significandHigh = significandHigh.add(Long.fromNumber(digits[dIdx]));
476
- }
477
-
478
- significandLow = Long.fromNumber(digits[dIdx++]);
479
-
480
- for (; dIdx <= lastDigit; dIdx++) {
481
- significandLow = significandLow.multiply(Long.fromNumber(10));
482
- significandLow = significandLow.add(Long.fromNumber(digits[dIdx]));
483
- }
484
- }
485
-
486
- const significand = multiply64x2(significandHigh, Long.fromString('100000000000000000'));
487
- significand.low = significand.low.add(significandLow);
488
-
489
- if (lessThan(significand.low, significandLow)) {
490
- significand.high = significand.high.add(Long.fromNumber(1));
491
- }
492
-
493
- // Biased exponent
494
- biasedExponent = exponent + EXPONENT_BIAS;
495
- const dec = { low: Long.fromNumber(0), high: Long.fromNumber(0) };
496
-
497
- // Encode combination, exponent, and significand.
498
- if (
499
- significand.high
500
- .shiftRightUnsigned(49)
501
- .and(Long.fromNumber(1))
502
- .equals(Long.fromNumber(1))
503
- ) {
504
- // Encode '11' into bits 1 to 3
505
- dec.high = dec.high.or(Long.fromNumber(0x3).shiftLeft(61));
506
- dec.high = dec.high.or(
507
- Long.fromNumber(biasedExponent).and(Long.fromNumber(0x3fff).shiftLeft(47))
508
- );
509
- dec.high = dec.high.or(significand.high.and(Long.fromNumber(0x7fffffffffff)));
510
- } else {
511
- dec.high = dec.high.or(Long.fromNumber(biasedExponent & 0x3fff).shiftLeft(49));
512
- dec.high = dec.high.or(significand.high.and(Long.fromNumber(0x1ffffffffffff)));
513
- }
514
-
515
- dec.low = significand.low;
516
-
517
- // Encode sign
518
- if (isNegative) {
519
- dec.high = dec.high.or(Long.fromString('9223372036854775808'));
520
- }
521
-
522
- // Encode into a buffer
523
- const buffer = Buffer.alloc(16);
524
- index = 0;
525
-
526
- // Encode the low 64 bits of the decimal
527
- // Encode low bits
528
- buffer[index++] = dec.low.low & 0xff;
529
- buffer[index++] = (dec.low.low >> 8) & 0xff;
530
- buffer[index++] = (dec.low.low >> 16) & 0xff;
531
- buffer[index++] = (dec.low.low >> 24) & 0xff;
532
- // Encode high bits
533
- buffer[index++] = dec.low.high & 0xff;
534
- buffer[index++] = (dec.low.high >> 8) & 0xff;
535
- buffer[index++] = (dec.low.high >> 16) & 0xff;
536
- buffer[index++] = (dec.low.high >> 24) & 0xff;
537
-
538
- // Encode the high 64 bits of the decimal
539
- // Encode low bits
540
- buffer[index++] = dec.high.low & 0xff;
541
- buffer[index++] = (dec.high.low >> 8) & 0xff;
542
- buffer[index++] = (dec.high.low >> 16) & 0xff;
543
- buffer[index++] = (dec.high.low >> 24) & 0xff;
544
- // Encode high bits
545
- buffer[index++] = dec.high.high & 0xff;
546
- buffer[index++] = (dec.high.high >> 8) & 0xff;
547
- buffer[index++] = (dec.high.high >> 16) & 0xff;
548
- buffer[index++] = (dec.high.high >> 24) & 0xff;
549
-
550
- // Return the new Decimal128
551
- return new Decimal128(buffer);
552
- };
553
-
554
- // Extract least significant 5 bits
555
- const COMBINATION_MASK = 0x1f;
556
- // Extract least significant 14 bits
557
- const EXPONENT_MASK = 0x3fff;
558
- // Value of combination field for Inf
559
- const COMBINATION_INFINITY = 30;
560
- // Value of combination field for NaN
561
- const COMBINATION_NAN = 31;
562
-
563
- /**
564
- * Create a string representation of the raw Decimal128 value
565
- *
566
- * @method
567
- * @return {string} returns a Decimal128 string representation.
568
- */
569
- Decimal128.prototype.toString = function() {
570
- // Note: bits in this routine are referred to starting at 0,
571
- // from the sign bit, towards the coefficient.
572
-
573
- // bits 0 - 31
574
- let high;
575
- // bits 32 - 63
576
- let midh;
577
- // bits 64 - 95
578
- let midl;
579
- // bits 96 - 127
580
- let low;
581
- // bits 1 - 5
582
- let combination;
583
- // decoded biased exponent (14 bits)
584
- let biased_exponent;
585
- // the number of significand digits
586
- let significand_digits = 0;
587
- // the base-10 digits in the significand
588
- const significand = new Array(36);
589
- for (let i = 0; i < significand.length; i++) significand[i] = 0;
590
- // read pointer into significand
591
- let index = 0;
592
-
593
- // unbiased exponent
594
- let exponent;
595
- // the exponent if scientific notation is used
596
- let scientific_exponent;
597
-
598
- // true if the number is zero
599
- let is_zero = false;
600
-
601
- // the most signifcant significand bits (50-46)
602
- let significand_msb;
603
- // temporary storage for significand decoding
604
- let significand128 = { parts: new Array(4) };
605
- // indexing variables
606
- let j, k;
607
-
608
- // Output string
609
- const string = [];
610
-
611
- // Unpack index
612
- index = 0;
613
-
614
- // Buffer reference
615
- const buffer = this.bytes;
616
-
617
- // Unpack the low 64bits into a long
618
- low =
619
- buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24);
620
- midl =
621
- buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24);
622
-
623
- // Unpack the high 64bits into a long
624
- midh =
625
- buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24);
626
- high =
627
- buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24);
628
-
629
- // Unpack index
630
- index = 0;
631
-
632
- // Create the state of the decimal
633
- const dec = {
634
- low: new Long(low, midl),
635
- high: new Long(midh, high)
636
- };
637
-
638
- if (dec.high.lessThan(Long.ZERO)) {
639
- string.push('-');
640
- }
641
-
642
- // Decode combination field and exponent
643
- combination = (high >> 26) & COMBINATION_MASK;
644
-
645
- if (combination >> 3 === 3) {
646
- // Check for 'special' values
647
- if (combination === COMBINATION_INFINITY) {
648
- return string.join('') + 'Infinity';
649
- } else if (combination === COMBINATION_NAN) {
650
- return 'NaN';
651
- } else {
652
- biased_exponent = (high >> 15) & EXPONENT_MASK;
653
- significand_msb = 0x08 + ((high >> 14) & 0x01);
654
- }
655
- } else {
656
- significand_msb = (high >> 14) & 0x07;
657
- biased_exponent = (high >> 17) & EXPONENT_MASK;
658
- }
659
-
660
- exponent = biased_exponent - EXPONENT_BIAS;
661
-
662
- // Create string of significand digits
663
-
664
- // Convert the 114-bit binary number represented by
665
- // (significand_high, significand_low) to at most 34 decimal
666
- // digits through modulo and division.
667
- significand128.parts[0] = (high & 0x3fff) + ((significand_msb & 0xf) << 14);
668
- significand128.parts[1] = midh;
669
- significand128.parts[2] = midl;
670
- significand128.parts[3] = low;
671
-
672
- if (
673
- significand128.parts[0] === 0 &&
674
- significand128.parts[1] === 0 &&
675
- significand128.parts[2] === 0 &&
676
- significand128.parts[3] === 0
677
- ) {
678
- is_zero = true;
679
- } else {
680
- for (k = 3; k >= 0; k--) {
681
- let least_digits = 0;
682
- // Peform the divide
683
- let result = divideu128(significand128);
684
- significand128 = result.quotient;
685
- least_digits = result.rem.low;
686
-
687
- // We now have the 9 least significant digits (in base 2).
688
- // Convert and output to string.
689
- if (!least_digits) continue;
690
-
691
- for (j = 8; j >= 0; j--) {
692
- // significand[k * 9 + j] = Math.round(least_digits % 10);
693
- significand[k * 9 + j] = least_digits % 10;
694
- // least_digits = Math.round(least_digits / 10);
695
- least_digits = Math.floor(least_digits / 10);
696
- }
697
- }
698
- }
699
-
700
- // Output format options:
701
- // Scientific - [-]d.dddE(+/-)dd or [-]dE(+/-)dd
702
- // Regular - ddd.ddd
703
-
704
- if (is_zero) {
705
- significand_digits = 1;
706
- significand[index] = 0;
707
- } else {
708
- significand_digits = 36;
709
- while (!significand[index]) {
710
- significand_digits = significand_digits - 1;
711
- index = index + 1;
712
- }
713
- }
714
-
715
- scientific_exponent = significand_digits - 1 + exponent;
716
-
717
- // The scientific exponent checks are dictated by the string conversion
718
- // specification and are somewhat arbitrary cutoffs.
719
- //
720
- // We must check exponent > 0, because if this is the case, the number
721
- // has trailing zeros. However, we *cannot* output these trailing zeros,
722
- // because doing so would change the precision of the value, and would
723
- // change stored data if the string converted number is round tripped.
724
- if (scientific_exponent >= 34 || scientific_exponent <= -7 || exponent > 0) {
725
- // Scientific format
726
-
727
- // if there are too many significant digits, we should just be treating numbers
728
- // as + or - 0 and using the non-scientific exponent (this is for the "invalid
729
- // representation should be treated as 0/-0" spec cases in decimal128-1.json)
730
- if (significand_digits > 34) {
731
- string.push(0);
732
- if (exponent > 0) string.push('E+' + exponent);
733
- else if (exponent < 0) string.push('E' + exponent);
734
- return string.join('');
735
- }
736
-
737
- string.push(significand[index++]);
738
- significand_digits = significand_digits - 1;
739
-
740
- if (significand_digits) {
741
- string.push('.');
742
- }
743
-
744
- for (let i = 0; i < significand_digits; i++) {
745
- string.push(significand[index++]);
746
- }
747
-
748
- // Exponent
749
- string.push('E');
750
- if (scientific_exponent > 0) {
751
- string.push('+' + scientific_exponent);
752
- } else {
753
- string.push(scientific_exponent);
754
- }
755
- } else {
756
- // Regular format with no decimal place
757
- if (exponent >= 0) {
758
- for (let i = 0; i < significand_digits; i++) {
759
- string.push(significand[index++]);
760
- }
761
- } else {
762
- let radix_position = significand_digits + exponent;
763
-
764
- // non-zero digits before radix
765
- if (radix_position > 0) {
766
- for (let i = 0; i < radix_position; i++) {
767
- string.push(significand[index++]);
356
+ // Round
357
+ // We've normalized the exponent, but might still need to round.
358
+ if (lastDigit - firstDigit + 1 < significantDigits) {
359
+ var endOfString = nDigitsRead;
360
+ // If we have seen a radix point, 'string' is 1 longer than we have
361
+ // documented with ndigits_read, so inc the position of the first nonzero
362
+ // digit and the position that digits are read to.
363
+ if (sawRadix) {
364
+ firstNonZero = firstNonZero + 1;
365
+ endOfString = endOfString + 1;
366
+ }
367
+ // if negative, we need to increment again to account for - sign at start.
368
+ if (isNegative) {
369
+ firstNonZero = firstNonZero + 1;
370
+ endOfString = endOfString + 1;
371
+ }
372
+ var roundDigit = parseInt(representation[firstNonZero + lastDigit + 1], 10);
373
+ var roundBit = 0;
374
+ if (roundDigit >= 5) {
375
+ roundBit = 1;
376
+ if (roundDigit === 5) {
377
+ roundBit = digits[lastDigit] % 2 === 1 ? 1 : 0;
378
+ for (i = firstNonZero + lastDigit + 2; i < endOfString; i++) {
379
+ if (parseInt(representation[i], 10)) {
380
+ roundBit = 1;
381
+ break;
382
+ }
383
+ }
384
+ }
385
+ }
386
+ if (roundBit) {
387
+ var dIdx = lastDigit;
388
+ for (; dIdx >= 0; dIdx--) {
389
+ if (++digits[dIdx] > 9) {
390
+ digits[dIdx] = 0;
391
+ // overflowed most significant digit
392
+ if (dIdx === 0) {
393
+ if (exponent < EXPONENT_MAX) {
394
+ exponent = exponent + 1;
395
+ digits[dIdx] = 1;
396
+ }
397
+ else {
398
+ return new Decimal128(buffer_1.Buffer.from(isNegative ? INF_NEGATIVE_BUFFER : INF_POSITIVE_BUFFER));
399
+ }
400
+ }
401
+ }
402
+ }
403
+ }
768
404
  }
769
- } else {
770
- string.push('0');
771
- }
772
-
773
- string.push('.');
774
- // add leading zeros after radix
775
- while (radix_position++ < 0) {
776
- string.push('0');
777
- }
778
-
779
- for (let i = 0; i < significand_digits - Math.max(radix_position - 1, 0); i++) {
780
- string.push(significand[index++]);
781
- }
782
- }
783
- }
784
-
785
- return string.join('');
786
- };
787
-
788
- Decimal128.prototype.toJSON = function() {
789
- return { $numberDecimal: this.toString() };
790
- };
791
-
792
- /**
793
- * @ignore
794
- */
795
- Decimal128.prototype.toExtendedJSON = function() {
796
- return { $numberDecimal: this.toString() };
797
- };
798
-
799
- /**
800
- * @ignore
801
- */
802
- Decimal128.fromExtendedJSON = function(doc) {
803
- return Decimal128.fromString(doc.$numberDecimal);
804
- };
805
-
405
+ // Encode significand
406
+ // The high 17 digits of the significand
407
+ significandHigh = long_1.Long.fromNumber(0);
408
+ // The low 17 digits of the significand
409
+ significandLow = long_1.Long.fromNumber(0);
410
+ // read a zero
411
+ if (significantDigits === 0) {
412
+ significandHigh = long_1.Long.fromNumber(0);
413
+ significandLow = long_1.Long.fromNumber(0);
414
+ }
415
+ else if (lastDigit - firstDigit < 17) {
416
+ var dIdx = firstDigit;
417
+ significandLow = long_1.Long.fromNumber(digits[dIdx++]);
418
+ significandHigh = new long_1.Long(0, 0);
419
+ for (; dIdx <= lastDigit; dIdx++) {
420
+ significandLow = significandLow.multiply(long_1.Long.fromNumber(10));
421
+ significandLow = significandLow.add(long_1.Long.fromNumber(digits[dIdx]));
422
+ }
423
+ }
424
+ else {
425
+ var dIdx = firstDigit;
426
+ significandHigh = long_1.Long.fromNumber(digits[dIdx++]);
427
+ for (; dIdx <= lastDigit - 17; dIdx++) {
428
+ significandHigh = significandHigh.multiply(long_1.Long.fromNumber(10));
429
+ significandHigh = significandHigh.add(long_1.Long.fromNumber(digits[dIdx]));
430
+ }
431
+ significandLow = long_1.Long.fromNumber(digits[dIdx++]);
432
+ for (; dIdx <= lastDigit; dIdx++) {
433
+ significandLow = significandLow.multiply(long_1.Long.fromNumber(10));
434
+ significandLow = significandLow.add(long_1.Long.fromNumber(digits[dIdx]));
435
+ }
436
+ }
437
+ var significand = multiply64x2(significandHigh, long_1.Long.fromString('100000000000000000'));
438
+ significand.low = significand.low.add(significandLow);
439
+ if (lessThan(significand.low, significandLow)) {
440
+ significand.high = significand.high.add(long_1.Long.fromNumber(1));
441
+ }
442
+ // Biased exponent
443
+ biasedExponent = exponent + EXPONENT_BIAS;
444
+ var dec = { low: long_1.Long.fromNumber(0), high: long_1.Long.fromNumber(0) };
445
+ // Encode combination, exponent, and significand.
446
+ if (significand.high.shiftRightUnsigned(49).and(long_1.Long.fromNumber(1)).equals(long_1.Long.fromNumber(1))) {
447
+ // Encode '11' into bits 1 to 3
448
+ dec.high = dec.high.or(long_1.Long.fromNumber(0x3).shiftLeft(61));
449
+ dec.high = dec.high.or(long_1.Long.fromNumber(biasedExponent).and(long_1.Long.fromNumber(0x3fff).shiftLeft(47)));
450
+ dec.high = dec.high.or(significand.high.and(long_1.Long.fromNumber(0x7fffffffffff)));
451
+ }
452
+ else {
453
+ dec.high = dec.high.or(long_1.Long.fromNumber(biasedExponent & 0x3fff).shiftLeft(49));
454
+ dec.high = dec.high.or(significand.high.and(long_1.Long.fromNumber(0x1ffffffffffff)));
455
+ }
456
+ dec.low = significand.low;
457
+ // Encode sign
458
+ if (isNegative) {
459
+ dec.high = dec.high.or(long_1.Long.fromString('9223372036854775808'));
460
+ }
461
+ // Encode into a buffer
462
+ var buffer = buffer_1.Buffer.alloc(16);
463
+ index = 0;
464
+ // Encode the low 64 bits of the decimal
465
+ // Encode low bits
466
+ buffer[index++] = dec.low.low & 0xff;
467
+ buffer[index++] = (dec.low.low >> 8) & 0xff;
468
+ buffer[index++] = (dec.low.low >> 16) & 0xff;
469
+ buffer[index++] = (dec.low.low >> 24) & 0xff;
470
+ // Encode high bits
471
+ buffer[index++] = dec.low.high & 0xff;
472
+ buffer[index++] = (dec.low.high >> 8) & 0xff;
473
+ buffer[index++] = (dec.low.high >> 16) & 0xff;
474
+ buffer[index++] = (dec.low.high >> 24) & 0xff;
475
+ // Encode the high 64 bits of the decimal
476
+ // Encode low bits
477
+ buffer[index++] = dec.high.low & 0xff;
478
+ buffer[index++] = (dec.high.low >> 8) & 0xff;
479
+ buffer[index++] = (dec.high.low >> 16) & 0xff;
480
+ buffer[index++] = (dec.high.low >> 24) & 0xff;
481
+ // Encode high bits
482
+ buffer[index++] = dec.high.high & 0xff;
483
+ buffer[index++] = (dec.high.high >> 8) & 0xff;
484
+ buffer[index++] = (dec.high.high >> 16) & 0xff;
485
+ buffer[index++] = (dec.high.high >> 24) & 0xff;
486
+ // Return the new Decimal128
487
+ return new Decimal128(buffer);
488
+ };
489
+ /** Create a string representation of the raw Decimal128 value */
490
+ Decimal128.prototype.toString = function () {
491
+ // Note: bits in this routine are referred to starting at 0,
492
+ // from the sign bit, towards the coefficient.
493
+ // decoded biased exponent (14 bits)
494
+ var biased_exponent;
495
+ // the number of significand digits
496
+ var significand_digits = 0;
497
+ // the base-10 digits in the significand
498
+ var significand = new Array(36);
499
+ for (var i = 0; i < significand.length; i++)
500
+ significand[i] = 0;
501
+ // read pointer into significand
502
+ var index = 0;
503
+ // true if the number is zero
504
+ var is_zero = false;
505
+ // the most significant significand bits (50-46)
506
+ var significand_msb;
507
+ // temporary storage for significand decoding
508
+ var significand128 = { parts: [0, 0, 0, 0] };
509
+ // indexing variables
510
+ var j, k;
511
+ // Output string
512
+ var string = [];
513
+ // Unpack index
514
+ index = 0;
515
+ // Buffer reference
516
+ var buffer = this.bytes;
517
+ // Unpack the low 64bits into a long
518
+ // bits 96 - 127
519
+ var low = buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24);
520
+ // bits 64 - 95
521
+ var midl = buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24);
522
+ // Unpack the high 64bits into a long
523
+ // bits 32 - 63
524
+ var midh = buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24);
525
+ // bits 0 - 31
526
+ var high = buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24);
527
+ // Unpack index
528
+ index = 0;
529
+ // Create the state of the decimal
530
+ var dec = {
531
+ low: new long_1.Long(low, midl),
532
+ high: new long_1.Long(midh, high)
533
+ };
534
+ if (dec.high.lessThan(long_1.Long.ZERO)) {
535
+ string.push('-');
536
+ }
537
+ // Decode combination field and exponent
538
+ // bits 1 - 5
539
+ var combination = (high >> 26) & COMBINATION_MASK;
540
+ if (combination >> 3 === 3) {
541
+ // Check for 'special' values
542
+ if (combination === COMBINATION_INFINITY) {
543
+ return string.join('') + 'Infinity';
544
+ }
545
+ else if (combination === COMBINATION_NAN) {
546
+ return 'NaN';
547
+ }
548
+ else {
549
+ biased_exponent = (high >> 15) & EXPONENT_MASK;
550
+ significand_msb = 0x08 + ((high >> 14) & 0x01);
551
+ }
552
+ }
553
+ else {
554
+ significand_msb = (high >> 14) & 0x07;
555
+ biased_exponent = (high >> 17) & EXPONENT_MASK;
556
+ }
557
+ // unbiased exponent
558
+ var exponent = biased_exponent - EXPONENT_BIAS;
559
+ // Create string of significand digits
560
+ // Convert the 114-bit binary number represented by
561
+ // (significand_high, significand_low) to at most 34 decimal
562
+ // digits through modulo and division.
563
+ significand128.parts[0] = (high & 0x3fff) + ((significand_msb & 0xf) << 14);
564
+ significand128.parts[1] = midh;
565
+ significand128.parts[2] = midl;
566
+ significand128.parts[3] = low;
567
+ if (significand128.parts[0] === 0 &&
568
+ significand128.parts[1] === 0 &&
569
+ significand128.parts[2] === 0 &&
570
+ significand128.parts[3] === 0) {
571
+ is_zero = true;
572
+ }
573
+ else {
574
+ for (k = 3; k >= 0; k--) {
575
+ var least_digits = 0;
576
+ // Perform the divide
577
+ var result = divideu128(significand128);
578
+ significand128 = result.quotient;
579
+ least_digits = result.rem.low;
580
+ // We now have the 9 least significant digits (in base 2).
581
+ // Convert and output to string.
582
+ if (!least_digits)
583
+ continue;
584
+ for (j = 8; j >= 0; j--) {
585
+ // significand[k * 9 + j] = Math.round(least_digits % 10);
586
+ significand[k * 9 + j] = least_digits % 10;
587
+ // least_digits = Math.round(least_digits / 10);
588
+ least_digits = Math.floor(least_digits / 10);
589
+ }
590
+ }
591
+ }
592
+ // Output format options:
593
+ // Scientific - [-]d.dddE(+/-)dd or [-]dE(+/-)dd
594
+ // Regular - ddd.ddd
595
+ if (is_zero) {
596
+ significand_digits = 1;
597
+ significand[index] = 0;
598
+ }
599
+ else {
600
+ significand_digits = 36;
601
+ while (!significand[index]) {
602
+ significand_digits = significand_digits - 1;
603
+ index = index + 1;
604
+ }
605
+ }
606
+ // the exponent if scientific notation is used
607
+ var scientific_exponent = significand_digits - 1 + exponent;
608
+ // The scientific exponent checks are dictated by the string conversion
609
+ // specification and are somewhat arbitrary cutoffs.
610
+ //
611
+ // We must check exponent > 0, because if this is the case, the number
612
+ // has trailing zeros. However, we *cannot* output these trailing zeros,
613
+ // because doing so would change the precision of the value, and would
614
+ // change stored data if the string converted number is round tripped.
615
+ if (scientific_exponent >= 34 || scientific_exponent <= -7 || exponent > 0) {
616
+ // Scientific format
617
+ // if there are too many significant digits, we should just be treating numbers
618
+ // as + or - 0 and using the non-scientific exponent (this is for the "invalid
619
+ // representation should be treated as 0/-0" spec cases in decimal128-1.json)
620
+ if (significand_digits > 34) {
621
+ string.push("" + 0);
622
+ if (exponent > 0)
623
+ string.push('E+' + exponent);
624
+ else if (exponent < 0)
625
+ string.push('E' + exponent);
626
+ return string.join('');
627
+ }
628
+ string.push("" + significand[index++]);
629
+ significand_digits = significand_digits - 1;
630
+ if (significand_digits) {
631
+ string.push('.');
632
+ }
633
+ for (var i = 0; i < significand_digits; i++) {
634
+ string.push("" + significand[index++]);
635
+ }
636
+ // Exponent
637
+ string.push('E');
638
+ if (scientific_exponent > 0) {
639
+ string.push('+' + scientific_exponent);
640
+ }
641
+ else {
642
+ string.push("" + scientific_exponent);
643
+ }
644
+ }
645
+ else {
646
+ // Regular format with no decimal place
647
+ if (exponent >= 0) {
648
+ for (var i = 0; i < significand_digits; i++) {
649
+ string.push("" + significand[index++]);
650
+ }
651
+ }
652
+ else {
653
+ var radix_position = significand_digits + exponent;
654
+ // non-zero digits before radix
655
+ if (radix_position > 0) {
656
+ for (var i = 0; i < radix_position; i++) {
657
+ string.push("" + significand[index++]);
658
+ }
659
+ }
660
+ else {
661
+ string.push('0');
662
+ }
663
+ string.push('.');
664
+ // add leading zeros after radix
665
+ while (radix_position++ < 0) {
666
+ string.push('0');
667
+ }
668
+ for (var i = 0; i < significand_digits - Math.max(radix_position - 1, 0); i++) {
669
+ string.push("" + significand[index++]);
670
+ }
671
+ }
672
+ }
673
+ return string.join('');
674
+ };
675
+ Decimal128.prototype.toJSON = function () {
676
+ return { $numberDecimal: this.toString() };
677
+ };
678
+ /** @internal */
679
+ Decimal128.prototype.toExtendedJSON = function () {
680
+ return { $numberDecimal: this.toString() };
681
+ };
682
+ /** @internal */
683
+ Decimal128.fromExtendedJSON = function (doc) {
684
+ return Decimal128.fromString(doc.$numberDecimal);
685
+ };
686
+ /** @internal */
687
+ Decimal128.prototype[Symbol.for('nodejs.util.inspect.custom')] = function () {
688
+ return this.inspect();
689
+ };
690
+ Decimal128.prototype.inspect = function () {
691
+ return "Decimal128.fromString(\"" + this.toString() + "\")";
692
+ };
693
+ return Decimal128;
694
+ }());
695
+ exports.Decimal128 = Decimal128;
806
696
  Object.defineProperty(Decimal128.prototype, '_bsontype', { value: 'Decimal128' });
807
- module.exports = Decimal128;
697
+ //# sourceMappingURL=decimal128.js.map