bson 6.3.0 → 6.4.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
@@ -162,7 +162,7 @@ function validateUtf8(bytes, start, end) {
162
162
  return !continuation;
163
163
  }
164
164
 
165
- function tryLatin(uint8array, start, end) {
165
+ function tryReadBasicLatin(uint8array, start, end) {
166
166
  if (uint8array.length === 0) {
167
167
  return '';
168
168
  }
@@ -197,6 +197,21 @@ function tryLatin(uint8array, start, end) {
197
197
  }
198
198
  return String.fromCharCode(...latinBytes);
199
199
  }
200
+ function tryWriteBasicLatin(destination, source, offset) {
201
+ if (source.length === 0)
202
+ return 0;
203
+ if (source.length > 25)
204
+ return null;
205
+ if (destination.length - offset < source.length)
206
+ return null;
207
+ for (let charOffset = 0, destinationOffset = offset; charOffset < source.length; charOffset++, destinationOffset++) {
208
+ const char = source.charCodeAt(charOffset);
209
+ if (char > 127)
210
+ return null;
211
+ destination[destinationOffset] = char;
212
+ }
213
+ return source.length;
214
+ }
200
215
 
201
216
  function nodejsMathRandomBytes(byteLength) {
202
217
  return nodeJsByteUtils.fromNumberArray(Array.from({ length: byteLength }, () => Math.floor(Math.random() * 256)));
@@ -229,6 +244,9 @@ const nodeJsByteUtils = {
229
244
  allocate(size) {
230
245
  return Buffer.alloc(size);
231
246
  },
247
+ allocateUnsafe(size) {
248
+ return Buffer.allocUnsafe(size);
249
+ },
232
250
  equals(a, b) {
233
251
  return nodeJsByteUtils.toLocalBufferType(a).equals(b);
234
252
  },
@@ -253,11 +271,8 @@ const nodeJsByteUtils = {
253
271
  toHex(buffer) {
254
272
  return nodeJsByteUtils.toLocalBufferType(buffer).toString('hex');
255
273
  },
256
- fromUTF8(text) {
257
- return Buffer.from(text, 'utf8');
258
- },
259
274
  toUTF8(buffer, start, end, fatal) {
260
- const basicLatin = end - start <= 20 ? tryLatin(buffer, start, end) : null;
275
+ const basicLatin = end - start <= 20 ? tryReadBasicLatin(buffer, start, end) : null;
261
276
  if (basicLatin != null) {
262
277
  return basicLatin;
263
278
  }
@@ -278,6 +293,10 @@ const nodeJsByteUtils = {
278
293
  return Buffer.byteLength(input, 'utf8');
279
294
  },
280
295
  encodeUTF8Into(buffer, source, byteOffset) {
296
+ const latinBytesWritten = tryWriteBasicLatin(buffer, source, byteOffset);
297
+ if (latinBytesWritten != null) {
298
+ return latinBytesWritten;
299
+ }
281
300
  return nodeJsByteUtils.toLocalBufferType(buffer).write(source, byteOffset, undefined, 'utf8');
282
301
  },
283
302
  randomBytes: nodejsRandomBytes
@@ -333,6 +352,9 @@ const webByteUtils = {
333
352
  }
334
353
  return new Uint8Array(size);
335
354
  },
355
+ allocateUnsafe(size) {
356
+ return webByteUtils.allocate(size);
357
+ },
336
358
  equals(a, b) {
337
359
  if (a.byteLength !== b.byteLength) {
338
360
  return false;
@@ -379,11 +401,8 @@ const webByteUtils = {
379
401
  toHex(uint8array) {
380
402
  return Array.from(uint8array, byte => byte.toString(16).padStart(2, '0')).join('');
381
403
  },
382
- fromUTF8(text) {
383
- return new TextEncoder().encode(text);
384
- },
385
404
  toUTF8(uint8array, start, end, fatal) {
386
- const basicLatin = end - start <= 20 ? tryLatin(uint8array, start, end) : null;
405
+ const basicLatin = end - start <= 20 ? tryReadBasicLatin(uint8array, start, end) : null;
387
406
  if (basicLatin != null) {
388
407
  return basicLatin;
389
408
  }
@@ -398,11 +417,11 @@ const webByteUtils = {
398
417
  return new TextDecoder('utf8', { fatal }).decode(uint8array.slice(start, end));
399
418
  },
400
419
  utf8ByteLength(input) {
401
- return webByteUtils.fromUTF8(input).byteLength;
420
+ return new TextEncoder().encode(input).byteLength;
402
421
  },
403
- encodeUTF8Into(buffer, source, byteOffset) {
404
- const bytes = webByteUtils.fromUTF8(source);
405
- buffer.set(bytes, byteOffset);
422
+ encodeUTF8Into(uint8array, source, byteOffset) {
423
+ const bytes = new TextEncoder().encode(source);
424
+ uint8array.set(bytes, byteOffset);
406
425
  return bytes.byteLength;
407
426
  },
408
427
  randomBytes: webRandomBytes
@@ -410,11 +429,6 @@ const webByteUtils = {
410
429
 
411
430
  const hasGlobalBuffer = typeof Buffer === 'function' && Buffer.prototype?._isBuffer !== true;
412
431
  const ByteUtils = hasGlobalBuffer ? nodeJsByteUtils : webByteUtils;
413
- class BSONDataView extends DataView {
414
- static fromUint8Array(input) {
415
- return new DataView(input.buffer, input.byteOffset, input.byteLength);
416
- }
417
- }
418
432
 
419
433
  class BSONValue {
420
434
  get [Symbol.for('@@mdb.bson.version')]() {
@@ -1834,7 +1848,7 @@ class Decimal128 extends BSONValue {
1834
1848
  if (isNegative) {
1835
1849
  dec.high = dec.high.or(Long.fromString('9223372036854775808'));
1836
1850
  }
1837
- const buffer = ByteUtils.allocate(16);
1851
+ const buffer = ByteUtils.allocateUnsafe(16);
1838
1852
  index = 0;
1839
1853
  buffer[index++] = dec.low.low & 0xff;
1840
1854
  buffer[index++] = (dec.low.low >> 8) & 0xff;
@@ -2107,9 +2121,99 @@ class MinKey extends BSONValue {
2107
2121
  }
2108
2122
  }
2109
2123
 
2124
+ const FLOAT = new Float64Array(1);
2125
+ const FLOAT_BYTES = new Uint8Array(FLOAT.buffer, 0, 8);
2126
+ const NumberUtils = {
2127
+ getInt32LE(source, offset) {
2128
+ return (source[offset] |
2129
+ (source[offset + 1] << 8) |
2130
+ (source[offset + 2] << 16) |
2131
+ (source[offset + 3] << 24));
2132
+ },
2133
+ getUint32LE(source, offset) {
2134
+ return (source[offset] +
2135
+ source[offset + 1] * 256 +
2136
+ source[offset + 2] * 65536 +
2137
+ source[offset + 3] * 16777216);
2138
+ },
2139
+ getUint32BE(source, offset) {
2140
+ return (source[offset + 3] +
2141
+ source[offset + 2] * 256 +
2142
+ source[offset + 1] * 65536 +
2143
+ source[offset] * 16777216);
2144
+ },
2145
+ getBigInt64LE(source, offset) {
2146
+ const lo = NumberUtils.getUint32LE(source, offset);
2147
+ const hi = NumberUtils.getUint32LE(source, offset + 4);
2148
+ return (BigInt(hi) << BigInt(32)) + BigInt(lo);
2149
+ },
2150
+ getFloat64LE(source, offset) {
2151
+ FLOAT_BYTES[0] = source[offset];
2152
+ FLOAT_BYTES[1] = source[offset + 1];
2153
+ FLOAT_BYTES[2] = source[offset + 2];
2154
+ FLOAT_BYTES[3] = source[offset + 3];
2155
+ FLOAT_BYTES[4] = source[offset + 4];
2156
+ FLOAT_BYTES[5] = source[offset + 5];
2157
+ FLOAT_BYTES[6] = source[offset + 6];
2158
+ FLOAT_BYTES[7] = source[offset + 7];
2159
+ return FLOAT[0];
2160
+ },
2161
+ setInt32BE(destination, offset, value) {
2162
+ destination[offset + 3] = value;
2163
+ value >>>= 8;
2164
+ destination[offset + 2] = value;
2165
+ value >>>= 8;
2166
+ destination[offset + 1] = value;
2167
+ value >>>= 8;
2168
+ destination[offset] = value;
2169
+ return 4;
2170
+ },
2171
+ setInt32LE(destination, offset, value) {
2172
+ destination[offset] = value;
2173
+ value >>>= 8;
2174
+ destination[offset + 1] = value;
2175
+ value >>>= 8;
2176
+ destination[offset + 2] = value;
2177
+ value >>>= 8;
2178
+ destination[offset + 3] = value;
2179
+ return 4;
2180
+ },
2181
+ setBigInt64LE(destination, offset, value) {
2182
+ const mask32bits = BigInt(4294967295);
2183
+ let lo = Number(value & mask32bits);
2184
+ destination[offset] = lo;
2185
+ lo >>= 8;
2186
+ destination[offset + 1] = lo;
2187
+ lo >>= 8;
2188
+ destination[offset + 2] = lo;
2189
+ lo >>= 8;
2190
+ destination[offset + 3] = lo;
2191
+ let hi = Number((value >> BigInt(32)) & mask32bits);
2192
+ destination[offset + 4] = hi;
2193
+ hi >>= 8;
2194
+ destination[offset + 5] = hi;
2195
+ hi >>= 8;
2196
+ destination[offset + 6] = hi;
2197
+ hi >>= 8;
2198
+ destination[offset + 7] = hi;
2199
+ return 8;
2200
+ },
2201
+ setFloat64LE(destination, offset, value) {
2202
+ FLOAT[0] = value;
2203
+ destination[offset] = FLOAT_BYTES[0];
2204
+ destination[offset + 1] = FLOAT_BYTES[1];
2205
+ destination[offset + 2] = FLOAT_BYTES[2];
2206
+ destination[offset + 3] = FLOAT_BYTES[3];
2207
+ destination[offset + 4] = FLOAT_BYTES[4];
2208
+ destination[offset + 5] = FLOAT_BYTES[5];
2209
+ destination[offset + 6] = FLOAT_BYTES[6];
2210
+ destination[offset + 7] = FLOAT_BYTES[7];
2211
+ return 8;
2212
+ }
2213
+ };
2214
+
2110
2215
  const checkForHexRegExp = new RegExp('^[0-9a-fA-F]{24}$');
2111
2216
  let PROCESS_UNIQUE = null;
2112
- const kId = Symbol('id');
2113
2217
  class ObjectId extends BSONValue {
2114
2218
  get _bsontype() {
2115
2219
  return 'ObjectId';
@@ -2132,14 +2236,14 @@ class ObjectId extends BSONValue {
2132
2236
  workingId = inputId;
2133
2237
  }
2134
2238
  if (workingId == null || typeof workingId === 'number') {
2135
- this[kId] = ObjectId.generate(typeof workingId === 'number' ? workingId : undefined);
2239
+ this.buffer = ObjectId.generate(typeof workingId === 'number' ? workingId : undefined);
2136
2240
  }
2137
2241
  else if (ArrayBuffer.isView(workingId) && workingId.byteLength === 12) {
2138
- this[kId] = ByteUtils.toLocalBufferType(workingId);
2242
+ this.buffer = ByteUtils.toLocalBufferType(workingId);
2139
2243
  }
2140
2244
  else if (typeof workingId === 'string') {
2141
2245
  if (workingId.length === 24 && checkForHexRegExp.test(workingId)) {
2142
- this[kId] = ByteUtils.fromHex(workingId);
2246
+ this.buffer = ByteUtils.fromHex(workingId);
2143
2247
  }
2144
2248
  else {
2145
2249
  throw new BSONError('input must be a 24 character hex string, 12 byte Uint8Array, or an integer');
@@ -2153,10 +2257,10 @@ class ObjectId extends BSONValue {
2153
2257
  }
2154
2258
  }
2155
2259
  get id() {
2156
- return this[kId];
2260
+ return this.buffer;
2157
2261
  }
2158
2262
  set id(value) {
2159
- this[kId] = value;
2263
+ this.buffer = value;
2160
2264
  if (ObjectId.cacheHexString) {
2161
2265
  this.__id = ByteUtils.toHex(value);
2162
2266
  }
@@ -2179,8 +2283,8 @@ class ObjectId extends BSONValue {
2179
2283
  time = Math.floor(Date.now() / 1000);
2180
2284
  }
2181
2285
  const inc = ObjectId.getInc();
2182
- const buffer = ByteUtils.allocate(12);
2183
- BSONDataView.fromUint8Array(buffer).setUint32(0, time, false);
2286
+ const buffer = ByteUtils.allocateUnsafe(12);
2287
+ NumberUtils.setInt32BE(buffer, 0, time);
2184
2288
  if (PROCESS_UNIQUE === null) {
2185
2289
  PROCESS_UNIQUE = ByteUtils.randomBytes(5);
2186
2290
  }
@@ -2215,7 +2319,7 @@ class ObjectId extends BSONValue {
2215
2319
  return false;
2216
2320
  }
2217
2321
  if (ObjectId.is(otherId)) {
2218
- return this[kId][11] === otherId[kId][11] && ByteUtils.equals(this[kId], otherId[kId]);
2322
+ return (this.buffer[11] === otherId.buffer[11] && ByteUtils.equals(this.buffer, otherId.buffer));
2219
2323
  }
2220
2324
  if (typeof otherId === 'string') {
2221
2325
  return otherId.toLowerCase() === this.toHexString();
@@ -2229,16 +2333,33 @@ class ObjectId extends BSONValue {
2229
2333
  }
2230
2334
  getTimestamp() {
2231
2335
  const timestamp = new Date();
2232
- const time = BSONDataView.fromUint8Array(this.id).getUint32(0, false);
2336
+ const time = NumberUtils.getUint32BE(this.buffer, 0);
2233
2337
  timestamp.setTime(Math.floor(time) * 1000);
2234
2338
  return timestamp;
2235
2339
  }
2236
2340
  static createPk() {
2237
2341
  return new ObjectId();
2238
2342
  }
2343
+ serializeInto(uint8array, index) {
2344
+ uint8array[index] = this.buffer[0];
2345
+ uint8array[index + 1] = this.buffer[1];
2346
+ uint8array[index + 2] = this.buffer[2];
2347
+ uint8array[index + 3] = this.buffer[3];
2348
+ uint8array[index + 4] = this.buffer[4];
2349
+ uint8array[index + 5] = this.buffer[5];
2350
+ uint8array[index + 6] = this.buffer[6];
2351
+ uint8array[index + 7] = this.buffer[7];
2352
+ uint8array[index + 8] = this.buffer[8];
2353
+ uint8array[index + 9] = this.buffer[9];
2354
+ uint8array[index + 10] = this.buffer[10];
2355
+ uint8array[index + 11] = this.buffer[11];
2356
+ return 12;
2357
+ }
2239
2358
  static createFromTime(time) {
2240
- const buffer = ByteUtils.fromNumberArray([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
2241
- BSONDataView.fromUint8Array(buffer).setUint32(0, time, false);
2359
+ const buffer = ByteUtils.allocate(12);
2360
+ for (let i = 11; i >= 4; i--)
2361
+ buffer[i] = 0;
2362
+ NumberUtils.setInt32BE(buffer, 0, time);
2242
2363
  return new ObjectId(buffer);
2243
2364
  }
2244
2365
  static createFromHexString(hexString) {
@@ -2610,10 +2731,7 @@ const JS_INT_MIN_LONG = Long.fromNumber(JS_INT_MIN);
2610
2731
  function internalDeserialize(buffer, options, isArray) {
2611
2732
  options = options == null ? {} : options;
2612
2733
  const index = options && options.index ? options.index : 0;
2613
- const size = buffer[index] |
2614
- (buffer[index + 1] << 8) |
2615
- (buffer[index + 2] << 16) |
2616
- (buffer[index + 3] << 24);
2734
+ const size = NumberUtils.getInt32LE(buffer, index);
2617
2735
  if (size < 5) {
2618
2736
  throw new BSONError(`bson size must be >= 5, is ${size}`);
2619
2737
  }
@@ -2649,7 +2767,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2649
2767
  const validation = options.validation == null ? { utf8: true } : options.validation;
2650
2768
  let globalUTFValidation = true;
2651
2769
  let validationSetting;
2652
- const utf8KeysSet = new Set();
2770
+ let utf8KeysSet;
2653
2771
  const utf8ValidatedKeys = validation.utf8;
2654
2772
  if (typeof utf8ValidatedKeys === 'boolean') {
2655
2773
  validationSetting = utf8ValidatedKeys;
@@ -2671,6 +2789,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2671
2789
  }
2672
2790
  }
2673
2791
  if (!globalUTFValidation) {
2792
+ utf8KeysSet = new Set();
2674
2793
  for (const key of Object.keys(utf8ValidatedKeys)) {
2675
2794
  utf8KeysSet.add(key);
2676
2795
  }
@@ -2678,14 +2797,14 @@ function deserializeObject(buffer, index, options, isArray = false) {
2678
2797
  const startIndex = index;
2679
2798
  if (buffer.length < 5)
2680
2799
  throw new BSONError('corrupt bson message < 5 bytes long');
2681
- const size = buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24);
2800
+ const size = NumberUtils.getInt32LE(buffer, index);
2801
+ index += 4;
2682
2802
  if (size < 5 || size > buffer.length)
2683
2803
  throw new BSONError('corrupt bson message');
2684
2804
  const object = isArray ? [] : {};
2685
2805
  let arrayIndex = 0;
2686
2806
  const done = false;
2687
2807
  let isPossibleDBRef = isArray ? false : null;
2688
- const dataview = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
2689
2808
  while (!done) {
2690
2809
  const elementType = buffer[index++];
2691
2810
  if (elementType === 0)
@@ -2698,7 +2817,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2698
2817
  throw new BSONError('Bad BSON Document: illegal CString');
2699
2818
  const name = isArray ? arrayIndex++ : ByteUtils.toUTF8(buffer, index, i, false);
2700
2819
  let shouldValidateKey = true;
2701
- if (globalUTFValidation || utf8KeysSet.has(name)) {
2820
+ if (globalUTFValidation || utf8KeysSet?.has(name)) {
2702
2821
  shouldValidateKey = validationSetting;
2703
2822
  }
2704
2823
  else {
@@ -2710,10 +2829,8 @@ function deserializeObject(buffer, index, options, isArray = false) {
2710
2829
  let value;
2711
2830
  index = i + 1;
2712
2831
  if (elementType === BSON_DATA_STRING) {
2713
- const stringSize = buffer[index++] |
2714
- (buffer[index++] << 8) |
2715
- (buffer[index++] << 16) |
2716
- (buffer[index++] << 24);
2832
+ const stringSize = NumberUtils.getInt32LE(buffer, index);
2833
+ index += 4;
2717
2834
  if (stringSize <= 0 ||
2718
2835
  stringSize > buffer.length - index ||
2719
2836
  buffer[index + stringSize - 1] !== 0) {
@@ -2723,38 +2840,30 @@ function deserializeObject(buffer, index, options, isArray = false) {
2723
2840
  index = index + stringSize;
2724
2841
  }
2725
2842
  else if (elementType === BSON_DATA_OID) {
2726
- const oid = ByteUtils.allocate(12);
2727
- oid.set(buffer.subarray(index, index + 12));
2843
+ const oid = ByteUtils.allocateUnsafe(12);
2844
+ for (let i = 0; i < 12; i++)
2845
+ oid[i] = buffer[index + i];
2728
2846
  value = new ObjectId(oid);
2729
2847
  index = index + 12;
2730
2848
  }
2731
2849
  else if (elementType === BSON_DATA_INT && promoteValues === false) {
2732
- value = new Int32(buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24));
2850
+ value = new Int32(NumberUtils.getInt32LE(buffer, index));
2851
+ index += 4;
2733
2852
  }
2734
2853
  else if (elementType === BSON_DATA_INT) {
2735
- value =
2736
- buffer[index++] |
2737
- (buffer[index++] << 8) |
2738
- (buffer[index++] << 16) |
2739
- (buffer[index++] << 24);
2740
- }
2741
- else if (elementType === BSON_DATA_NUMBER && promoteValues === false) {
2742
- value = new Double(dataview.getFloat64(index, true));
2743
- index = index + 8;
2854
+ value = NumberUtils.getInt32LE(buffer, index);
2855
+ index += 4;
2744
2856
  }
2745
2857
  else if (elementType === BSON_DATA_NUMBER) {
2746
- value = dataview.getFloat64(index, true);
2747
- index = index + 8;
2858
+ value = NumberUtils.getFloat64LE(buffer, index);
2859
+ index += 8;
2860
+ if (promoteValues === false)
2861
+ value = new Double(value);
2748
2862
  }
2749
2863
  else if (elementType === BSON_DATA_DATE) {
2750
- const lowBits = buffer[index++] |
2751
- (buffer[index++] << 8) |
2752
- (buffer[index++] << 16) |
2753
- (buffer[index++] << 24);
2754
- const highBits = buffer[index++] |
2755
- (buffer[index++] << 8) |
2756
- (buffer[index++] << 16) |
2757
- (buffer[index++] << 24);
2864
+ const lowBits = NumberUtils.getInt32LE(buffer, index);
2865
+ const highBits = NumberUtils.getInt32LE(buffer, index + 4);
2866
+ index += 8;
2758
2867
  value = new Date(new Long(lowBits, highBits).toNumber());
2759
2868
  }
2760
2869
  else if (elementType === BSON_DATA_BOOLEAN) {
@@ -2764,10 +2873,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2764
2873
  }
2765
2874
  else if (elementType === BSON_DATA_OBJECT) {
2766
2875
  const _index = index;
2767
- const objectSize = buffer[index] |
2768
- (buffer[index + 1] << 8) |
2769
- (buffer[index + 2] << 16) |
2770
- (buffer[index + 3] << 24);
2876
+ const objectSize = NumberUtils.getInt32LE(buffer, index);
2771
2877
  if (objectSize <= 0 || objectSize > buffer.length - index)
2772
2878
  throw new BSONError('bad embedded document length in bson');
2773
2879
  if (raw) {
@@ -2784,10 +2890,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2784
2890
  }
2785
2891
  else if (elementType === BSON_DATA_ARRAY) {
2786
2892
  const _index = index;
2787
- const objectSize = buffer[index] |
2788
- (buffer[index + 1] << 8) |
2789
- (buffer[index + 2] << 16) |
2790
- (buffer[index + 3] << 24);
2893
+ const objectSize = NumberUtils.getInt32LE(buffer, index);
2791
2894
  let arrayOptions = options;
2792
2895
  const stopIndex = index + objectSize;
2793
2896
  if (fieldsAsRaw && fieldsAsRaw[name]) {
@@ -2810,40 +2913,36 @@ function deserializeObject(buffer, index, options, isArray = false) {
2810
2913
  value = null;
2811
2914
  }
2812
2915
  else if (elementType === BSON_DATA_LONG) {
2813
- const dataview = BSONDataView.fromUint8Array(buffer.subarray(index, index + 8));
2814
- const lowBits = buffer[index++] |
2815
- (buffer[index++] << 8) |
2816
- (buffer[index++] << 16) |
2817
- (buffer[index++] << 24);
2818
- const highBits = buffer[index++] |
2819
- (buffer[index++] << 8) |
2820
- (buffer[index++] << 16) |
2821
- (buffer[index++] << 24);
2822
- const long = new Long(lowBits, highBits);
2823
2916
  if (useBigInt64) {
2824
- value = dataview.getBigInt64(0, true);
2825
- }
2826
- else if (promoteLongs && promoteValues === true) {
2827
- value =
2828
- long.lessThanOrEqual(JS_INT_MAX_LONG) && long.greaterThanOrEqual(JS_INT_MIN_LONG)
2829
- ? long.toNumber()
2830
- : long;
2917
+ value = NumberUtils.getBigInt64LE(buffer, index);
2918
+ index += 8;
2831
2919
  }
2832
2920
  else {
2833
- value = long;
2921
+ const lowBits = NumberUtils.getInt32LE(buffer, index);
2922
+ const highBits = NumberUtils.getInt32LE(buffer, index + 4);
2923
+ index += 8;
2924
+ const long = new Long(lowBits, highBits);
2925
+ if (promoteLongs && promoteValues === true) {
2926
+ value =
2927
+ long.lessThanOrEqual(JS_INT_MAX_LONG) && long.greaterThanOrEqual(JS_INT_MIN_LONG)
2928
+ ? long.toNumber()
2929
+ : long;
2930
+ }
2931
+ else {
2932
+ value = long;
2933
+ }
2834
2934
  }
2835
2935
  }
2836
2936
  else if (elementType === BSON_DATA_DECIMAL128) {
2837
- const bytes = ByteUtils.allocate(16);
2838
- bytes.set(buffer.subarray(index, index + 16), 0);
2937
+ const bytes = ByteUtils.allocateUnsafe(16);
2938
+ for (let i = 0; i < 16; i++)
2939
+ bytes[i] = buffer[index + i];
2839
2940
  index = index + 16;
2840
2941
  value = new Decimal128(bytes);
2841
2942
  }
2842
2943
  else if (elementType === BSON_DATA_BINARY) {
2843
- let binarySize = buffer[index++] |
2844
- (buffer[index++] << 8) |
2845
- (buffer[index++] << 16) |
2846
- (buffer[index++] << 24);
2944
+ let binarySize = NumberUtils.getInt32LE(buffer, index);
2945
+ index += 4;
2847
2946
  const totalBinarySize = binarySize;
2848
2947
  const subType = buffer[index++];
2849
2948
  if (binarySize < 0)
@@ -2852,11 +2951,8 @@ function deserializeObject(buffer, index, options, isArray = false) {
2852
2951
  throw new BSONError('Binary type size larger than document size');
2853
2952
  if (buffer['slice'] != null) {
2854
2953
  if (subType === Binary.SUBTYPE_BYTE_ARRAY) {
2855
- binarySize =
2856
- buffer[index++] |
2857
- (buffer[index++] << 8) |
2858
- (buffer[index++] << 16) |
2859
- (buffer[index++] << 24);
2954
+ binarySize = NumberUtils.getInt32LE(buffer, index);
2955
+ index += 4;
2860
2956
  if (binarySize < 0)
2861
2957
  throw new BSONError('Negative binary type element size found for subtype 0x02');
2862
2958
  if (binarySize > totalBinarySize - 4)
@@ -2875,13 +2971,9 @@ function deserializeObject(buffer, index, options, isArray = false) {
2875
2971
  }
2876
2972
  }
2877
2973
  else {
2878
- const _buffer = ByteUtils.allocate(binarySize);
2879
2974
  if (subType === Binary.SUBTYPE_BYTE_ARRAY) {
2880
- binarySize =
2881
- buffer[index++] |
2882
- (buffer[index++] << 8) |
2883
- (buffer[index++] << 16) |
2884
- (buffer[index++] << 24);
2975
+ binarySize = NumberUtils.getInt32LE(buffer, index);
2976
+ index += 4;
2885
2977
  if (binarySize < 0)
2886
2978
  throw new BSONError('Negative binary type element size found for subtype 0x02');
2887
2979
  if (binarySize > totalBinarySize - 4)
@@ -2889,11 +2981,11 @@ function deserializeObject(buffer, index, options, isArray = false) {
2889
2981
  if (binarySize < totalBinarySize - 4)
2890
2982
  throw new BSONError('Binary type with subtype 0x02 contains too short binary size');
2891
2983
  }
2892
- for (i = 0; i < binarySize; i++) {
2893
- _buffer[i] = buffer[index + i];
2894
- }
2895
2984
  if (promoteBuffers && promoteValues) {
2896
- value = _buffer;
2985
+ value = ByteUtils.allocateUnsafe(binarySize);
2986
+ for (i = 0; i < binarySize; i++) {
2987
+ value[i] = buffer[index + i];
2988
+ }
2897
2989
  }
2898
2990
  else {
2899
2991
  value = new Binary(buffer.slice(index, index + binarySize), subType);
@@ -2957,10 +3049,8 @@ function deserializeObject(buffer, index, options, isArray = false) {
2957
3049
  value = new BSONRegExp(source, regExpOptions);
2958
3050
  }
2959
3051
  else if (elementType === BSON_DATA_SYMBOL) {
2960
- const stringSize = buffer[index++] |
2961
- (buffer[index++] << 8) |
2962
- (buffer[index++] << 16) |
2963
- (buffer[index++] << 24);
3052
+ const stringSize = NumberUtils.getInt32LE(buffer, index);
3053
+ index += 4;
2964
3054
  if (stringSize <= 0 ||
2965
3055
  stringSize > buffer.length - index ||
2966
3056
  buffer[index + stringSize - 1] !== 0) {
@@ -2971,15 +3061,11 @@ function deserializeObject(buffer, index, options, isArray = false) {
2971
3061
  index = index + stringSize;
2972
3062
  }
2973
3063
  else if (elementType === BSON_DATA_TIMESTAMP) {
2974
- const i = buffer[index++] +
2975
- buffer[index++] * (1 << 8) +
2976
- buffer[index++] * (1 << 16) +
2977
- buffer[index++] * (1 << 24);
2978
- const t = buffer[index++] +
2979
- buffer[index++] * (1 << 8) +
2980
- buffer[index++] * (1 << 16) +
2981
- buffer[index++] * (1 << 24);
2982
- value = new Timestamp({ i, t });
3064
+ value = new Timestamp({
3065
+ i: NumberUtils.getUint32LE(buffer, index),
3066
+ t: NumberUtils.getUint32LE(buffer, index + 4)
3067
+ });
3068
+ index += 8;
2983
3069
  }
2984
3070
  else if (elementType === BSON_DATA_MIN_KEY) {
2985
3071
  value = new MinKey();
@@ -2988,10 +3074,8 @@ function deserializeObject(buffer, index, options, isArray = false) {
2988
3074
  value = new MaxKey();
2989
3075
  }
2990
3076
  else if (elementType === BSON_DATA_CODE) {
2991
- const stringSize = buffer[index++] |
2992
- (buffer[index++] << 8) |
2993
- (buffer[index++] << 16) |
2994
- (buffer[index++] << 24);
3077
+ const stringSize = NumberUtils.getInt32LE(buffer, index);
3078
+ index += 4;
2995
3079
  if (stringSize <= 0 ||
2996
3080
  stringSize > buffer.length - index ||
2997
3081
  buffer[index + stringSize - 1] !== 0) {
@@ -3002,17 +3086,13 @@ function deserializeObject(buffer, index, options, isArray = false) {
3002
3086
  index = index + stringSize;
3003
3087
  }
3004
3088
  else if (elementType === BSON_DATA_CODE_W_SCOPE) {
3005
- const totalSize = buffer[index++] |
3006
- (buffer[index++] << 8) |
3007
- (buffer[index++] << 16) |
3008
- (buffer[index++] << 24);
3089
+ const totalSize = NumberUtils.getInt32LE(buffer, index);
3090
+ index += 4;
3009
3091
  if (totalSize < 4 + 4 + 4 + 1) {
3010
3092
  throw new BSONError('code_w_scope total size shorter minimum expected length');
3011
3093
  }
3012
- const stringSize = buffer[index++] |
3013
- (buffer[index++] << 8) |
3014
- (buffer[index++] << 16) |
3015
- (buffer[index++] << 24);
3094
+ const stringSize = NumberUtils.getInt32LE(buffer, index);
3095
+ index += 4;
3016
3096
  if (stringSize <= 0 ||
3017
3097
  stringSize > buffer.length - index ||
3018
3098
  buffer[index + stringSize - 1] !== 0) {
@@ -3021,10 +3101,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
3021
3101
  const functionString = ByteUtils.toUTF8(buffer, index, index + stringSize - 1, shouldValidateKey);
3022
3102
  index = index + stringSize;
3023
3103
  const _index = index;
3024
- const objectSize = buffer[index] |
3025
- (buffer[index + 1] << 8) |
3026
- (buffer[index + 2] << 16) |
3027
- (buffer[index + 3] << 24);
3104
+ const objectSize = NumberUtils.getInt32LE(buffer, index);
3028
3105
  const scopeObject = deserializeObject(buffer, _index, options, false);
3029
3106
  index = index + objectSize;
3030
3107
  if (totalSize < 4 + 4 + objectSize + stringSize) {
@@ -3036,10 +3113,8 @@ function deserializeObject(buffer, index, options, isArray = false) {
3036
3113
  value = new Code(functionString, scopeObject);
3037
3114
  }
3038
3115
  else if (elementType === BSON_DATA_DBPOINTER) {
3039
- const stringSize = buffer[index++] |
3040
- (buffer[index++] << 8) |
3041
- (buffer[index++] << 16) |
3042
- (buffer[index++] << 24);
3116
+ const stringSize = NumberUtils.getInt32LE(buffer, index);
3117
+ index += 4;
3043
3118
  if (stringSize <= 0 ||
3044
3119
  stringSize > buffer.length - index ||
3045
3120
  buffer[index + stringSize - 1] !== 0)
@@ -3051,8 +3126,9 @@ function deserializeObject(buffer, index, options, isArray = false) {
3051
3126
  }
3052
3127
  const namespace = ByteUtils.toUTF8(buffer, index, index + stringSize - 1, false);
3053
3128
  index = index + stringSize;
3054
- const oidBuffer = ByteUtils.allocate(12);
3055
- oidBuffer.set(buffer.subarray(index, index + 12), 0);
3129
+ const oidBuffer = ByteUtils.allocateUnsafe(12);
3130
+ for (let i = 0; i < 12; i++)
3131
+ oidBuffer[i] = buffer[index + i];
3056
3132
  const oid = new ObjectId(oidBuffer);
3057
3133
  index = index + 12;
3058
3134
  value = new DBRef(namespace, oid);
@@ -3097,17 +3173,11 @@ function serializeString(buffer, key, value, index) {
3097
3173
  index = index + numberOfWrittenBytes + 1;
3098
3174
  buffer[index - 1] = 0;
3099
3175
  const size = ByteUtils.encodeUTF8Into(buffer, value, index + 4);
3100
- buffer[index + 3] = ((size + 1) >> 24) & 0xff;
3101
- buffer[index + 2] = ((size + 1) >> 16) & 0xff;
3102
- buffer[index + 1] = ((size + 1) >> 8) & 0xff;
3103
- buffer[index] = (size + 1) & 0xff;
3176
+ NumberUtils.setInt32LE(buffer, index, size + 1);
3104
3177
  index = index + 4 + size;
3105
3178
  buffer[index++] = 0;
3106
3179
  return index;
3107
3180
  }
3108
- const NUMBER_SPACE = new DataView(new ArrayBuffer(8), 0, 8);
3109
- const FOUR_BYTE_VIEW_ON_NUMBER = new Uint8Array(NUMBER_SPACE.buffer, 0, 4);
3110
- const EIGHT_BYTE_VIEW_ON_NUMBER = new Uint8Array(NUMBER_SPACE.buffer, 0, 8);
3111
3181
  function serializeNumber(buffer, key, value, index) {
3112
3182
  const isNegativeZero = Object.is(value, -0);
3113
3183
  const type = !isNegativeZero &&
@@ -3116,19 +3186,16 @@ function serializeNumber(buffer, key, value, index) {
3116
3186
  value >= BSON_INT32_MIN
3117
3187
  ? BSON_DATA_INT
3118
3188
  : BSON_DATA_NUMBER;
3119
- if (type === BSON_DATA_INT) {
3120
- NUMBER_SPACE.setInt32(0, value, true);
3121
- }
3122
- else {
3123
- NUMBER_SPACE.setFloat64(0, value, true);
3124
- }
3125
- const bytes = type === BSON_DATA_INT ? FOUR_BYTE_VIEW_ON_NUMBER : EIGHT_BYTE_VIEW_ON_NUMBER;
3126
3189
  buffer[index++] = type;
3127
3190
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3128
3191
  index = index + numberOfWrittenBytes;
3129
3192
  buffer[index++] = 0x00;
3130
- buffer.set(bytes, index);
3131
- index += bytes.byteLength;
3193
+ if (type === BSON_DATA_INT) {
3194
+ index += NumberUtils.setInt32LE(buffer, index, value);
3195
+ }
3196
+ else {
3197
+ index += NumberUtils.setFloat64LE(buffer, index, value);
3198
+ }
3132
3199
  return index;
3133
3200
  }
3134
3201
  function serializeBigInt(buffer, key, value, index) {
@@ -3136,9 +3203,7 @@ function serializeBigInt(buffer, key, value, index) {
3136
3203
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3137
3204
  index += numberOfWrittenBytes;
3138
3205
  buffer[index++] = 0;
3139
- NUMBER_SPACE.setBigInt64(0, value, true);
3140
- buffer.set(EIGHT_BYTE_VIEW_ON_NUMBER, index);
3141
- index += EIGHT_BYTE_VIEW_ON_NUMBER.byteLength;
3206
+ index += NumberUtils.setBigInt64LE(buffer, index, value);
3142
3207
  return index;
3143
3208
  }
3144
3209
  function serializeNull(buffer, key, _, index) {
@@ -3164,14 +3229,8 @@ function serializeDate(buffer, key, value, index) {
3164
3229
  const dateInMilis = Long.fromNumber(value.getTime());
3165
3230
  const lowBits = dateInMilis.getLowBits();
3166
3231
  const highBits = dateInMilis.getHighBits();
3167
- buffer[index++] = lowBits & 0xff;
3168
- buffer[index++] = (lowBits >> 8) & 0xff;
3169
- buffer[index++] = (lowBits >> 16) & 0xff;
3170
- buffer[index++] = (lowBits >> 24) & 0xff;
3171
- buffer[index++] = highBits & 0xff;
3172
- buffer[index++] = (highBits >> 8) & 0xff;
3173
- buffer[index++] = (highBits >> 16) & 0xff;
3174
- buffer[index++] = (highBits >> 24) & 0xff;
3232
+ index += NumberUtils.setInt32LE(buffer, index, lowBits);
3233
+ index += NumberUtils.setInt32LE(buffer, index, highBits);
3175
3234
  return index;
3176
3235
  }
3177
3236
  function serializeRegExp(buffer, key, value, index) {
@@ -3228,15 +3287,7 @@ function serializeObjectId(buffer, key, value, index) {
3228
3287
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3229
3288
  index = index + numberOfWrittenBytes;
3230
3289
  buffer[index++] = 0;
3231
- const idValue = value.id;
3232
- if (isUint8Array(idValue)) {
3233
- for (let i = 0; i < 12; i++) {
3234
- buffer[index++] = idValue[i];
3235
- }
3236
- }
3237
- else {
3238
- throw new BSONError('object [' + JSON.stringify(value) + '] is not a valid ObjectId');
3239
- }
3290
+ index += value.serializeInto(buffer, index);
3240
3291
  return index;
3241
3292
  }
3242
3293
  function serializeBuffer(buffer, key, value, index) {
@@ -3245,12 +3296,15 @@ function serializeBuffer(buffer, key, value, index) {
3245
3296
  index = index + numberOfWrittenBytes;
3246
3297
  buffer[index++] = 0;
3247
3298
  const size = value.length;
3248
- buffer[index++] = size & 0xff;
3249
- buffer[index++] = (size >> 8) & 0xff;
3250
- buffer[index++] = (size >> 16) & 0xff;
3251
- buffer[index++] = (size >> 24) & 0xff;
3299
+ index += NumberUtils.setInt32LE(buffer, index, size);
3252
3300
  buffer[index++] = BSON_BINARY_SUBTYPE_DEFAULT;
3253
- buffer.set(value, index);
3301
+ if (size <= 16) {
3302
+ for (let i = 0; i < size; i++)
3303
+ buffer[index + i] = value[i];
3304
+ }
3305
+ else {
3306
+ buffer.set(value, index);
3307
+ }
3254
3308
  index = index + size;
3255
3309
  return index;
3256
3310
  }
@@ -3272,7 +3326,8 @@ function serializeDecimal128(buffer, key, value, index) {
3272
3326
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3273
3327
  index = index + numberOfWrittenBytes;
3274
3328
  buffer[index++] = 0;
3275
- buffer.set(value.bytes.subarray(0, 16), index);
3329
+ for (let i = 0; i < 16; i++)
3330
+ buffer[index + i] = value.bytes[i];
3276
3331
  return index + 16;
3277
3332
  }
3278
3333
  function serializeLong(buffer, key, value, index) {
@@ -3283,14 +3338,8 @@ function serializeLong(buffer, key, value, index) {
3283
3338
  buffer[index++] = 0;
3284
3339
  const lowBits = value.getLowBits();
3285
3340
  const highBits = value.getHighBits();
3286
- buffer[index++] = lowBits & 0xff;
3287
- buffer[index++] = (lowBits >> 8) & 0xff;
3288
- buffer[index++] = (lowBits >> 16) & 0xff;
3289
- buffer[index++] = (lowBits >> 24) & 0xff;
3290
- buffer[index++] = highBits & 0xff;
3291
- buffer[index++] = (highBits >> 8) & 0xff;
3292
- buffer[index++] = (highBits >> 16) & 0xff;
3293
- buffer[index++] = (highBits >> 24) & 0xff;
3341
+ index += NumberUtils.setInt32LE(buffer, index, lowBits);
3342
+ index += NumberUtils.setInt32LE(buffer, index, highBits);
3294
3343
  return index;
3295
3344
  }
3296
3345
  function serializeInt32(buffer, key, value, index) {
@@ -3299,10 +3348,7 @@ function serializeInt32(buffer, key, value, index) {
3299
3348
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3300
3349
  index = index + numberOfWrittenBytes;
3301
3350
  buffer[index++] = 0;
3302
- buffer[index++] = value & 0xff;
3303
- buffer[index++] = (value >> 8) & 0xff;
3304
- buffer[index++] = (value >> 16) & 0xff;
3305
- buffer[index++] = (value >> 24) & 0xff;
3351
+ index += NumberUtils.setInt32LE(buffer, index, value);
3306
3352
  return index;
3307
3353
  }
3308
3354
  function serializeDouble(buffer, key, value, index) {
@@ -3310,9 +3356,7 @@ function serializeDouble(buffer, key, value, index) {
3310
3356
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3311
3357
  index = index + numberOfWrittenBytes;
3312
3358
  buffer[index++] = 0;
3313
- NUMBER_SPACE.setFloat64(0, value.value, true);
3314
- buffer.set(EIGHT_BYTE_VIEW_ON_NUMBER, index);
3315
- index = index + 8;
3359
+ index += NumberUtils.setFloat64LE(buffer, index, value.value);
3316
3360
  return index;
3317
3361
  }
3318
3362
  function serializeFunction(buffer, key, value, index) {
@@ -3322,10 +3366,7 @@ function serializeFunction(buffer, key, value, index) {
3322
3366
  buffer[index++] = 0;
3323
3367
  const functionString = value.toString();
3324
3368
  const size = ByteUtils.encodeUTF8Into(buffer, functionString, index + 4) + 1;
3325
- buffer[index] = size & 0xff;
3326
- buffer[index + 1] = (size >> 8) & 0xff;
3327
- buffer[index + 2] = (size >> 16) & 0xff;
3328
- buffer[index + 3] = (size >> 24) & 0xff;
3369
+ NumberUtils.setInt32LE(buffer, index, size);
3329
3370
  index = index + 4 + size - 1;
3330
3371
  buffer[index++] = 0;
3331
3372
  return index;
@@ -3340,19 +3381,13 @@ function serializeCode(buffer, key, value, index, checkKeys = false, depth = 0,
3340
3381
  const functionString = value.code;
3341
3382
  index = index + 4;
3342
3383
  const codeSize = ByteUtils.encodeUTF8Into(buffer, functionString, index + 4) + 1;
3343
- buffer[index] = codeSize & 0xff;
3344
- buffer[index + 1] = (codeSize >> 8) & 0xff;
3345
- buffer[index + 2] = (codeSize >> 16) & 0xff;
3346
- buffer[index + 3] = (codeSize >> 24) & 0xff;
3384
+ NumberUtils.setInt32LE(buffer, index, codeSize);
3347
3385
  buffer[index + 4 + codeSize - 1] = 0;
3348
3386
  index = index + codeSize + 4;
3349
3387
  const endIndex = serializeInto(buffer, value.scope, checkKeys, index, depth + 1, serializeFunctions, ignoreUndefined, path);
3350
3388
  index = endIndex - 1;
3351
3389
  const totalSize = endIndex - startIndex;
3352
- buffer[startIndex++] = totalSize & 0xff;
3353
- buffer[startIndex++] = (totalSize >> 8) & 0xff;
3354
- buffer[startIndex++] = (totalSize >> 16) & 0xff;
3355
- buffer[startIndex++] = (totalSize >> 24) & 0xff;
3390
+ startIndex += NumberUtils.setInt32LE(buffer, startIndex, totalSize);
3356
3391
  buffer[index++] = 0;
3357
3392
  }
3358
3393
  else {
@@ -3362,10 +3397,7 @@ function serializeCode(buffer, key, value, index, checkKeys = false, depth = 0,
3362
3397
  buffer[index++] = 0;
3363
3398
  const functionString = value.code.toString();
3364
3399
  const size = ByteUtils.encodeUTF8Into(buffer, functionString, index + 4) + 1;
3365
- buffer[index] = size & 0xff;
3366
- buffer[index + 1] = (size >> 8) & 0xff;
3367
- buffer[index + 2] = (size >> 16) & 0xff;
3368
- buffer[index + 3] = (size >> 24) & 0xff;
3400
+ NumberUtils.setInt32LE(buffer, index, size);
3369
3401
  index = index + 4 + size - 1;
3370
3402
  buffer[index++] = 0;
3371
3403
  }
@@ -3380,19 +3412,19 @@ function serializeBinary(buffer, key, value, index) {
3380
3412
  let size = value.position;
3381
3413
  if (value.sub_type === Binary.SUBTYPE_BYTE_ARRAY)
3382
3414
  size = size + 4;
3383
- buffer[index++] = size & 0xff;
3384
- buffer[index++] = (size >> 8) & 0xff;
3385
- buffer[index++] = (size >> 16) & 0xff;
3386
- buffer[index++] = (size >> 24) & 0xff;
3415
+ index += NumberUtils.setInt32LE(buffer, index, size);
3387
3416
  buffer[index++] = value.sub_type;
3388
3417
  if (value.sub_type === Binary.SUBTYPE_BYTE_ARRAY) {
3389
3418
  size = size - 4;
3390
- buffer[index++] = size & 0xff;
3391
- buffer[index++] = (size >> 8) & 0xff;
3392
- buffer[index++] = (size >> 16) & 0xff;
3393
- buffer[index++] = (size >> 24) & 0xff;
3419
+ index += NumberUtils.setInt32LE(buffer, index, size);
3420
+ }
3421
+ if (size <= 16) {
3422
+ for (let i = 0; i < size; i++)
3423
+ buffer[index + i] = data[i];
3424
+ }
3425
+ else {
3426
+ buffer.set(data, index);
3394
3427
  }
3395
- buffer.set(data, index);
3396
3428
  index = index + value.position;
3397
3429
  return index;
3398
3430
  }
@@ -3402,12 +3434,9 @@ function serializeSymbol(buffer, key, value, index) {
3402
3434
  index = index + numberOfWrittenBytes;
3403
3435
  buffer[index++] = 0;
3404
3436
  const size = ByteUtils.encodeUTF8Into(buffer, value.value, index + 4) + 1;
3405
- buffer[index] = size & 0xff;
3406
- buffer[index + 1] = (size >> 8) & 0xff;
3407
- buffer[index + 2] = (size >> 16) & 0xff;
3408
- buffer[index + 3] = (size >> 24) & 0xff;
3437
+ NumberUtils.setInt32LE(buffer, index, size);
3409
3438
  index = index + 4 + size - 1;
3410
- buffer[index++] = 0x00;
3439
+ buffer[index++] = 0;
3411
3440
  return index;
3412
3441
  }
3413
3442
  function serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path) {
@@ -3426,10 +3455,7 @@ function serializeDBRef(buffer, key, value, index, depth, serializeFunctions, pa
3426
3455
  output = Object.assign(output, value.fields);
3427
3456
  const endIndex = serializeInto(buffer, output, false, index, depth + 1, serializeFunctions, true, path);
3428
3457
  const size = endIndex - startIndex;
3429
- buffer[startIndex++] = size & 0xff;
3430
- buffer[startIndex++] = (size >> 8) & 0xff;
3431
- buffer[startIndex++] = (size >> 16) & 0xff;
3432
- buffer[startIndex++] = (size >> 24) & 0xff;
3458
+ startIndex += NumberUtils.setInt32LE(buffer, index, size);
3433
3459
  return endIndex;
3434
3460
  }
3435
3461
  function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializeFunctions, ignoreUndefined, path) {
@@ -3565,7 +3591,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3565
3591
  if ('$' === key[0]) {
3566
3592
  throw new BSONError('key ' + key + " must not start with '$'");
3567
3593
  }
3568
- else if (~key.indexOf('.')) {
3594
+ else if (key.includes('.')) {
3569
3595
  throw new BSONError('key ' + key + " must not contain '.'");
3570
3596
  }
3571
3597
  }
@@ -3663,7 +3689,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3663
3689
  if ('$' === key[0]) {
3664
3690
  throw new BSONError('key ' + key + " must not start with '$'");
3665
3691
  }
3666
- else if (~key.indexOf('.')) {
3692
+ else if (key.includes('.')) {
3667
3693
  throw new BSONError('key ' + key + " must not contain '.'");
3668
3694
  }
3669
3695
  }
@@ -3747,10 +3773,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3747
3773
  path.delete(object);
3748
3774
  buffer[index++] = 0x00;
3749
3775
  const size = index - startingIndex;
3750
- buffer[startingIndex++] = size & 0xff;
3751
- buffer[startingIndex++] = (size >> 8) & 0xff;
3752
- buffer[startingIndex++] = (size >> 16) & 0xff;
3753
- buffer[startingIndex++] = (size >> 24) & 0xff;
3776
+ startingIndex += NumberUtils.setInt32LE(buffer, startingIndex, size);
3754
3777
  return index;
3755
3778
  }
3756
3779
 
@@ -4080,7 +4103,7 @@ function serialize(object, options = {}) {
4080
4103
  buffer = ByteUtils.allocate(minInternalBufferSize);
4081
4104
  }
4082
4105
  const serializationIndex = serializeInto(buffer, object, checkKeys, 0, 0, serializeFunctions, ignoreUndefined, null);
4083
- const finishedBuffer = ByteUtils.allocate(serializationIndex);
4106
+ const finishedBuffer = ByteUtils.allocateUnsafe(serializationIndex);
4084
4107
  finishedBuffer.set(buffer.subarray(0, serializationIndex), 0);
4085
4108
  return finishedBuffer;
4086
4109
  }
@@ -4107,10 +4130,7 @@ function deserializeStream(data, startIndex, numberOfDocuments, documents, docSt
4107
4130
  const bufferData = ByteUtils.toLocalBufferType(data);
4108
4131
  let index = startIndex;
4109
4132
  for (let i = 0; i < numberOfDocuments; i++) {
4110
- const size = bufferData[index] |
4111
- (bufferData[index + 1] << 8) |
4112
- (bufferData[index + 2] << 16) |
4113
- (bufferData[index + 3] << 24);
4133
+ const size = NumberUtils.getInt32LE(bufferData, index);
4114
4134
  internalOptions.index = index;
4115
4135
  documents[docStartIndex + i] = internalDeserialize(bufferData, internalOptions);
4116
4136
  index = index + size;