bson 6.3.0 → 6.4.1

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.rn.cjs CHANGED
@@ -177,7 +177,7 @@ function validateUtf8(bytes, start, end) {
177
177
  return !continuation;
178
178
  }
179
179
 
180
- function tryLatin(uint8array, start, end) {
180
+ function tryReadBasicLatin(uint8array, start, end) {
181
181
  if (uint8array.length === 0) {
182
182
  return '';
183
183
  }
@@ -212,6 +212,21 @@ function tryLatin(uint8array, start, end) {
212
212
  }
213
213
  return String.fromCharCode(...latinBytes);
214
214
  }
215
+ function tryWriteBasicLatin(destination, source, offset) {
216
+ if (source.length === 0)
217
+ return 0;
218
+ if (source.length > 25)
219
+ return null;
220
+ if (destination.length - offset < source.length)
221
+ return null;
222
+ for (let charOffset = 0, destinationOffset = offset; charOffset < source.length; charOffset++, destinationOffset++) {
223
+ const char = source.charCodeAt(charOffset);
224
+ if (char > 127)
225
+ return null;
226
+ destination[destinationOffset] = char;
227
+ }
228
+ return source.length;
229
+ }
215
230
 
216
231
  function nodejsMathRandomBytes(byteLength) {
217
232
  return nodeJsByteUtils.fromNumberArray(Array.from({ length: byteLength }, () => Math.floor(Math.random() * 256)));
@@ -244,6 +259,9 @@ const nodeJsByteUtils = {
244
259
  allocate(size) {
245
260
  return Buffer.alloc(size);
246
261
  },
262
+ allocateUnsafe(size) {
263
+ return Buffer.allocUnsafe(size);
264
+ },
247
265
  equals(a, b) {
248
266
  return nodeJsByteUtils.toLocalBufferType(a).equals(b);
249
267
  },
@@ -268,11 +286,8 @@ const nodeJsByteUtils = {
268
286
  toHex(buffer) {
269
287
  return nodeJsByteUtils.toLocalBufferType(buffer).toString('hex');
270
288
  },
271
- fromUTF8(text) {
272
- return Buffer.from(text, 'utf8');
273
- },
274
289
  toUTF8(buffer, start, end, fatal) {
275
- const basicLatin = end - start <= 20 ? tryLatin(buffer, start, end) : null;
290
+ const basicLatin = end - start <= 20 ? tryReadBasicLatin(buffer, start, end) : null;
276
291
  if (basicLatin != null) {
277
292
  return basicLatin;
278
293
  }
@@ -293,6 +308,10 @@ const nodeJsByteUtils = {
293
308
  return Buffer.byteLength(input, 'utf8');
294
309
  },
295
310
  encodeUTF8Into(buffer, source, byteOffset) {
311
+ const latinBytesWritten = tryWriteBasicLatin(buffer, source, byteOffset);
312
+ if (latinBytesWritten != null) {
313
+ return latinBytesWritten;
314
+ }
296
315
  return nodeJsByteUtils.toLocalBufferType(buffer).write(source, byteOffset, undefined, 'utf8');
297
316
  },
298
317
  randomBytes: nodejsRandomBytes
@@ -350,6 +369,9 @@ const webByteUtils = {
350
369
  }
351
370
  return new Uint8Array(size);
352
371
  },
372
+ allocateUnsafe(size) {
373
+ return webByteUtils.allocate(size);
374
+ },
353
375
  equals(a, b) {
354
376
  if (a.byteLength !== b.byteLength) {
355
377
  return false;
@@ -396,11 +418,8 @@ const webByteUtils = {
396
418
  toHex(uint8array) {
397
419
  return Array.from(uint8array, byte => byte.toString(16).padStart(2, '0')).join('');
398
420
  },
399
- fromUTF8(text) {
400
- return new TextEncoder().encode(text);
401
- },
402
421
  toUTF8(uint8array, start, end, fatal) {
403
- const basicLatin = end - start <= 20 ? tryLatin(uint8array, start, end) : null;
422
+ const basicLatin = end - start <= 20 ? tryReadBasicLatin(uint8array, start, end) : null;
404
423
  if (basicLatin != null) {
405
424
  return basicLatin;
406
425
  }
@@ -415,11 +434,11 @@ const webByteUtils = {
415
434
  return new TextDecoder('utf8', { fatal }).decode(uint8array.slice(start, end));
416
435
  },
417
436
  utf8ByteLength(input) {
418
- return webByteUtils.fromUTF8(input).byteLength;
437
+ return new TextEncoder().encode(input).byteLength;
419
438
  },
420
- encodeUTF8Into(buffer, source, byteOffset) {
421
- const bytes = webByteUtils.fromUTF8(source);
422
- buffer.set(bytes, byteOffset);
439
+ encodeUTF8Into(uint8array, source, byteOffset) {
440
+ const bytes = new TextEncoder().encode(source);
441
+ uint8array.set(bytes, byteOffset);
423
442
  return bytes.byteLength;
424
443
  },
425
444
  randomBytes: webRandomBytes
@@ -427,11 +446,6 @@ const webByteUtils = {
427
446
 
428
447
  const hasGlobalBuffer = typeof Buffer === 'function' && Buffer.prototype?._isBuffer !== true;
429
448
  const ByteUtils = hasGlobalBuffer ? nodeJsByteUtils : webByteUtils;
430
- class BSONDataView extends DataView {
431
- static fromUint8Array(input) {
432
- return new DataView(input.buffer, input.byteOffset, input.byteLength);
433
- }
434
- }
435
449
 
436
450
  class BSONValue {
437
451
  get [Symbol.for('@@mdb.bson.version')]() {
@@ -1851,7 +1865,7 @@ class Decimal128 extends BSONValue {
1851
1865
  if (isNegative) {
1852
1866
  dec.high = dec.high.or(Long.fromString('9223372036854775808'));
1853
1867
  }
1854
- const buffer = ByteUtils.allocate(16);
1868
+ const buffer = ByteUtils.allocateUnsafe(16);
1855
1869
  index = 0;
1856
1870
  buffer[index++] = dec.low.low & 0xff;
1857
1871
  buffer[index++] = (dec.low.low >> 8) & 0xff;
@@ -2124,9 +2138,132 @@ class MinKey extends BSONValue {
2124
2138
  }
2125
2139
  }
2126
2140
 
2141
+ const FLOAT = new Float64Array(1);
2142
+ const FLOAT_BYTES = new Uint8Array(FLOAT.buffer, 0, 8);
2143
+ FLOAT[0] = -1;
2144
+ const isBigEndian = FLOAT_BYTES[7] === 0;
2145
+ const NumberUtils = {
2146
+ getInt32LE(source, offset) {
2147
+ return (source[offset] |
2148
+ (source[offset + 1] << 8) |
2149
+ (source[offset + 2] << 16) |
2150
+ (source[offset + 3] << 24));
2151
+ },
2152
+ getUint32LE(source, offset) {
2153
+ return (source[offset] +
2154
+ source[offset + 1] * 256 +
2155
+ source[offset + 2] * 65536 +
2156
+ source[offset + 3] * 16777216);
2157
+ },
2158
+ getUint32BE(source, offset) {
2159
+ return (source[offset + 3] +
2160
+ source[offset + 2] * 256 +
2161
+ source[offset + 1] * 65536 +
2162
+ source[offset] * 16777216);
2163
+ },
2164
+ getBigInt64LE(source, offset) {
2165
+ const hi = BigInt(source[offset + 4] +
2166
+ source[offset + 5] * 256 +
2167
+ source[offset + 6] * 65536 +
2168
+ (source[offset + 7] << 24));
2169
+ const lo = BigInt(source[offset] +
2170
+ source[offset + 1] * 256 +
2171
+ source[offset + 2] * 65536 +
2172
+ source[offset + 3] * 16777216);
2173
+ return (hi << BigInt(32)) + lo;
2174
+ },
2175
+ getFloat64LE: isBigEndian
2176
+ ? (source, offset) => {
2177
+ FLOAT_BYTES[7] = source[offset];
2178
+ FLOAT_BYTES[6] = source[offset + 1];
2179
+ FLOAT_BYTES[5] = source[offset + 2];
2180
+ FLOAT_BYTES[4] = source[offset + 3];
2181
+ FLOAT_BYTES[3] = source[offset + 4];
2182
+ FLOAT_BYTES[2] = source[offset + 5];
2183
+ FLOAT_BYTES[1] = source[offset + 6];
2184
+ FLOAT_BYTES[0] = source[offset + 7];
2185
+ return FLOAT[0];
2186
+ }
2187
+ : (source, offset) => {
2188
+ FLOAT_BYTES[0] = source[offset];
2189
+ FLOAT_BYTES[1] = source[offset + 1];
2190
+ FLOAT_BYTES[2] = source[offset + 2];
2191
+ FLOAT_BYTES[3] = source[offset + 3];
2192
+ FLOAT_BYTES[4] = source[offset + 4];
2193
+ FLOAT_BYTES[5] = source[offset + 5];
2194
+ FLOAT_BYTES[6] = source[offset + 6];
2195
+ FLOAT_BYTES[7] = source[offset + 7];
2196
+ return FLOAT[0];
2197
+ },
2198
+ setInt32BE(destination, offset, value) {
2199
+ destination[offset + 3] = value;
2200
+ value >>>= 8;
2201
+ destination[offset + 2] = value;
2202
+ value >>>= 8;
2203
+ destination[offset + 1] = value;
2204
+ value >>>= 8;
2205
+ destination[offset] = value;
2206
+ return 4;
2207
+ },
2208
+ setInt32LE(destination, offset, value) {
2209
+ destination[offset] = value;
2210
+ value >>>= 8;
2211
+ destination[offset + 1] = value;
2212
+ value >>>= 8;
2213
+ destination[offset + 2] = value;
2214
+ value >>>= 8;
2215
+ destination[offset + 3] = value;
2216
+ return 4;
2217
+ },
2218
+ setBigInt64LE(destination, offset, value) {
2219
+ const mask32bits = BigInt(4294967295);
2220
+ let lo = Number(value & mask32bits);
2221
+ destination[offset] = lo;
2222
+ lo >>= 8;
2223
+ destination[offset + 1] = lo;
2224
+ lo >>= 8;
2225
+ destination[offset + 2] = lo;
2226
+ lo >>= 8;
2227
+ destination[offset + 3] = lo;
2228
+ let hi = Number((value >> BigInt(32)) & mask32bits);
2229
+ destination[offset + 4] = hi;
2230
+ hi >>= 8;
2231
+ destination[offset + 5] = hi;
2232
+ hi >>= 8;
2233
+ destination[offset + 6] = hi;
2234
+ hi >>= 8;
2235
+ destination[offset + 7] = hi;
2236
+ return 8;
2237
+ },
2238
+ setFloat64LE: isBigEndian
2239
+ ? (destination, offset, value) => {
2240
+ FLOAT[0] = value;
2241
+ destination[offset] = FLOAT_BYTES[7];
2242
+ destination[offset + 1] = FLOAT_BYTES[6];
2243
+ destination[offset + 2] = FLOAT_BYTES[5];
2244
+ destination[offset + 3] = FLOAT_BYTES[4];
2245
+ destination[offset + 4] = FLOAT_BYTES[3];
2246
+ destination[offset + 5] = FLOAT_BYTES[2];
2247
+ destination[offset + 6] = FLOAT_BYTES[1];
2248
+ destination[offset + 7] = FLOAT_BYTES[0];
2249
+ return 8;
2250
+ }
2251
+ : (destination, offset, value) => {
2252
+ FLOAT[0] = value;
2253
+ destination[offset] = FLOAT_BYTES[0];
2254
+ destination[offset + 1] = FLOAT_BYTES[1];
2255
+ destination[offset + 2] = FLOAT_BYTES[2];
2256
+ destination[offset + 3] = FLOAT_BYTES[3];
2257
+ destination[offset + 4] = FLOAT_BYTES[4];
2258
+ destination[offset + 5] = FLOAT_BYTES[5];
2259
+ destination[offset + 6] = FLOAT_BYTES[6];
2260
+ destination[offset + 7] = FLOAT_BYTES[7];
2261
+ return 8;
2262
+ }
2263
+ };
2264
+
2127
2265
  const checkForHexRegExp = new RegExp('^[0-9a-fA-F]{24}$');
2128
2266
  let PROCESS_UNIQUE = null;
2129
- const kId = Symbol('id');
2130
2267
  class ObjectId extends BSONValue {
2131
2268
  get _bsontype() {
2132
2269
  return 'ObjectId';
@@ -2149,14 +2286,14 @@ class ObjectId extends BSONValue {
2149
2286
  workingId = inputId;
2150
2287
  }
2151
2288
  if (workingId == null || typeof workingId === 'number') {
2152
- this[kId] = ObjectId.generate(typeof workingId === 'number' ? workingId : undefined);
2289
+ this.buffer = ObjectId.generate(typeof workingId === 'number' ? workingId : undefined);
2153
2290
  }
2154
2291
  else if (ArrayBuffer.isView(workingId) && workingId.byteLength === 12) {
2155
- this[kId] = ByteUtils.toLocalBufferType(workingId);
2292
+ this.buffer = ByteUtils.toLocalBufferType(workingId);
2156
2293
  }
2157
2294
  else if (typeof workingId === 'string') {
2158
2295
  if (workingId.length === 24 && checkForHexRegExp.test(workingId)) {
2159
- this[kId] = ByteUtils.fromHex(workingId);
2296
+ this.buffer = ByteUtils.fromHex(workingId);
2160
2297
  }
2161
2298
  else {
2162
2299
  throw new BSONError('input must be a 24 character hex string, 12 byte Uint8Array, or an integer');
@@ -2170,10 +2307,10 @@ class ObjectId extends BSONValue {
2170
2307
  }
2171
2308
  }
2172
2309
  get id() {
2173
- return this[kId];
2310
+ return this.buffer;
2174
2311
  }
2175
2312
  set id(value) {
2176
- this[kId] = value;
2313
+ this.buffer = value;
2177
2314
  if (ObjectId.cacheHexString) {
2178
2315
  this.__id = ByteUtils.toHex(value);
2179
2316
  }
@@ -2196,8 +2333,8 @@ class ObjectId extends BSONValue {
2196
2333
  time = Math.floor(Date.now() / 1000);
2197
2334
  }
2198
2335
  const inc = ObjectId.getInc();
2199
- const buffer = ByteUtils.allocate(12);
2200
- BSONDataView.fromUint8Array(buffer).setUint32(0, time, false);
2336
+ const buffer = ByteUtils.allocateUnsafe(12);
2337
+ NumberUtils.setInt32BE(buffer, 0, time);
2201
2338
  if (PROCESS_UNIQUE === null) {
2202
2339
  PROCESS_UNIQUE = ByteUtils.randomBytes(5);
2203
2340
  }
@@ -2232,7 +2369,7 @@ class ObjectId extends BSONValue {
2232
2369
  return false;
2233
2370
  }
2234
2371
  if (ObjectId.is(otherId)) {
2235
- return this[kId][11] === otherId[kId][11] && ByteUtils.equals(this[kId], otherId[kId]);
2372
+ return (this.buffer[11] === otherId.buffer[11] && ByteUtils.equals(this.buffer, otherId.buffer));
2236
2373
  }
2237
2374
  if (typeof otherId === 'string') {
2238
2375
  return otherId.toLowerCase() === this.toHexString();
@@ -2246,16 +2383,33 @@ class ObjectId extends BSONValue {
2246
2383
  }
2247
2384
  getTimestamp() {
2248
2385
  const timestamp = new Date();
2249
- const time = BSONDataView.fromUint8Array(this.id).getUint32(0, false);
2386
+ const time = NumberUtils.getUint32BE(this.buffer, 0);
2250
2387
  timestamp.setTime(Math.floor(time) * 1000);
2251
2388
  return timestamp;
2252
2389
  }
2253
2390
  static createPk() {
2254
2391
  return new ObjectId();
2255
2392
  }
2393
+ serializeInto(uint8array, index) {
2394
+ uint8array[index] = this.buffer[0];
2395
+ uint8array[index + 1] = this.buffer[1];
2396
+ uint8array[index + 2] = this.buffer[2];
2397
+ uint8array[index + 3] = this.buffer[3];
2398
+ uint8array[index + 4] = this.buffer[4];
2399
+ uint8array[index + 5] = this.buffer[5];
2400
+ uint8array[index + 6] = this.buffer[6];
2401
+ uint8array[index + 7] = this.buffer[7];
2402
+ uint8array[index + 8] = this.buffer[8];
2403
+ uint8array[index + 9] = this.buffer[9];
2404
+ uint8array[index + 10] = this.buffer[10];
2405
+ uint8array[index + 11] = this.buffer[11];
2406
+ return 12;
2407
+ }
2256
2408
  static createFromTime(time) {
2257
- const buffer = ByteUtils.fromNumberArray([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
2258
- BSONDataView.fromUint8Array(buffer).setUint32(0, time, false);
2409
+ const buffer = ByteUtils.allocate(12);
2410
+ for (let i = 11; i >= 4; i--)
2411
+ buffer[i] = 0;
2412
+ NumberUtils.setInt32BE(buffer, 0, time);
2259
2413
  return new ObjectId(buffer);
2260
2414
  }
2261
2415
  static createFromHexString(hexString) {
@@ -2627,10 +2781,7 @@ const JS_INT_MIN_LONG = Long.fromNumber(JS_INT_MIN);
2627
2781
  function internalDeserialize(buffer, options, isArray) {
2628
2782
  options = options == null ? {} : options;
2629
2783
  const index = options && options.index ? options.index : 0;
2630
- const size = buffer[index] |
2631
- (buffer[index + 1] << 8) |
2632
- (buffer[index + 2] << 16) |
2633
- (buffer[index + 3] << 24);
2784
+ const size = NumberUtils.getInt32LE(buffer, index);
2634
2785
  if (size < 5) {
2635
2786
  throw new BSONError(`bson size must be >= 5, is ${size}`);
2636
2787
  }
@@ -2666,7 +2817,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2666
2817
  const validation = options.validation == null ? { utf8: true } : options.validation;
2667
2818
  let globalUTFValidation = true;
2668
2819
  let validationSetting;
2669
- const utf8KeysSet = new Set();
2820
+ let utf8KeysSet;
2670
2821
  const utf8ValidatedKeys = validation.utf8;
2671
2822
  if (typeof utf8ValidatedKeys === 'boolean') {
2672
2823
  validationSetting = utf8ValidatedKeys;
@@ -2688,6 +2839,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2688
2839
  }
2689
2840
  }
2690
2841
  if (!globalUTFValidation) {
2842
+ utf8KeysSet = new Set();
2691
2843
  for (const key of Object.keys(utf8ValidatedKeys)) {
2692
2844
  utf8KeysSet.add(key);
2693
2845
  }
@@ -2695,14 +2847,14 @@ function deserializeObject(buffer, index, options, isArray = false) {
2695
2847
  const startIndex = index;
2696
2848
  if (buffer.length < 5)
2697
2849
  throw new BSONError('corrupt bson message < 5 bytes long');
2698
- const size = buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24);
2850
+ const size = NumberUtils.getInt32LE(buffer, index);
2851
+ index += 4;
2699
2852
  if (size < 5 || size > buffer.length)
2700
2853
  throw new BSONError('corrupt bson message');
2701
2854
  const object = isArray ? [] : {};
2702
2855
  let arrayIndex = 0;
2703
2856
  const done = false;
2704
2857
  let isPossibleDBRef = isArray ? false : null;
2705
- const dataview = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
2706
2858
  while (!done) {
2707
2859
  const elementType = buffer[index++];
2708
2860
  if (elementType === 0)
@@ -2715,7 +2867,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2715
2867
  throw new BSONError('Bad BSON Document: illegal CString');
2716
2868
  const name = isArray ? arrayIndex++ : ByteUtils.toUTF8(buffer, index, i, false);
2717
2869
  let shouldValidateKey = true;
2718
- if (globalUTFValidation || utf8KeysSet.has(name)) {
2870
+ if (globalUTFValidation || utf8KeysSet?.has(name)) {
2719
2871
  shouldValidateKey = validationSetting;
2720
2872
  }
2721
2873
  else {
@@ -2727,10 +2879,8 @@ function deserializeObject(buffer, index, options, isArray = false) {
2727
2879
  let value;
2728
2880
  index = i + 1;
2729
2881
  if (elementType === BSON_DATA_STRING) {
2730
- const stringSize = buffer[index++] |
2731
- (buffer[index++] << 8) |
2732
- (buffer[index++] << 16) |
2733
- (buffer[index++] << 24);
2882
+ const stringSize = NumberUtils.getInt32LE(buffer, index);
2883
+ index += 4;
2734
2884
  if (stringSize <= 0 ||
2735
2885
  stringSize > buffer.length - index ||
2736
2886
  buffer[index + stringSize - 1] !== 0) {
@@ -2740,38 +2890,30 @@ function deserializeObject(buffer, index, options, isArray = false) {
2740
2890
  index = index + stringSize;
2741
2891
  }
2742
2892
  else if (elementType === BSON_DATA_OID) {
2743
- const oid = ByteUtils.allocate(12);
2744
- oid.set(buffer.subarray(index, index + 12));
2893
+ const oid = ByteUtils.allocateUnsafe(12);
2894
+ for (let i = 0; i < 12; i++)
2895
+ oid[i] = buffer[index + i];
2745
2896
  value = new ObjectId(oid);
2746
2897
  index = index + 12;
2747
2898
  }
2748
2899
  else if (elementType === BSON_DATA_INT && promoteValues === false) {
2749
- value = new Int32(buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24));
2900
+ value = new Int32(NumberUtils.getInt32LE(buffer, index));
2901
+ index += 4;
2750
2902
  }
2751
2903
  else if (elementType === BSON_DATA_INT) {
2752
- value =
2753
- buffer[index++] |
2754
- (buffer[index++] << 8) |
2755
- (buffer[index++] << 16) |
2756
- (buffer[index++] << 24);
2757
- }
2758
- else if (elementType === BSON_DATA_NUMBER && promoteValues === false) {
2759
- value = new Double(dataview.getFloat64(index, true));
2760
- index = index + 8;
2904
+ value = NumberUtils.getInt32LE(buffer, index);
2905
+ index += 4;
2761
2906
  }
2762
2907
  else if (elementType === BSON_DATA_NUMBER) {
2763
- value = dataview.getFloat64(index, true);
2764
- index = index + 8;
2908
+ value = NumberUtils.getFloat64LE(buffer, index);
2909
+ index += 8;
2910
+ if (promoteValues === false)
2911
+ value = new Double(value);
2765
2912
  }
2766
2913
  else if (elementType === BSON_DATA_DATE) {
2767
- const lowBits = buffer[index++] |
2768
- (buffer[index++] << 8) |
2769
- (buffer[index++] << 16) |
2770
- (buffer[index++] << 24);
2771
- const highBits = buffer[index++] |
2772
- (buffer[index++] << 8) |
2773
- (buffer[index++] << 16) |
2774
- (buffer[index++] << 24);
2914
+ const lowBits = NumberUtils.getInt32LE(buffer, index);
2915
+ const highBits = NumberUtils.getInt32LE(buffer, index + 4);
2916
+ index += 8;
2775
2917
  value = new Date(new Long(lowBits, highBits).toNumber());
2776
2918
  }
2777
2919
  else if (elementType === BSON_DATA_BOOLEAN) {
@@ -2781,10 +2923,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2781
2923
  }
2782
2924
  else if (elementType === BSON_DATA_OBJECT) {
2783
2925
  const _index = index;
2784
- const objectSize = buffer[index] |
2785
- (buffer[index + 1] << 8) |
2786
- (buffer[index + 2] << 16) |
2787
- (buffer[index + 3] << 24);
2926
+ const objectSize = NumberUtils.getInt32LE(buffer, index);
2788
2927
  if (objectSize <= 0 || objectSize > buffer.length - index)
2789
2928
  throw new BSONError('bad embedded document length in bson');
2790
2929
  if (raw) {
@@ -2801,10 +2940,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2801
2940
  }
2802
2941
  else if (elementType === BSON_DATA_ARRAY) {
2803
2942
  const _index = index;
2804
- const objectSize = buffer[index] |
2805
- (buffer[index + 1] << 8) |
2806
- (buffer[index + 2] << 16) |
2807
- (buffer[index + 3] << 24);
2943
+ const objectSize = NumberUtils.getInt32LE(buffer, index);
2808
2944
  let arrayOptions = options;
2809
2945
  const stopIndex = index + objectSize;
2810
2946
  if (fieldsAsRaw && fieldsAsRaw[name]) {
@@ -2827,40 +2963,36 @@ function deserializeObject(buffer, index, options, isArray = false) {
2827
2963
  value = null;
2828
2964
  }
2829
2965
  else if (elementType === BSON_DATA_LONG) {
2830
- const dataview = BSONDataView.fromUint8Array(buffer.subarray(index, index + 8));
2831
- const lowBits = buffer[index++] |
2832
- (buffer[index++] << 8) |
2833
- (buffer[index++] << 16) |
2834
- (buffer[index++] << 24);
2835
- const highBits = buffer[index++] |
2836
- (buffer[index++] << 8) |
2837
- (buffer[index++] << 16) |
2838
- (buffer[index++] << 24);
2839
- const long = new Long(lowBits, highBits);
2840
2966
  if (useBigInt64) {
2841
- value = dataview.getBigInt64(0, true);
2842
- }
2843
- else if (promoteLongs && promoteValues === true) {
2844
- value =
2845
- long.lessThanOrEqual(JS_INT_MAX_LONG) && long.greaterThanOrEqual(JS_INT_MIN_LONG)
2846
- ? long.toNumber()
2847
- : long;
2967
+ value = NumberUtils.getBigInt64LE(buffer, index);
2968
+ index += 8;
2848
2969
  }
2849
2970
  else {
2850
- value = long;
2971
+ const lowBits = NumberUtils.getInt32LE(buffer, index);
2972
+ const highBits = NumberUtils.getInt32LE(buffer, index + 4);
2973
+ index += 8;
2974
+ const long = new Long(lowBits, highBits);
2975
+ if (promoteLongs && promoteValues === true) {
2976
+ value =
2977
+ long.lessThanOrEqual(JS_INT_MAX_LONG) && long.greaterThanOrEqual(JS_INT_MIN_LONG)
2978
+ ? long.toNumber()
2979
+ : long;
2980
+ }
2981
+ else {
2982
+ value = long;
2983
+ }
2851
2984
  }
2852
2985
  }
2853
2986
  else if (elementType === BSON_DATA_DECIMAL128) {
2854
- const bytes = ByteUtils.allocate(16);
2855
- bytes.set(buffer.subarray(index, index + 16), 0);
2987
+ const bytes = ByteUtils.allocateUnsafe(16);
2988
+ for (let i = 0; i < 16; i++)
2989
+ bytes[i] = buffer[index + i];
2856
2990
  index = index + 16;
2857
2991
  value = new Decimal128(bytes);
2858
2992
  }
2859
2993
  else if (elementType === BSON_DATA_BINARY) {
2860
- let binarySize = buffer[index++] |
2861
- (buffer[index++] << 8) |
2862
- (buffer[index++] << 16) |
2863
- (buffer[index++] << 24);
2994
+ let binarySize = NumberUtils.getInt32LE(buffer, index);
2995
+ index += 4;
2864
2996
  const totalBinarySize = binarySize;
2865
2997
  const subType = buffer[index++];
2866
2998
  if (binarySize < 0)
@@ -2869,11 +3001,8 @@ function deserializeObject(buffer, index, options, isArray = false) {
2869
3001
  throw new BSONError('Binary type size larger than document size');
2870
3002
  if (buffer['slice'] != null) {
2871
3003
  if (subType === Binary.SUBTYPE_BYTE_ARRAY) {
2872
- binarySize =
2873
- buffer[index++] |
2874
- (buffer[index++] << 8) |
2875
- (buffer[index++] << 16) |
2876
- (buffer[index++] << 24);
3004
+ binarySize = NumberUtils.getInt32LE(buffer, index);
3005
+ index += 4;
2877
3006
  if (binarySize < 0)
2878
3007
  throw new BSONError('Negative binary type element size found for subtype 0x02');
2879
3008
  if (binarySize > totalBinarySize - 4)
@@ -2892,13 +3021,9 @@ function deserializeObject(buffer, index, options, isArray = false) {
2892
3021
  }
2893
3022
  }
2894
3023
  else {
2895
- const _buffer = ByteUtils.allocate(binarySize);
2896
3024
  if (subType === Binary.SUBTYPE_BYTE_ARRAY) {
2897
- binarySize =
2898
- buffer[index++] |
2899
- (buffer[index++] << 8) |
2900
- (buffer[index++] << 16) |
2901
- (buffer[index++] << 24);
3025
+ binarySize = NumberUtils.getInt32LE(buffer, index);
3026
+ index += 4;
2902
3027
  if (binarySize < 0)
2903
3028
  throw new BSONError('Negative binary type element size found for subtype 0x02');
2904
3029
  if (binarySize > totalBinarySize - 4)
@@ -2906,11 +3031,11 @@ function deserializeObject(buffer, index, options, isArray = false) {
2906
3031
  if (binarySize < totalBinarySize - 4)
2907
3032
  throw new BSONError('Binary type with subtype 0x02 contains too short binary size');
2908
3033
  }
2909
- for (i = 0; i < binarySize; i++) {
2910
- _buffer[i] = buffer[index + i];
2911
- }
2912
3034
  if (promoteBuffers && promoteValues) {
2913
- value = _buffer;
3035
+ value = ByteUtils.allocateUnsafe(binarySize);
3036
+ for (i = 0; i < binarySize; i++) {
3037
+ value[i] = buffer[index + i];
3038
+ }
2914
3039
  }
2915
3040
  else {
2916
3041
  value = new Binary(buffer.slice(index, index + binarySize), subType);
@@ -2974,10 +3099,8 @@ function deserializeObject(buffer, index, options, isArray = false) {
2974
3099
  value = new BSONRegExp(source, regExpOptions);
2975
3100
  }
2976
3101
  else if (elementType === BSON_DATA_SYMBOL) {
2977
- const stringSize = buffer[index++] |
2978
- (buffer[index++] << 8) |
2979
- (buffer[index++] << 16) |
2980
- (buffer[index++] << 24);
3102
+ const stringSize = NumberUtils.getInt32LE(buffer, index);
3103
+ index += 4;
2981
3104
  if (stringSize <= 0 ||
2982
3105
  stringSize > buffer.length - index ||
2983
3106
  buffer[index + stringSize - 1] !== 0) {
@@ -2988,15 +3111,11 @@ function deserializeObject(buffer, index, options, isArray = false) {
2988
3111
  index = index + stringSize;
2989
3112
  }
2990
3113
  else if (elementType === BSON_DATA_TIMESTAMP) {
2991
- const i = buffer[index++] +
2992
- buffer[index++] * (1 << 8) +
2993
- buffer[index++] * (1 << 16) +
2994
- buffer[index++] * (1 << 24);
2995
- const t = buffer[index++] +
2996
- buffer[index++] * (1 << 8) +
2997
- buffer[index++] * (1 << 16) +
2998
- buffer[index++] * (1 << 24);
2999
- value = new Timestamp({ i, t });
3114
+ value = new Timestamp({
3115
+ i: NumberUtils.getUint32LE(buffer, index),
3116
+ t: NumberUtils.getUint32LE(buffer, index + 4)
3117
+ });
3118
+ index += 8;
3000
3119
  }
3001
3120
  else if (elementType === BSON_DATA_MIN_KEY) {
3002
3121
  value = new MinKey();
@@ -3005,10 +3124,8 @@ function deserializeObject(buffer, index, options, isArray = false) {
3005
3124
  value = new MaxKey();
3006
3125
  }
3007
3126
  else if (elementType === BSON_DATA_CODE) {
3008
- const stringSize = buffer[index++] |
3009
- (buffer[index++] << 8) |
3010
- (buffer[index++] << 16) |
3011
- (buffer[index++] << 24);
3127
+ const stringSize = NumberUtils.getInt32LE(buffer, index);
3128
+ index += 4;
3012
3129
  if (stringSize <= 0 ||
3013
3130
  stringSize > buffer.length - index ||
3014
3131
  buffer[index + stringSize - 1] !== 0) {
@@ -3019,17 +3136,13 @@ function deserializeObject(buffer, index, options, isArray = false) {
3019
3136
  index = index + stringSize;
3020
3137
  }
3021
3138
  else if (elementType === BSON_DATA_CODE_W_SCOPE) {
3022
- const totalSize = buffer[index++] |
3023
- (buffer[index++] << 8) |
3024
- (buffer[index++] << 16) |
3025
- (buffer[index++] << 24);
3139
+ const totalSize = NumberUtils.getInt32LE(buffer, index);
3140
+ index += 4;
3026
3141
  if (totalSize < 4 + 4 + 4 + 1) {
3027
3142
  throw new BSONError('code_w_scope total size shorter minimum expected length');
3028
3143
  }
3029
- const stringSize = buffer[index++] |
3030
- (buffer[index++] << 8) |
3031
- (buffer[index++] << 16) |
3032
- (buffer[index++] << 24);
3144
+ const stringSize = NumberUtils.getInt32LE(buffer, index);
3145
+ index += 4;
3033
3146
  if (stringSize <= 0 ||
3034
3147
  stringSize > buffer.length - index ||
3035
3148
  buffer[index + stringSize - 1] !== 0) {
@@ -3038,10 +3151,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
3038
3151
  const functionString = ByteUtils.toUTF8(buffer, index, index + stringSize - 1, shouldValidateKey);
3039
3152
  index = index + stringSize;
3040
3153
  const _index = index;
3041
- const objectSize = buffer[index] |
3042
- (buffer[index + 1] << 8) |
3043
- (buffer[index + 2] << 16) |
3044
- (buffer[index + 3] << 24);
3154
+ const objectSize = NumberUtils.getInt32LE(buffer, index);
3045
3155
  const scopeObject = deserializeObject(buffer, _index, options, false);
3046
3156
  index = index + objectSize;
3047
3157
  if (totalSize < 4 + 4 + objectSize + stringSize) {
@@ -3053,10 +3163,8 @@ function deserializeObject(buffer, index, options, isArray = false) {
3053
3163
  value = new Code(functionString, scopeObject);
3054
3164
  }
3055
3165
  else if (elementType === BSON_DATA_DBPOINTER) {
3056
- const stringSize = buffer[index++] |
3057
- (buffer[index++] << 8) |
3058
- (buffer[index++] << 16) |
3059
- (buffer[index++] << 24);
3166
+ const stringSize = NumberUtils.getInt32LE(buffer, index);
3167
+ index += 4;
3060
3168
  if (stringSize <= 0 ||
3061
3169
  stringSize > buffer.length - index ||
3062
3170
  buffer[index + stringSize - 1] !== 0)
@@ -3068,8 +3176,9 @@ function deserializeObject(buffer, index, options, isArray = false) {
3068
3176
  }
3069
3177
  const namespace = ByteUtils.toUTF8(buffer, index, index + stringSize - 1, false);
3070
3178
  index = index + stringSize;
3071
- const oidBuffer = ByteUtils.allocate(12);
3072
- oidBuffer.set(buffer.subarray(index, index + 12), 0);
3179
+ const oidBuffer = ByteUtils.allocateUnsafe(12);
3180
+ for (let i = 0; i < 12; i++)
3181
+ oidBuffer[i] = buffer[index + i];
3073
3182
  const oid = new ObjectId(oidBuffer);
3074
3183
  index = index + 12;
3075
3184
  value = new DBRef(namespace, oid);
@@ -3114,17 +3223,11 @@ function serializeString(buffer, key, value, index) {
3114
3223
  index = index + numberOfWrittenBytes + 1;
3115
3224
  buffer[index - 1] = 0;
3116
3225
  const size = ByteUtils.encodeUTF8Into(buffer, value, index + 4);
3117
- buffer[index + 3] = ((size + 1) >> 24) & 0xff;
3118
- buffer[index + 2] = ((size + 1) >> 16) & 0xff;
3119
- buffer[index + 1] = ((size + 1) >> 8) & 0xff;
3120
- buffer[index] = (size + 1) & 0xff;
3226
+ NumberUtils.setInt32LE(buffer, index, size + 1);
3121
3227
  index = index + 4 + size;
3122
3228
  buffer[index++] = 0;
3123
3229
  return index;
3124
3230
  }
3125
- const NUMBER_SPACE = new DataView(new ArrayBuffer(8), 0, 8);
3126
- const FOUR_BYTE_VIEW_ON_NUMBER = new Uint8Array(NUMBER_SPACE.buffer, 0, 4);
3127
- const EIGHT_BYTE_VIEW_ON_NUMBER = new Uint8Array(NUMBER_SPACE.buffer, 0, 8);
3128
3231
  function serializeNumber(buffer, key, value, index) {
3129
3232
  const isNegativeZero = Object.is(value, -0);
3130
3233
  const type = !isNegativeZero &&
@@ -3133,19 +3236,16 @@ function serializeNumber(buffer, key, value, index) {
3133
3236
  value >= BSON_INT32_MIN
3134
3237
  ? BSON_DATA_INT
3135
3238
  : BSON_DATA_NUMBER;
3136
- if (type === BSON_DATA_INT) {
3137
- NUMBER_SPACE.setInt32(0, value, true);
3138
- }
3139
- else {
3140
- NUMBER_SPACE.setFloat64(0, value, true);
3141
- }
3142
- const bytes = type === BSON_DATA_INT ? FOUR_BYTE_VIEW_ON_NUMBER : EIGHT_BYTE_VIEW_ON_NUMBER;
3143
3239
  buffer[index++] = type;
3144
3240
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3145
3241
  index = index + numberOfWrittenBytes;
3146
3242
  buffer[index++] = 0x00;
3147
- buffer.set(bytes, index);
3148
- index += bytes.byteLength;
3243
+ if (type === BSON_DATA_INT) {
3244
+ index += NumberUtils.setInt32LE(buffer, index, value);
3245
+ }
3246
+ else {
3247
+ index += NumberUtils.setFloat64LE(buffer, index, value);
3248
+ }
3149
3249
  return index;
3150
3250
  }
3151
3251
  function serializeBigInt(buffer, key, value, index) {
@@ -3153,9 +3253,7 @@ function serializeBigInt(buffer, key, value, index) {
3153
3253
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3154
3254
  index += numberOfWrittenBytes;
3155
3255
  buffer[index++] = 0;
3156
- NUMBER_SPACE.setBigInt64(0, value, true);
3157
- buffer.set(EIGHT_BYTE_VIEW_ON_NUMBER, index);
3158
- index += EIGHT_BYTE_VIEW_ON_NUMBER.byteLength;
3256
+ index += NumberUtils.setBigInt64LE(buffer, index, value);
3159
3257
  return index;
3160
3258
  }
3161
3259
  function serializeNull(buffer, key, _, index) {
@@ -3181,14 +3279,8 @@ function serializeDate(buffer, key, value, index) {
3181
3279
  const dateInMilis = Long.fromNumber(value.getTime());
3182
3280
  const lowBits = dateInMilis.getLowBits();
3183
3281
  const highBits = dateInMilis.getHighBits();
3184
- buffer[index++] = lowBits & 0xff;
3185
- buffer[index++] = (lowBits >> 8) & 0xff;
3186
- buffer[index++] = (lowBits >> 16) & 0xff;
3187
- buffer[index++] = (lowBits >> 24) & 0xff;
3188
- buffer[index++] = highBits & 0xff;
3189
- buffer[index++] = (highBits >> 8) & 0xff;
3190
- buffer[index++] = (highBits >> 16) & 0xff;
3191
- buffer[index++] = (highBits >> 24) & 0xff;
3282
+ index += NumberUtils.setInt32LE(buffer, index, lowBits);
3283
+ index += NumberUtils.setInt32LE(buffer, index, highBits);
3192
3284
  return index;
3193
3285
  }
3194
3286
  function serializeRegExp(buffer, key, value, index) {
@@ -3245,15 +3337,7 @@ function serializeObjectId(buffer, key, value, index) {
3245
3337
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3246
3338
  index = index + numberOfWrittenBytes;
3247
3339
  buffer[index++] = 0;
3248
- const idValue = value.id;
3249
- if (isUint8Array(idValue)) {
3250
- for (let i = 0; i < 12; i++) {
3251
- buffer[index++] = idValue[i];
3252
- }
3253
- }
3254
- else {
3255
- throw new BSONError('object [' + JSON.stringify(value) + '] is not a valid ObjectId');
3256
- }
3340
+ index += value.serializeInto(buffer, index);
3257
3341
  return index;
3258
3342
  }
3259
3343
  function serializeBuffer(buffer, key, value, index) {
@@ -3262,12 +3346,15 @@ function serializeBuffer(buffer, key, value, index) {
3262
3346
  index = index + numberOfWrittenBytes;
3263
3347
  buffer[index++] = 0;
3264
3348
  const size = value.length;
3265
- buffer[index++] = size & 0xff;
3266
- buffer[index++] = (size >> 8) & 0xff;
3267
- buffer[index++] = (size >> 16) & 0xff;
3268
- buffer[index++] = (size >> 24) & 0xff;
3349
+ index += NumberUtils.setInt32LE(buffer, index, size);
3269
3350
  buffer[index++] = BSON_BINARY_SUBTYPE_DEFAULT;
3270
- buffer.set(value, index);
3351
+ if (size <= 16) {
3352
+ for (let i = 0; i < size; i++)
3353
+ buffer[index + i] = value[i];
3354
+ }
3355
+ else {
3356
+ buffer.set(value, index);
3357
+ }
3271
3358
  index = index + size;
3272
3359
  return index;
3273
3360
  }
@@ -3289,7 +3376,8 @@ function serializeDecimal128(buffer, key, value, index) {
3289
3376
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3290
3377
  index = index + numberOfWrittenBytes;
3291
3378
  buffer[index++] = 0;
3292
- buffer.set(value.bytes.subarray(0, 16), index);
3379
+ for (let i = 0; i < 16; i++)
3380
+ buffer[index + i] = value.bytes[i];
3293
3381
  return index + 16;
3294
3382
  }
3295
3383
  function serializeLong(buffer, key, value, index) {
@@ -3300,14 +3388,8 @@ function serializeLong(buffer, key, value, index) {
3300
3388
  buffer[index++] = 0;
3301
3389
  const lowBits = value.getLowBits();
3302
3390
  const highBits = value.getHighBits();
3303
- buffer[index++] = lowBits & 0xff;
3304
- buffer[index++] = (lowBits >> 8) & 0xff;
3305
- buffer[index++] = (lowBits >> 16) & 0xff;
3306
- buffer[index++] = (lowBits >> 24) & 0xff;
3307
- buffer[index++] = highBits & 0xff;
3308
- buffer[index++] = (highBits >> 8) & 0xff;
3309
- buffer[index++] = (highBits >> 16) & 0xff;
3310
- buffer[index++] = (highBits >> 24) & 0xff;
3391
+ index += NumberUtils.setInt32LE(buffer, index, lowBits);
3392
+ index += NumberUtils.setInt32LE(buffer, index, highBits);
3311
3393
  return index;
3312
3394
  }
3313
3395
  function serializeInt32(buffer, key, value, index) {
@@ -3316,10 +3398,7 @@ function serializeInt32(buffer, key, value, index) {
3316
3398
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3317
3399
  index = index + numberOfWrittenBytes;
3318
3400
  buffer[index++] = 0;
3319
- buffer[index++] = value & 0xff;
3320
- buffer[index++] = (value >> 8) & 0xff;
3321
- buffer[index++] = (value >> 16) & 0xff;
3322
- buffer[index++] = (value >> 24) & 0xff;
3401
+ index += NumberUtils.setInt32LE(buffer, index, value);
3323
3402
  return index;
3324
3403
  }
3325
3404
  function serializeDouble(buffer, key, value, index) {
@@ -3327,9 +3406,7 @@ function serializeDouble(buffer, key, value, index) {
3327
3406
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3328
3407
  index = index + numberOfWrittenBytes;
3329
3408
  buffer[index++] = 0;
3330
- NUMBER_SPACE.setFloat64(0, value.value, true);
3331
- buffer.set(EIGHT_BYTE_VIEW_ON_NUMBER, index);
3332
- index = index + 8;
3409
+ index += NumberUtils.setFloat64LE(buffer, index, value.value);
3333
3410
  return index;
3334
3411
  }
3335
3412
  function serializeFunction(buffer, key, value, index) {
@@ -3339,10 +3416,7 @@ function serializeFunction(buffer, key, value, index) {
3339
3416
  buffer[index++] = 0;
3340
3417
  const functionString = value.toString();
3341
3418
  const size = ByteUtils.encodeUTF8Into(buffer, functionString, index + 4) + 1;
3342
- buffer[index] = size & 0xff;
3343
- buffer[index + 1] = (size >> 8) & 0xff;
3344
- buffer[index + 2] = (size >> 16) & 0xff;
3345
- buffer[index + 3] = (size >> 24) & 0xff;
3419
+ NumberUtils.setInt32LE(buffer, index, size);
3346
3420
  index = index + 4 + size - 1;
3347
3421
  buffer[index++] = 0;
3348
3422
  return index;
@@ -3357,19 +3431,13 @@ function serializeCode(buffer, key, value, index, checkKeys = false, depth = 0,
3357
3431
  const functionString = value.code;
3358
3432
  index = index + 4;
3359
3433
  const codeSize = ByteUtils.encodeUTF8Into(buffer, functionString, index + 4) + 1;
3360
- buffer[index] = codeSize & 0xff;
3361
- buffer[index + 1] = (codeSize >> 8) & 0xff;
3362
- buffer[index + 2] = (codeSize >> 16) & 0xff;
3363
- buffer[index + 3] = (codeSize >> 24) & 0xff;
3434
+ NumberUtils.setInt32LE(buffer, index, codeSize);
3364
3435
  buffer[index + 4 + codeSize - 1] = 0;
3365
3436
  index = index + codeSize + 4;
3366
3437
  const endIndex = serializeInto(buffer, value.scope, checkKeys, index, depth + 1, serializeFunctions, ignoreUndefined, path);
3367
3438
  index = endIndex - 1;
3368
3439
  const totalSize = endIndex - startIndex;
3369
- buffer[startIndex++] = totalSize & 0xff;
3370
- buffer[startIndex++] = (totalSize >> 8) & 0xff;
3371
- buffer[startIndex++] = (totalSize >> 16) & 0xff;
3372
- buffer[startIndex++] = (totalSize >> 24) & 0xff;
3440
+ startIndex += NumberUtils.setInt32LE(buffer, startIndex, totalSize);
3373
3441
  buffer[index++] = 0;
3374
3442
  }
3375
3443
  else {
@@ -3379,10 +3447,7 @@ function serializeCode(buffer, key, value, index, checkKeys = false, depth = 0,
3379
3447
  buffer[index++] = 0;
3380
3448
  const functionString = value.code.toString();
3381
3449
  const size = ByteUtils.encodeUTF8Into(buffer, functionString, index + 4) + 1;
3382
- buffer[index] = size & 0xff;
3383
- buffer[index + 1] = (size >> 8) & 0xff;
3384
- buffer[index + 2] = (size >> 16) & 0xff;
3385
- buffer[index + 3] = (size >> 24) & 0xff;
3450
+ NumberUtils.setInt32LE(buffer, index, size);
3386
3451
  index = index + 4 + size - 1;
3387
3452
  buffer[index++] = 0;
3388
3453
  }
@@ -3397,19 +3462,19 @@ function serializeBinary(buffer, key, value, index) {
3397
3462
  let size = value.position;
3398
3463
  if (value.sub_type === Binary.SUBTYPE_BYTE_ARRAY)
3399
3464
  size = size + 4;
3400
- buffer[index++] = size & 0xff;
3401
- buffer[index++] = (size >> 8) & 0xff;
3402
- buffer[index++] = (size >> 16) & 0xff;
3403
- buffer[index++] = (size >> 24) & 0xff;
3465
+ index += NumberUtils.setInt32LE(buffer, index, size);
3404
3466
  buffer[index++] = value.sub_type;
3405
3467
  if (value.sub_type === Binary.SUBTYPE_BYTE_ARRAY) {
3406
3468
  size = size - 4;
3407
- buffer[index++] = size & 0xff;
3408
- buffer[index++] = (size >> 8) & 0xff;
3409
- buffer[index++] = (size >> 16) & 0xff;
3410
- buffer[index++] = (size >> 24) & 0xff;
3469
+ index += NumberUtils.setInt32LE(buffer, index, size);
3470
+ }
3471
+ if (size <= 16) {
3472
+ for (let i = 0; i < size; i++)
3473
+ buffer[index + i] = data[i];
3474
+ }
3475
+ else {
3476
+ buffer.set(data, index);
3411
3477
  }
3412
- buffer.set(data, index);
3413
3478
  index = index + value.position;
3414
3479
  return index;
3415
3480
  }
@@ -3419,12 +3484,9 @@ function serializeSymbol(buffer, key, value, index) {
3419
3484
  index = index + numberOfWrittenBytes;
3420
3485
  buffer[index++] = 0;
3421
3486
  const size = ByteUtils.encodeUTF8Into(buffer, value.value, index + 4) + 1;
3422
- buffer[index] = size & 0xff;
3423
- buffer[index + 1] = (size >> 8) & 0xff;
3424
- buffer[index + 2] = (size >> 16) & 0xff;
3425
- buffer[index + 3] = (size >> 24) & 0xff;
3487
+ NumberUtils.setInt32LE(buffer, index, size);
3426
3488
  index = index + 4 + size - 1;
3427
- buffer[index++] = 0x00;
3489
+ buffer[index++] = 0;
3428
3490
  return index;
3429
3491
  }
3430
3492
  function serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path) {
@@ -3443,10 +3505,7 @@ function serializeDBRef(buffer, key, value, index, depth, serializeFunctions, pa
3443
3505
  output = Object.assign(output, value.fields);
3444
3506
  const endIndex = serializeInto(buffer, output, false, index, depth + 1, serializeFunctions, true, path);
3445
3507
  const size = endIndex - startIndex;
3446
- buffer[startIndex++] = size & 0xff;
3447
- buffer[startIndex++] = (size >> 8) & 0xff;
3448
- buffer[startIndex++] = (size >> 16) & 0xff;
3449
- buffer[startIndex++] = (size >> 24) & 0xff;
3508
+ startIndex += NumberUtils.setInt32LE(buffer, index, size);
3450
3509
  return endIndex;
3451
3510
  }
3452
3511
  function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializeFunctions, ignoreUndefined, path) {
@@ -3582,7 +3641,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3582
3641
  if ('$' === key[0]) {
3583
3642
  throw new BSONError('key ' + key + " must not start with '$'");
3584
3643
  }
3585
- else if (~key.indexOf('.')) {
3644
+ else if (key.includes('.')) {
3586
3645
  throw new BSONError('key ' + key + " must not contain '.'");
3587
3646
  }
3588
3647
  }
@@ -3680,7 +3739,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3680
3739
  if ('$' === key[0]) {
3681
3740
  throw new BSONError('key ' + key + " must not start with '$'");
3682
3741
  }
3683
- else if (~key.indexOf('.')) {
3742
+ else if (key.includes('.')) {
3684
3743
  throw new BSONError('key ' + key + " must not contain '.'");
3685
3744
  }
3686
3745
  }
@@ -3764,10 +3823,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3764
3823
  path.delete(object);
3765
3824
  buffer[index++] = 0x00;
3766
3825
  const size = index - startingIndex;
3767
- buffer[startingIndex++] = size & 0xff;
3768
- buffer[startingIndex++] = (size >> 8) & 0xff;
3769
- buffer[startingIndex++] = (size >> 16) & 0xff;
3770
- buffer[startingIndex++] = (size >> 24) & 0xff;
3826
+ startingIndex += NumberUtils.setInt32LE(buffer, startingIndex, size);
3771
3827
  return index;
3772
3828
  }
3773
3829
 
@@ -4097,7 +4153,7 @@ function serialize(object, options = {}) {
4097
4153
  buffer = ByteUtils.allocate(minInternalBufferSize);
4098
4154
  }
4099
4155
  const serializationIndex = serializeInto(buffer, object, checkKeys, 0, 0, serializeFunctions, ignoreUndefined, null);
4100
- const finishedBuffer = ByteUtils.allocate(serializationIndex);
4156
+ const finishedBuffer = ByteUtils.allocateUnsafe(serializationIndex);
4101
4157
  finishedBuffer.set(buffer.subarray(0, serializationIndex), 0);
4102
4158
  return finishedBuffer;
4103
4159
  }
@@ -4124,10 +4180,7 @@ function deserializeStream(data, startIndex, numberOfDocuments, documents, docSt
4124
4180
  const bufferData = ByteUtils.toLocalBufferType(data);
4125
4181
  let index = startIndex;
4126
4182
  for (let i = 0; i < numberOfDocuments; i++) {
4127
- const size = bufferData[index] |
4128
- (bufferData[index + 1] << 8) |
4129
- (bufferData[index + 2] << 16) |
4130
- (bufferData[index + 3] << 24);
4183
+ const size = NumberUtils.getInt32LE(bufferData, index);
4131
4184
  internalOptions.index = index;
4132
4185
  documents[docStartIndex + i] = internalDeserialize(bufferData, internalOptions);
4133
4186
  index = index + size;