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