bson 6.0.0-alpha.1 → 6.1.0

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.
package/lib/bson.mjs CHANGED
@@ -1419,6 +1419,12 @@ class Decimal128 extends BSONValue {
1419
1419
  }
1420
1420
  }
1421
1421
  static fromString(representation) {
1422
+ return Decimal128._fromString(representation, { allowRounding: false });
1423
+ }
1424
+ static fromStringWithRounding(representation) {
1425
+ return Decimal128._fromString(representation, { allowRounding: true });
1426
+ }
1427
+ static _fromString(representation, options) {
1422
1428
  let isNegative = false;
1423
1429
  let sawSign = false;
1424
1430
  let sawRadix = false;
@@ -1539,44 +1545,117 @@ class Decimal128 extends BSONValue {
1539
1545
  }
1540
1546
  exponent = exponent - 1;
1541
1547
  }
1542
- while (exponent < EXPONENT_MIN || nDigitsStored < nDigits) {
1543
- if (lastDigit === 0) {
1544
- if (significantDigits === 0) {
1548
+ if (options.allowRounding) {
1549
+ while (exponent < EXPONENT_MIN || nDigitsStored < nDigits) {
1550
+ if (lastDigit === 0 && significantDigits < nDigitsStored) {
1545
1551
  exponent = EXPONENT_MIN;
1552
+ significantDigits = 0;
1546
1553
  break;
1547
1554
  }
1548
- invalidErr(representation, 'exponent underflow');
1549
- }
1550
- if (nDigitsStored < nDigits) {
1551
- if (representation[nDigits - 1 + Number(sawSign) + Number(sawRadix)] !== '0' &&
1552
- significantDigits !== 0) {
1553
- invalidErr(representation, 'inexact rounding');
1555
+ if (nDigitsStored < nDigits) {
1556
+ nDigits = nDigits - 1;
1554
1557
  }
1555
- nDigits = nDigits - 1;
1556
- }
1557
- else {
1558
- if (digits[lastDigit] !== 0) {
1559
- invalidErr(representation, 'inexact rounding');
1558
+ else {
1559
+ lastDigit = lastDigit - 1;
1560
+ }
1561
+ if (exponent < EXPONENT_MAX) {
1562
+ exponent = exponent + 1;
1563
+ }
1564
+ else {
1565
+ const digitsString = digits.join('');
1566
+ if (digitsString.match(/^0+$/)) {
1567
+ exponent = EXPONENT_MAX;
1568
+ break;
1569
+ }
1570
+ invalidErr(representation, 'overflow');
1560
1571
  }
1561
- lastDigit = lastDigit - 1;
1562
- }
1563
- if (exponent < EXPONENT_MAX) {
1564
- exponent = exponent + 1;
1565
1572
  }
1566
- else {
1567
- invalidErr(representation, 'overflow');
1573
+ if (lastDigit + 1 < significantDigits) {
1574
+ let endOfString = nDigitsRead;
1575
+ if (sawRadix) {
1576
+ firstNonZero = firstNonZero + 1;
1577
+ endOfString = endOfString + 1;
1578
+ }
1579
+ if (sawSign) {
1580
+ firstNonZero = firstNonZero + 1;
1581
+ endOfString = endOfString + 1;
1582
+ }
1583
+ const roundDigit = parseInt(representation[firstNonZero + lastDigit + 1], 10);
1584
+ let roundBit = 0;
1585
+ if (roundDigit >= 5) {
1586
+ roundBit = 1;
1587
+ if (roundDigit === 5) {
1588
+ roundBit = digits[lastDigit] % 2 === 1 ? 1 : 0;
1589
+ for (let i = firstNonZero + lastDigit + 2; i < endOfString; i++) {
1590
+ if (parseInt(representation[i], 10)) {
1591
+ roundBit = 1;
1592
+ break;
1593
+ }
1594
+ }
1595
+ }
1596
+ }
1597
+ if (roundBit) {
1598
+ let dIdx = lastDigit;
1599
+ for (; dIdx >= 0; dIdx--) {
1600
+ if (++digits[dIdx] > 9) {
1601
+ digits[dIdx] = 0;
1602
+ if (dIdx === 0) {
1603
+ if (exponent < EXPONENT_MAX) {
1604
+ exponent = exponent + 1;
1605
+ digits[dIdx] = 1;
1606
+ }
1607
+ else {
1608
+ return new Decimal128(isNegative ? INF_NEGATIVE_BUFFER : INF_POSITIVE_BUFFER);
1609
+ }
1610
+ }
1611
+ }
1612
+ else {
1613
+ break;
1614
+ }
1615
+ }
1616
+ }
1568
1617
  }
1569
1618
  }
1570
- if (lastDigit + 1 < significantDigits) {
1571
- if (sawRadix) {
1572
- firstNonZero = firstNonZero + 1;
1573
- }
1574
- if (sawSign) {
1575
- firstNonZero = firstNonZero + 1;
1619
+ else {
1620
+ while (exponent < EXPONENT_MIN || nDigitsStored < nDigits) {
1621
+ if (lastDigit === 0) {
1622
+ if (significantDigits === 0) {
1623
+ exponent = EXPONENT_MIN;
1624
+ break;
1625
+ }
1626
+ invalidErr(representation, 'exponent underflow');
1627
+ }
1628
+ if (nDigitsStored < nDigits) {
1629
+ if (representation[nDigits - 1 + Number(sawSign) + Number(sawRadix)] !== '0' &&
1630
+ significantDigits !== 0) {
1631
+ invalidErr(representation, 'inexact rounding');
1632
+ }
1633
+ nDigits = nDigits - 1;
1634
+ }
1635
+ else {
1636
+ if (digits[lastDigit] !== 0) {
1637
+ invalidErr(representation, 'inexact rounding');
1638
+ }
1639
+ lastDigit = lastDigit - 1;
1640
+ }
1641
+ if (exponent < EXPONENT_MAX) {
1642
+ exponent = exponent + 1;
1643
+ }
1644
+ else {
1645
+ invalidErr(representation, 'overflow');
1646
+ }
1576
1647
  }
1577
- const roundDigit = parseInt(representation[firstNonZero + lastDigit + 1], 10);
1578
- if (roundDigit !== 0) {
1579
- invalidErr(representation, 'inexact rounding');
1648
+ if (lastDigit + 1 < significantDigits) {
1649
+ if (sawRadix) {
1650
+ firstNonZero = firstNonZero + 1;
1651
+ }
1652
+ if (sawSign) {
1653
+ firstNonZero = firstNonZero + 1;
1654
+ }
1655
+ const roundDigit = parseInt(representation[firstNonZero + lastDigit + 1], 10);
1656
+ if (roundDigit !== 0) {
1657
+ invalidErr(representation, 'inexact rounding');
1658
+ }
1580
1659
  }
1581
1660
  }
1582
1661
  significandHigh = Long.fromNumber(0);
@@ -3087,13 +3166,16 @@ function serializeObjectId(buffer, key, value, index) {
3087
3166
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3088
3167
  index = index + numberOfWrittenBytes;
3089
3168
  buffer[index++] = 0;
3090
- if (isUint8Array(value.id)) {
3091
- buffer.set(value.id.subarray(0, 12), index);
3169
+ const idValue = value.id;
3170
+ if (isUint8Array(idValue)) {
3171
+ for (let i = 0; i < 12; i++) {
3172
+ buffer[index++] = idValue[i];
3173
+ }
3092
3174
  }
3093
3175
  else {
3094
3176
  throw new BSONError('object [' + JSON.stringify(value) + '] is not a valid ObjectId');
3095
3177
  }
3096
- return index + 12;
3178
+ return index;
3097
3179
  }
3098
3180
  function serializeBuffer(buffer, key, value, index) {
3099
3181
  buffer[index++] = BSON_DATA_BINARY;