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.cjs CHANGED
@@ -164,7 +164,7 @@ function validateUtf8(bytes, start, end) {
164
164
  return !continuation;
165
165
  }
166
166
 
167
- function tryLatin(uint8array, start, end) {
167
+ function tryReadBasicLatin(uint8array, start, end) {
168
168
  if (uint8array.length === 0) {
169
169
  return '';
170
170
  }
@@ -199,6 +199,21 @@ function tryLatin(uint8array, start, end) {
199
199
  }
200
200
  return String.fromCharCode(...latinBytes);
201
201
  }
202
+ function tryWriteBasicLatin(destination, source, offset) {
203
+ if (source.length === 0)
204
+ return 0;
205
+ if (source.length > 25)
206
+ return null;
207
+ if (destination.length - offset < source.length)
208
+ return null;
209
+ for (let charOffset = 0, destinationOffset = offset; charOffset < source.length; charOffset++, destinationOffset++) {
210
+ const char = source.charCodeAt(charOffset);
211
+ if (char > 127)
212
+ return null;
213
+ destination[destinationOffset] = char;
214
+ }
215
+ return source.length;
216
+ }
202
217
 
203
218
  function nodejsMathRandomBytes(byteLength) {
204
219
  return nodeJsByteUtils.fromNumberArray(Array.from({ length: byteLength }, () => Math.floor(Math.random() * 256)));
@@ -231,6 +246,9 @@ const nodeJsByteUtils = {
231
246
  allocate(size) {
232
247
  return Buffer.alloc(size);
233
248
  },
249
+ allocateUnsafe(size) {
250
+ return Buffer.allocUnsafe(size);
251
+ },
234
252
  equals(a, b) {
235
253
  return nodeJsByteUtils.toLocalBufferType(a).equals(b);
236
254
  },
@@ -255,11 +273,8 @@ const nodeJsByteUtils = {
255
273
  toHex(buffer) {
256
274
  return nodeJsByteUtils.toLocalBufferType(buffer).toString('hex');
257
275
  },
258
- fromUTF8(text) {
259
- return Buffer.from(text, 'utf8');
260
- },
261
276
  toUTF8(buffer, start, end, fatal) {
262
- const basicLatin = end - start <= 20 ? tryLatin(buffer, start, end) : null;
277
+ const basicLatin = end - start <= 20 ? tryReadBasicLatin(buffer, start, end) : null;
263
278
  if (basicLatin != null) {
264
279
  return basicLatin;
265
280
  }
@@ -280,6 +295,10 @@ const nodeJsByteUtils = {
280
295
  return Buffer.byteLength(input, 'utf8');
281
296
  },
282
297
  encodeUTF8Into(buffer, source, byteOffset) {
298
+ const latinBytesWritten = tryWriteBasicLatin(buffer, source, byteOffset);
299
+ if (latinBytesWritten != null) {
300
+ return latinBytesWritten;
301
+ }
283
302
  return nodeJsByteUtils.toLocalBufferType(buffer).write(source, byteOffset, undefined, 'utf8');
284
303
  },
285
304
  randomBytes: nodejsRandomBytes
@@ -335,6 +354,9 @@ const webByteUtils = {
335
354
  }
336
355
  return new Uint8Array(size);
337
356
  },
357
+ allocateUnsafe(size) {
358
+ return webByteUtils.allocate(size);
359
+ },
338
360
  equals(a, b) {
339
361
  if (a.byteLength !== b.byteLength) {
340
362
  return false;
@@ -381,11 +403,8 @@ const webByteUtils = {
381
403
  toHex(uint8array) {
382
404
  return Array.from(uint8array, byte => byte.toString(16).padStart(2, '0')).join('');
383
405
  },
384
- fromUTF8(text) {
385
- return new TextEncoder().encode(text);
386
- },
387
406
  toUTF8(uint8array, start, end, fatal) {
388
- const basicLatin = end - start <= 20 ? tryLatin(uint8array, start, end) : null;
407
+ const basicLatin = end - start <= 20 ? tryReadBasicLatin(uint8array, start, end) : null;
389
408
  if (basicLatin != null) {
390
409
  return basicLatin;
391
410
  }
@@ -400,11 +419,11 @@ const webByteUtils = {
400
419
  return new TextDecoder('utf8', { fatal }).decode(uint8array.slice(start, end));
401
420
  },
402
421
  utf8ByteLength(input) {
403
- return webByteUtils.fromUTF8(input).byteLength;
422
+ return new TextEncoder().encode(input).byteLength;
404
423
  },
405
- encodeUTF8Into(buffer, source, byteOffset) {
406
- const bytes = webByteUtils.fromUTF8(source);
407
- buffer.set(bytes, byteOffset);
424
+ encodeUTF8Into(uint8array, source, byteOffset) {
425
+ const bytes = new TextEncoder().encode(source);
426
+ uint8array.set(bytes, byteOffset);
408
427
  return bytes.byteLength;
409
428
  },
410
429
  randomBytes: webRandomBytes
@@ -412,11 +431,6 @@ const webByteUtils = {
412
431
 
413
432
  const hasGlobalBuffer = typeof Buffer === 'function' && Buffer.prototype?._isBuffer !== true;
414
433
  const ByteUtils = hasGlobalBuffer ? nodeJsByteUtils : webByteUtils;
415
- class BSONDataView extends DataView {
416
- static fromUint8Array(input) {
417
- return new DataView(input.buffer, input.byteOffset, input.byteLength);
418
- }
419
- }
420
434
 
421
435
  class BSONValue {
422
436
  get [Symbol.for('@@mdb.bson.version')]() {
@@ -1836,7 +1850,7 @@ class Decimal128 extends BSONValue {
1836
1850
  if (isNegative) {
1837
1851
  dec.high = dec.high.or(Long.fromString('9223372036854775808'));
1838
1852
  }
1839
- const buffer = ByteUtils.allocate(16);
1853
+ const buffer = ByteUtils.allocateUnsafe(16);
1840
1854
  index = 0;
1841
1855
  buffer[index++] = dec.low.low & 0xff;
1842
1856
  buffer[index++] = (dec.low.low >> 8) & 0xff;
@@ -2109,9 +2123,132 @@ class MinKey extends BSONValue {
2109
2123
  }
2110
2124
  }
2111
2125
 
2126
+ const FLOAT = new Float64Array(1);
2127
+ const FLOAT_BYTES = new Uint8Array(FLOAT.buffer, 0, 8);
2128
+ FLOAT[0] = -1;
2129
+ const isBigEndian = FLOAT_BYTES[7] === 0;
2130
+ const NumberUtils = {
2131
+ getInt32LE(source, offset) {
2132
+ return (source[offset] |
2133
+ (source[offset + 1] << 8) |
2134
+ (source[offset + 2] << 16) |
2135
+ (source[offset + 3] << 24));
2136
+ },
2137
+ getUint32LE(source, offset) {
2138
+ return (source[offset] +
2139
+ source[offset + 1] * 256 +
2140
+ source[offset + 2] * 65536 +
2141
+ source[offset + 3] * 16777216);
2142
+ },
2143
+ getUint32BE(source, offset) {
2144
+ return (source[offset + 3] +
2145
+ source[offset + 2] * 256 +
2146
+ source[offset + 1] * 65536 +
2147
+ source[offset] * 16777216);
2148
+ },
2149
+ getBigInt64LE(source, offset) {
2150
+ const hi = BigInt(source[offset + 4] +
2151
+ source[offset + 5] * 256 +
2152
+ source[offset + 6] * 65536 +
2153
+ (source[offset + 7] << 24));
2154
+ const lo = BigInt(source[offset] +
2155
+ source[offset + 1] * 256 +
2156
+ source[offset + 2] * 65536 +
2157
+ source[offset + 3] * 16777216);
2158
+ return (hi << BigInt(32)) + lo;
2159
+ },
2160
+ getFloat64LE: isBigEndian
2161
+ ? (source, offset) => {
2162
+ FLOAT_BYTES[7] = source[offset];
2163
+ FLOAT_BYTES[6] = source[offset + 1];
2164
+ FLOAT_BYTES[5] = source[offset + 2];
2165
+ FLOAT_BYTES[4] = source[offset + 3];
2166
+ FLOAT_BYTES[3] = source[offset + 4];
2167
+ FLOAT_BYTES[2] = source[offset + 5];
2168
+ FLOAT_BYTES[1] = source[offset + 6];
2169
+ FLOAT_BYTES[0] = source[offset + 7];
2170
+ return FLOAT[0];
2171
+ }
2172
+ : (source, offset) => {
2173
+ FLOAT_BYTES[0] = source[offset];
2174
+ FLOAT_BYTES[1] = source[offset + 1];
2175
+ FLOAT_BYTES[2] = source[offset + 2];
2176
+ FLOAT_BYTES[3] = source[offset + 3];
2177
+ FLOAT_BYTES[4] = source[offset + 4];
2178
+ FLOAT_BYTES[5] = source[offset + 5];
2179
+ FLOAT_BYTES[6] = source[offset + 6];
2180
+ FLOAT_BYTES[7] = source[offset + 7];
2181
+ return FLOAT[0];
2182
+ },
2183
+ setInt32BE(destination, offset, value) {
2184
+ destination[offset + 3] = value;
2185
+ value >>>= 8;
2186
+ destination[offset + 2] = value;
2187
+ value >>>= 8;
2188
+ destination[offset + 1] = value;
2189
+ value >>>= 8;
2190
+ destination[offset] = value;
2191
+ return 4;
2192
+ },
2193
+ setInt32LE(destination, offset, value) {
2194
+ destination[offset] = value;
2195
+ value >>>= 8;
2196
+ destination[offset + 1] = value;
2197
+ value >>>= 8;
2198
+ destination[offset + 2] = value;
2199
+ value >>>= 8;
2200
+ destination[offset + 3] = value;
2201
+ return 4;
2202
+ },
2203
+ setBigInt64LE(destination, offset, value) {
2204
+ const mask32bits = BigInt(4294967295);
2205
+ let lo = Number(value & mask32bits);
2206
+ destination[offset] = lo;
2207
+ lo >>= 8;
2208
+ destination[offset + 1] = lo;
2209
+ lo >>= 8;
2210
+ destination[offset + 2] = lo;
2211
+ lo >>= 8;
2212
+ destination[offset + 3] = lo;
2213
+ let hi = Number((value >> BigInt(32)) & mask32bits);
2214
+ destination[offset + 4] = hi;
2215
+ hi >>= 8;
2216
+ destination[offset + 5] = hi;
2217
+ hi >>= 8;
2218
+ destination[offset + 6] = hi;
2219
+ hi >>= 8;
2220
+ destination[offset + 7] = hi;
2221
+ return 8;
2222
+ },
2223
+ setFloat64LE: isBigEndian
2224
+ ? (destination, offset, value) => {
2225
+ FLOAT[0] = value;
2226
+ destination[offset] = FLOAT_BYTES[7];
2227
+ destination[offset + 1] = FLOAT_BYTES[6];
2228
+ destination[offset + 2] = FLOAT_BYTES[5];
2229
+ destination[offset + 3] = FLOAT_BYTES[4];
2230
+ destination[offset + 4] = FLOAT_BYTES[3];
2231
+ destination[offset + 5] = FLOAT_BYTES[2];
2232
+ destination[offset + 6] = FLOAT_BYTES[1];
2233
+ destination[offset + 7] = FLOAT_BYTES[0];
2234
+ return 8;
2235
+ }
2236
+ : (destination, offset, value) => {
2237
+ FLOAT[0] = value;
2238
+ destination[offset] = FLOAT_BYTES[0];
2239
+ destination[offset + 1] = FLOAT_BYTES[1];
2240
+ destination[offset + 2] = FLOAT_BYTES[2];
2241
+ destination[offset + 3] = FLOAT_BYTES[3];
2242
+ destination[offset + 4] = FLOAT_BYTES[4];
2243
+ destination[offset + 5] = FLOAT_BYTES[5];
2244
+ destination[offset + 6] = FLOAT_BYTES[6];
2245
+ destination[offset + 7] = FLOAT_BYTES[7];
2246
+ return 8;
2247
+ }
2248
+ };
2249
+
2112
2250
  const checkForHexRegExp = new RegExp('^[0-9a-fA-F]{24}$');
2113
2251
  let PROCESS_UNIQUE = null;
2114
- const kId = Symbol('id');
2115
2252
  class ObjectId extends BSONValue {
2116
2253
  get _bsontype() {
2117
2254
  return 'ObjectId';
@@ -2134,14 +2271,14 @@ class ObjectId extends BSONValue {
2134
2271
  workingId = inputId;
2135
2272
  }
2136
2273
  if (workingId == null || typeof workingId === 'number') {
2137
- this[kId] = ObjectId.generate(typeof workingId === 'number' ? workingId : undefined);
2274
+ this.buffer = ObjectId.generate(typeof workingId === 'number' ? workingId : undefined);
2138
2275
  }
2139
2276
  else if (ArrayBuffer.isView(workingId) && workingId.byteLength === 12) {
2140
- this[kId] = ByteUtils.toLocalBufferType(workingId);
2277
+ this.buffer = ByteUtils.toLocalBufferType(workingId);
2141
2278
  }
2142
2279
  else if (typeof workingId === 'string') {
2143
2280
  if (workingId.length === 24 && checkForHexRegExp.test(workingId)) {
2144
- this[kId] = ByteUtils.fromHex(workingId);
2281
+ this.buffer = ByteUtils.fromHex(workingId);
2145
2282
  }
2146
2283
  else {
2147
2284
  throw new BSONError('input must be a 24 character hex string, 12 byte Uint8Array, or an integer');
@@ -2155,10 +2292,10 @@ class ObjectId extends BSONValue {
2155
2292
  }
2156
2293
  }
2157
2294
  get id() {
2158
- return this[kId];
2295
+ return this.buffer;
2159
2296
  }
2160
2297
  set id(value) {
2161
- this[kId] = value;
2298
+ this.buffer = value;
2162
2299
  if (ObjectId.cacheHexString) {
2163
2300
  this.__id = ByteUtils.toHex(value);
2164
2301
  }
@@ -2181,8 +2318,8 @@ class ObjectId extends BSONValue {
2181
2318
  time = Math.floor(Date.now() / 1000);
2182
2319
  }
2183
2320
  const inc = ObjectId.getInc();
2184
- const buffer = ByteUtils.allocate(12);
2185
- BSONDataView.fromUint8Array(buffer).setUint32(0, time, false);
2321
+ const buffer = ByteUtils.allocateUnsafe(12);
2322
+ NumberUtils.setInt32BE(buffer, 0, time);
2186
2323
  if (PROCESS_UNIQUE === null) {
2187
2324
  PROCESS_UNIQUE = ByteUtils.randomBytes(5);
2188
2325
  }
@@ -2217,7 +2354,7 @@ class ObjectId extends BSONValue {
2217
2354
  return false;
2218
2355
  }
2219
2356
  if (ObjectId.is(otherId)) {
2220
- return this[kId][11] === otherId[kId][11] && ByteUtils.equals(this[kId], otherId[kId]);
2357
+ return (this.buffer[11] === otherId.buffer[11] && ByteUtils.equals(this.buffer, otherId.buffer));
2221
2358
  }
2222
2359
  if (typeof otherId === 'string') {
2223
2360
  return otherId.toLowerCase() === this.toHexString();
@@ -2231,16 +2368,33 @@ class ObjectId extends BSONValue {
2231
2368
  }
2232
2369
  getTimestamp() {
2233
2370
  const timestamp = new Date();
2234
- const time = BSONDataView.fromUint8Array(this.id).getUint32(0, false);
2371
+ const time = NumberUtils.getUint32BE(this.buffer, 0);
2235
2372
  timestamp.setTime(Math.floor(time) * 1000);
2236
2373
  return timestamp;
2237
2374
  }
2238
2375
  static createPk() {
2239
2376
  return new ObjectId();
2240
2377
  }
2378
+ serializeInto(uint8array, index) {
2379
+ uint8array[index] = this.buffer[0];
2380
+ uint8array[index + 1] = this.buffer[1];
2381
+ uint8array[index + 2] = this.buffer[2];
2382
+ uint8array[index + 3] = this.buffer[3];
2383
+ uint8array[index + 4] = this.buffer[4];
2384
+ uint8array[index + 5] = this.buffer[5];
2385
+ uint8array[index + 6] = this.buffer[6];
2386
+ uint8array[index + 7] = this.buffer[7];
2387
+ uint8array[index + 8] = this.buffer[8];
2388
+ uint8array[index + 9] = this.buffer[9];
2389
+ uint8array[index + 10] = this.buffer[10];
2390
+ uint8array[index + 11] = this.buffer[11];
2391
+ return 12;
2392
+ }
2241
2393
  static createFromTime(time) {
2242
- const buffer = ByteUtils.fromNumberArray([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
2243
- BSONDataView.fromUint8Array(buffer).setUint32(0, time, false);
2394
+ const buffer = ByteUtils.allocate(12);
2395
+ for (let i = 11; i >= 4; i--)
2396
+ buffer[i] = 0;
2397
+ NumberUtils.setInt32BE(buffer, 0, time);
2244
2398
  return new ObjectId(buffer);
2245
2399
  }
2246
2400
  static createFromHexString(hexString) {
@@ -2612,10 +2766,7 @@ const JS_INT_MIN_LONG = Long.fromNumber(JS_INT_MIN);
2612
2766
  function internalDeserialize(buffer, options, isArray) {
2613
2767
  options = options == null ? {} : options;
2614
2768
  const index = options && options.index ? options.index : 0;
2615
- const size = buffer[index] |
2616
- (buffer[index + 1] << 8) |
2617
- (buffer[index + 2] << 16) |
2618
- (buffer[index + 3] << 24);
2769
+ const size = NumberUtils.getInt32LE(buffer, index);
2619
2770
  if (size < 5) {
2620
2771
  throw new BSONError(`bson size must be >= 5, is ${size}`);
2621
2772
  }
@@ -2651,7 +2802,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2651
2802
  const validation = options.validation == null ? { utf8: true } : options.validation;
2652
2803
  let globalUTFValidation = true;
2653
2804
  let validationSetting;
2654
- const utf8KeysSet = new Set();
2805
+ let utf8KeysSet;
2655
2806
  const utf8ValidatedKeys = validation.utf8;
2656
2807
  if (typeof utf8ValidatedKeys === 'boolean') {
2657
2808
  validationSetting = utf8ValidatedKeys;
@@ -2673,6 +2824,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2673
2824
  }
2674
2825
  }
2675
2826
  if (!globalUTFValidation) {
2827
+ utf8KeysSet = new Set();
2676
2828
  for (const key of Object.keys(utf8ValidatedKeys)) {
2677
2829
  utf8KeysSet.add(key);
2678
2830
  }
@@ -2680,14 +2832,14 @@ function deserializeObject(buffer, index, options, isArray = false) {
2680
2832
  const startIndex = index;
2681
2833
  if (buffer.length < 5)
2682
2834
  throw new BSONError('corrupt bson message < 5 bytes long');
2683
- const size = buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24);
2835
+ const size = NumberUtils.getInt32LE(buffer, index);
2836
+ index += 4;
2684
2837
  if (size < 5 || size > buffer.length)
2685
2838
  throw new BSONError('corrupt bson message');
2686
2839
  const object = isArray ? [] : {};
2687
2840
  let arrayIndex = 0;
2688
2841
  const done = false;
2689
2842
  let isPossibleDBRef = isArray ? false : null;
2690
- const dataview = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
2691
2843
  while (!done) {
2692
2844
  const elementType = buffer[index++];
2693
2845
  if (elementType === 0)
@@ -2700,7 +2852,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2700
2852
  throw new BSONError('Bad BSON Document: illegal CString');
2701
2853
  const name = isArray ? arrayIndex++ : ByteUtils.toUTF8(buffer, index, i, false);
2702
2854
  let shouldValidateKey = true;
2703
- if (globalUTFValidation || utf8KeysSet.has(name)) {
2855
+ if (globalUTFValidation || utf8KeysSet?.has(name)) {
2704
2856
  shouldValidateKey = validationSetting;
2705
2857
  }
2706
2858
  else {
@@ -2712,10 +2864,8 @@ function deserializeObject(buffer, index, options, isArray = false) {
2712
2864
  let value;
2713
2865
  index = i + 1;
2714
2866
  if (elementType === BSON_DATA_STRING) {
2715
- const stringSize = buffer[index++] |
2716
- (buffer[index++] << 8) |
2717
- (buffer[index++] << 16) |
2718
- (buffer[index++] << 24);
2867
+ const stringSize = NumberUtils.getInt32LE(buffer, index);
2868
+ index += 4;
2719
2869
  if (stringSize <= 0 ||
2720
2870
  stringSize > buffer.length - index ||
2721
2871
  buffer[index + stringSize - 1] !== 0) {
@@ -2725,38 +2875,30 @@ function deserializeObject(buffer, index, options, isArray = false) {
2725
2875
  index = index + stringSize;
2726
2876
  }
2727
2877
  else if (elementType === BSON_DATA_OID) {
2728
- const oid = ByteUtils.allocate(12);
2729
- oid.set(buffer.subarray(index, index + 12));
2878
+ const oid = ByteUtils.allocateUnsafe(12);
2879
+ for (let i = 0; i < 12; i++)
2880
+ oid[i] = buffer[index + i];
2730
2881
  value = new ObjectId(oid);
2731
2882
  index = index + 12;
2732
2883
  }
2733
2884
  else if (elementType === BSON_DATA_INT && promoteValues === false) {
2734
- value = new Int32(buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24));
2885
+ value = new Int32(NumberUtils.getInt32LE(buffer, index));
2886
+ index += 4;
2735
2887
  }
2736
2888
  else if (elementType === BSON_DATA_INT) {
2737
- value =
2738
- buffer[index++] |
2739
- (buffer[index++] << 8) |
2740
- (buffer[index++] << 16) |
2741
- (buffer[index++] << 24);
2742
- }
2743
- else if (elementType === BSON_DATA_NUMBER && promoteValues === false) {
2744
- value = new Double(dataview.getFloat64(index, true));
2745
- index = index + 8;
2889
+ value = NumberUtils.getInt32LE(buffer, index);
2890
+ index += 4;
2746
2891
  }
2747
2892
  else if (elementType === BSON_DATA_NUMBER) {
2748
- value = dataview.getFloat64(index, true);
2749
- index = index + 8;
2893
+ value = NumberUtils.getFloat64LE(buffer, index);
2894
+ index += 8;
2895
+ if (promoteValues === false)
2896
+ value = new Double(value);
2750
2897
  }
2751
2898
  else if (elementType === BSON_DATA_DATE) {
2752
- const lowBits = buffer[index++] |
2753
- (buffer[index++] << 8) |
2754
- (buffer[index++] << 16) |
2755
- (buffer[index++] << 24);
2756
- const highBits = buffer[index++] |
2757
- (buffer[index++] << 8) |
2758
- (buffer[index++] << 16) |
2759
- (buffer[index++] << 24);
2899
+ const lowBits = NumberUtils.getInt32LE(buffer, index);
2900
+ const highBits = NumberUtils.getInt32LE(buffer, index + 4);
2901
+ index += 8;
2760
2902
  value = new Date(new Long(lowBits, highBits).toNumber());
2761
2903
  }
2762
2904
  else if (elementType === BSON_DATA_BOOLEAN) {
@@ -2766,10 +2908,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2766
2908
  }
2767
2909
  else if (elementType === BSON_DATA_OBJECT) {
2768
2910
  const _index = index;
2769
- const objectSize = buffer[index] |
2770
- (buffer[index + 1] << 8) |
2771
- (buffer[index + 2] << 16) |
2772
- (buffer[index + 3] << 24);
2911
+ const objectSize = NumberUtils.getInt32LE(buffer, index);
2773
2912
  if (objectSize <= 0 || objectSize > buffer.length - index)
2774
2913
  throw new BSONError('bad embedded document length in bson');
2775
2914
  if (raw) {
@@ -2786,10 +2925,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2786
2925
  }
2787
2926
  else if (elementType === BSON_DATA_ARRAY) {
2788
2927
  const _index = index;
2789
- const objectSize = buffer[index] |
2790
- (buffer[index + 1] << 8) |
2791
- (buffer[index + 2] << 16) |
2792
- (buffer[index + 3] << 24);
2928
+ const objectSize = NumberUtils.getInt32LE(buffer, index);
2793
2929
  let arrayOptions = options;
2794
2930
  const stopIndex = index + objectSize;
2795
2931
  if (fieldsAsRaw && fieldsAsRaw[name]) {
@@ -2812,40 +2948,36 @@ function deserializeObject(buffer, index, options, isArray = false) {
2812
2948
  value = null;
2813
2949
  }
2814
2950
  else if (elementType === BSON_DATA_LONG) {
2815
- const dataview = BSONDataView.fromUint8Array(buffer.subarray(index, index + 8));
2816
- const lowBits = buffer[index++] |
2817
- (buffer[index++] << 8) |
2818
- (buffer[index++] << 16) |
2819
- (buffer[index++] << 24);
2820
- const highBits = buffer[index++] |
2821
- (buffer[index++] << 8) |
2822
- (buffer[index++] << 16) |
2823
- (buffer[index++] << 24);
2824
- const long = new Long(lowBits, highBits);
2825
2951
  if (useBigInt64) {
2826
- value = dataview.getBigInt64(0, true);
2827
- }
2828
- else if (promoteLongs && promoteValues === true) {
2829
- value =
2830
- long.lessThanOrEqual(JS_INT_MAX_LONG) && long.greaterThanOrEqual(JS_INT_MIN_LONG)
2831
- ? long.toNumber()
2832
- : long;
2952
+ value = NumberUtils.getBigInt64LE(buffer, index);
2953
+ index += 8;
2833
2954
  }
2834
2955
  else {
2835
- value = long;
2956
+ const lowBits = NumberUtils.getInt32LE(buffer, index);
2957
+ const highBits = NumberUtils.getInt32LE(buffer, index + 4);
2958
+ index += 8;
2959
+ const long = new Long(lowBits, highBits);
2960
+ if (promoteLongs && promoteValues === true) {
2961
+ value =
2962
+ long.lessThanOrEqual(JS_INT_MAX_LONG) && long.greaterThanOrEqual(JS_INT_MIN_LONG)
2963
+ ? long.toNumber()
2964
+ : long;
2965
+ }
2966
+ else {
2967
+ value = long;
2968
+ }
2836
2969
  }
2837
2970
  }
2838
2971
  else if (elementType === BSON_DATA_DECIMAL128) {
2839
- const bytes = ByteUtils.allocate(16);
2840
- bytes.set(buffer.subarray(index, index + 16), 0);
2972
+ const bytes = ByteUtils.allocateUnsafe(16);
2973
+ for (let i = 0; i < 16; i++)
2974
+ bytes[i] = buffer[index + i];
2841
2975
  index = index + 16;
2842
2976
  value = new Decimal128(bytes);
2843
2977
  }
2844
2978
  else if (elementType === BSON_DATA_BINARY) {
2845
- let binarySize = buffer[index++] |
2846
- (buffer[index++] << 8) |
2847
- (buffer[index++] << 16) |
2848
- (buffer[index++] << 24);
2979
+ let binarySize = NumberUtils.getInt32LE(buffer, index);
2980
+ index += 4;
2849
2981
  const totalBinarySize = binarySize;
2850
2982
  const subType = buffer[index++];
2851
2983
  if (binarySize < 0)
@@ -2854,11 +2986,8 @@ function deserializeObject(buffer, index, options, isArray = false) {
2854
2986
  throw new BSONError('Binary type size larger than document size');
2855
2987
  if (buffer['slice'] != null) {
2856
2988
  if (subType === Binary.SUBTYPE_BYTE_ARRAY) {
2857
- binarySize =
2858
- buffer[index++] |
2859
- (buffer[index++] << 8) |
2860
- (buffer[index++] << 16) |
2861
- (buffer[index++] << 24);
2989
+ binarySize = NumberUtils.getInt32LE(buffer, index);
2990
+ index += 4;
2862
2991
  if (binarySize < 0)
2863
2992
  throw new BSONError('Negative binary type element size found for subtype 0x02');
2864
2993
  if (binarySize > totalBinarySize - 4)
@@ -2877,13 +3006,9 @@ function deserializeObject(buffer, index, options, isArray = false) {
2877
3006
  }
2878
3007
  }
2879
3008
  else {
2880
- const _buffer = ByteUtils.allocate(binarySize);
2881
3009
  if (subType === Binary.SUBTYPE_BYTE_ARRAY) {
2882
- binarySize =
2883
- buffer[index++] |
2884
- (buffer[index++] << 8) |
2885
- (buffer[index++] << 16) |
2886
- (buffer[index++] << 24);
3010
+ binarySize = NumberUtils.getInt32LE(buffer, index);
3011
+ index += 4;
2887
3012
  if (binarySize < 0)
2888
3013
  throw new BSONError('Negative binary type element size found for subtype 0x02');
2889
3014
  if (binarySize > totalBinarySize - 4)
@@ -2891,11 +3016,11 @@ function deserializeObject(buffer, index, options, isArray = false) {
2891
3016
  if (binarySize < totalBinarySize - 4)
2892
3017
  throw new BSONError('Binary type with subtype 0x02 contains too short binary size');
2893
3018
  }
2894
- for (i = 0; i < binarySize; i++) {
2895
- _buffer[i] = buffer[index + i];
2896
- }
2897
3019
  if (promoteBuffers && promoteValues) {
2898
- value = _buffer;
3020
+ value = ByteUtils.allocateUnsafe(binarySize);
3021
+ for (i = 0; i < binarySize; i++) {
3022
+ value[i] = buffer[index + i];
3023
+ }
2899
3024
  }
2900
3025
  else {
2901
3026
  value = new Binary(buffer.slice(index, index + binarySize), subType);
@@ -2959,10 +3084,8 @@ function deserializeObject(buffer, index, options, isArray = false) {
2959
3084
  value = new BSONRegExp(source, regExpOptions);
2960
3085
  }
2961
3086
  else if (elementType === BSON_DATA_SYMBOL) {
2962
- const stringSize = buffer[index++] |
2963
- (buffer[index++] << 8) |
2964
- (buffer[index++] << 16) |
2965
- (buffer[index++] << 24);
3087
+ const stringSize = NumberUtils.getInt32LE(buffer, index);
3088
+ index += 4;
2966
3089
  if (stringSize <= 0 ||
2967
3090
  stringSize > buffer.length - index ||
2968
3091
  buffer[index + stringSize - 1] !== 0) {
@@ -2973,15 +3096,11 @@ function deserializeObject(buffer, index, options, isArray = false) {
2973
3096
  index = index + stringSize;
2974
3097
  }
2975
3098
  else if (elementType === BSON_DATA_TIMESTAMP) {
2976
- const i = buffer[index++] +
2977
- buffer[index++] * (1 << 8) +
2978
- buffer[index++] * (1 << 16) +
2979
- buffer[index++] * (1 << 24);
2980
- const t = buffer[index++] +
2981
- buffer[index++] * (1 << 8) +
2982
- buffer[index++] * (1 << 16) +
2983
- buffer[index++] * (1 << 24);
2984
- value = new Timestamp({ i, t });
3099
+ value = new Timestamp({
3100
+ i: NumberUtils.getUint32LE(buffer, index),
3101
+ t: NumberUtils.getUint32LE(buffer, index + 4)
3102
+ });
3103
+ index += 8;
2985
3104
  }
2986
3105
  else if (elementType === BSON_DATA_MIN_KEY) {
2987
3106
  value = new MinKey();
@@ -2990,10 +3109,8 @@ function deserializeObject(buffer, index, options, isArray = false) {
2990
3109
  value = new MaxKey();
2991
3110
  }
2992
3111
  else if (elementType === BSON_DATA_CODE) {
2993
- const stringSize = buffer[index++] |
2994
- (buffer[index++] << 8) |
2995
- (buffer[index++] << 16) |
2996
- (buffer[index++] << 24);
3112
+ const stringSize = NumberUtils.getInt32LE(buffer, index);
3113
+ index += 4;
2997
3114
  if (stringSize <= 0 ||
2998
3115
  stringSize > buffer.length - index ||
2999
3116
  buffer[index + stringSize - 1] !== 0) {
@@ -3004,17 +3121,13 @@ function deserializeObject(buffer, index, options, isArray = false) {
3004
3121
  index = index + stringSize;
3005
3122
  }
3006
3123
  else if (elementType === BSON_DATA_CODE_W_SCOPE) {
3007
- const totalSize = buffer[index++] |
3008
- (buffer[index++] << 8) |
3009
- (buffer[index++] << 16) |
3010
- (buffer[index++] << 24);
3124
+ const totalSize = NumberUtils.getInt32LE(buffer, index);
3125
+ index += 4;
3011
3126
  if (totalSize < 4 + 4 + 4 + 1) {
3012
3127
  throw new BSONError('code_w_scope total size shorter minimum expected length');
3013
3128
  }
3014
- const stringSize = buffer[index++] |
3015
- (buffer[index++] << 8) |
3016
- (buffer[index++] << 16) |
3017
- (buffer[index++] << 24);
3129
+ const stringSize = NumberUtils.getInt32LE(buffer, index);
3130
+ index += 4;
3018
3131
  if (stringSize <= 0 ||
3019
3132
  stringSize > buffer.length - index ||
3020
3133
  buffer[index + stringSize - 1] !== 0) {
@@ -3023,10 +3136,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
3023
3136
  const functionString = ByteUtils.toUTF8(buffer, index, index + stringSize - 1, shouldValidateKey);
3024
3137
  index = index + stringSize;
3025
3138
  const _index = index;
3026
- const objectSize = buffer[index] |
3027
- (buffer[index + 1] << 8) |
3028
- (buffer[index + 2] << 16) |
3029
- (buffer[index + 3] << 24);
3139
+ const objectSize = NumberUtils.getInt32LE(buffer, index);
3030
3140
  const scopeObject = deserializeObject(buffer, _index, options, false);
3031
3141
  index = index + objectSize;
3032
3142
  if (totalSize < 4 + 4 + objectSize + stringSize) {
@@ -3038,10 +3148,8 @@ function deserializeObject(buffer, index, options, isArray = false) {
3038
3148
  value = new Code(functionString, scopeObject);
3039
3149
  }
3040
3150
  else if (elementType === BSON_DATA_DBPOINTER) {
3041
- const stringSize = buffer[index++] |
3042
- (buffer[index++] << 8) |
3043
- (buffer[index++] << 16) |
3044
- (buffer[index++] << 24);
3151
+ const stringSize = NumberUtils.getInt32LE(buffer, index);
3152
+ index += 4;
3045
3153
  if (stringSize <= 0 ||
3046
3154
  stringSize > buffer.length - index ||
3047
3155
  buffer[index + stringSize - 1] !== 0)
@@ -3053,8 +3161,9 @@ function deserializeObject(buffer, index, options, isArray = false) {
3053
3161
  }
3054
3162
  const namespace = ByteUtils.toUTF8(buffer, index, index + stringSize - 1, false);
3055
3163
  index = index + stringSize;
3056
- const oidBuffer = ByteUtils.allocate(12);
3057
- oidBuffer.set(buffer.subarray(index, index + 12), 0);
3164
+ const oidBuffer = ByteUtils.allocateUnsafe(12);
3165
+ for (let i = 0; i < 12; i++)
3166
+ oidBuffer[i] = buffer[index + i];
3058
3167
  const oid = new ObjectId(oidBuffer);
3059
3168
  index = index + 12;
3060
3169
  value = new DBRef(namespace, oid);
@@ -3099,17 +3208,11 @@ function serializeString(buffer, key, value, index) {
3099
3208
  index = index + numberOfWrittenBytes + 1;
3100
3209
  buffer[index - 1] = 0;
3101
3210
  const size = ByteUtils.encodeUTF8Into(buffer, value, index + 4);
3102
- buffer[index + 3] = ((size + 1) >> 24) & 0xff;
3103
- buffer[index + 2] = ((size + 1) >> 16) & 0xff;
3104
- buffer[index + 1] = ((size + 1) >> 8) & 0xff;
3105
- buffer[index] = (size + 1) & 0xff;
3211
+ NumberUtils.setInt32LE(buffer, index, size + 1);
3106
3212
  index = index + 4 + size;
3107
3213
  buffer[index++] = 0;
3108
3214
  return index;
3109
3215
  }
3110
- const NUMBER_SPACE = new DataView(new ArrayBuffer(8), 0, 8);
3111
- const FOUR_BYTE_VIEW_ON_NUMBER = new Uint8Array(NUMBER_SPACE.buffer, 0, 4);
3112
- const EIGHT_BYTE_VIEW_ON_NUMBER = new Uint8Array(NUMBER_SPACE.buffer, 0, 8);
3113
3216
  function serializeNumber(buffer, key, value, index) {
3114
3217
  const isNegativeZero = Object.is(value, -0);
3115
3218
  const type = !isNegativeZero &&
@@ -3118,19 +3221,16 @@ function serializeNumber(buffer, key, value, index) {
3118
3221
  value >= BSON_INT32_MIN
3119
3222
  ? BSON_DATA_INT
3120
3223
  : BSON_DATA_NUMBER;
3121
- if (type === BSON_DATA_INT) {
3122
- NUMBER_SPACE.setInt32(0, value, true);
3123
- }
3124
- else {
3125
- NUMBER_SPACE.setFloat64(0, value, true);
3126
- }
3127
- const bytes = type === BSON_DATA_INT ? FOUR_BYTE_VIEW_ON_NUMBER : EIGHT_BYTE_VIEW_ON_NUMBER;
3128
3224
  buffer[index++] = type;
3129
3225
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3130
3226
  index = index + numberOfWrittenBytes;
3131
3227
  buffer[index++] = 0x00;
3132
- buffer.set(bytes, index);
3133
- index += bytes.byteLength;
3228
+ if (type === BSON_DATA_INT) {
3229
+ index += NumberUtils.setInt32LE(buffer, index, value);
3230
+ }
3231
+ else {
3232
+ index += NumberUtils.setFloat64LE(buffer, index, value);
3233
+ }
3134
3234
  return index;
3135
3235
  }
3136
3236
  function serializeBigInt(buffer, key, value, index) {
@@ -3138,9 +3238,7 @@ function serializeBigInt(buffer, key, value, index) {
3138
3238
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3139
3239
  index += numberOfWrittenBytes;
3140
3240
  buffer[index++] = 0;
3141
- NUMBER_SPACE.setBigInt64(0, value, true);
3142
- buffer.set(EIGHT_BYTE_VIEW_ON_NUMBER, index);
3143
- index += EIGHT_BYTE_VIEW_ON_NUMBER.byteLength;
3241
+ index += NumberUtils.setBigInt64LE(buffer, index, value);
3144
3242
  return index;
3145
3243
  }
3146
3244
  function serializeNull(buffer, key, _, index) {
@@ -3166,14 +3264,8 @@ function serializeDate(buffer, key, value, index) {
3166
3264
  const dateInMilis = Long.fromNumber(value.getTime());
3167
3265
  const lowBits = dateInMilis.getLowBits();
3168
3266
  const highBits = dateInMilis.getHighBits();
3169
- buffer[index++] = lowBits & 0xff;
3170
- buffer[index++] = (lowBits >> 8) & 0xff;
3171
- buffer[index++] = (lowBits >> 16) & 0xff;
3172
- buffer[index++] = (lowBits >> 24) & 0xff;
3173
- buffer[index++] = highBits & 0xff;
3174
- buffer[index++] = (highBits >> 8) & 0xff;
3175
- buffer[index++] = (highBits >> 16) & 0xff;
3176
- buffer[index++] = (highBits >> 24) & 0xff;
3267
+ index += NumberUtils.setInt32LE(buffer, index, lowBits);
3268
+ index += NumberUtils.setInt32LE(buffer, index, highBits);
3177
3269
  return index;
3178
3270
  }
3179
3271
  function serializeRegExp(buffer, key, value, index) {
@@ -3230,15 +3322,7 @@ function serializeObjectId(buffer, key, value, index) {
3230
3322
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3231
3323
  index = index + numberOfWrittenBytes;
3232
3324
  buffer[index++] = 0;
3233
- const idValue = value.id;
3234
- if (isUint8Array(idValue)) {
3235
- for (let i = 0; i < 12; i++) {
3236
- buffer[index++] = idValue[i];
3237
- }
3238
- }
3239
- else {
3240
- throw new BSONError('object [' + JSON.stringify(value) + '] is not a valid ObjectId');
3241
- }
3325
+ index += value.serializeInto(buffer, index);
3242
3326
  return index;
3243
3327
  }
3244
3328
  function serializeBuffer(buffer, key, value, index) {
@@ -3247,12 +3331,15 @@ function serializeBuffer(buffer, key, value, index) {
3247
3331
  index = index + numberOfWrittenBytes;
3248
3332
  buffer[index++] = 0;
3249
3333
  const size = value.length;
3250
- buffer[index++] = size & 0xff;
3251
- buffer[index++] = (size >> 8) & 0xff;
3252
- buffer[index++] = (size >> 16) & 0xff;
3253
- buffer[index++] = (size >> 24) & 0xff;
3334
+ index += NumberUtils.setInt32LE(buffer, index, size);
3254
3335
  buffer[index++] = BSON_BINARY_SUBTYPE_DEFAULT;
3255
- buffer.set(value, index);
3336
+ if (size <= 16) {
3337
+ for (let i = 0; i < size; i++)
3338
+ buffer[index + i] = value[i];
3339
+ }
3340
+ else {
3341
+ buffer.set(value, index);
3342
+ }
3256
3343
  index = index + size;
3257
3344
  return index;
3258
3345
  }
@@ -3274,7 +3361,8 @@ function serializeDecimal128(buffer, key, value, index) {
3274
3361
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3275
3362
  index = index + numberOfWrittenBytes;
3276
3363
  buffer[index++] = 0;
3277
- buffer.set(value.bytes.subarray(0, 16), index);
3364
+ for (let i = 0; i < 16; i++)
3365
+ buffer[index + i] = value.bytes[i];
3278
3366
  return index + 16;
3279
3367
  }
3280
3368
  function serializeLong(buffer, key, value, index) {
@@ -3285,14 +3373,8 @@ function serializeLong(buffer, key, value, index) {
3285
3373
  buffer[index++] = 0;
3286
3374
  const lowBits = value.getLowBits();
3287
3375
  const highBits = value.getHighBits();
3288
- buffer[index++] = lowBits & 0xff;
3289
- buffer[index++] = (lowBits >> 8) & 0xff;
3290
- buffer[index++] = (lowBits >> 16) & 0xff;
3291
- buffer[index++] = (lowBits >> 24) & 0xff;
3292
- buffer[index++] = highBits & 0xff;
3293
- buffer[index++] = (highBits >> 8) & 0xff;
3294
- buffer[index++] = (highBits >> 16) & 0xff;
3295
- buffer[index++] = (highBits >> 24) & 0xff;
3376
+ index += NumberUtils.setInt32LE(buffer, index, lowBits);
3377
+ index += NumberUtils.setInt32LE(buffer, index, highBits);
3296
3378
  return index;
3297
3379
  }
3298
3380
  function serializeInt32(buffer, key, value, index) {
@@ -3301,10 +3383,7 @@ function serializeInt32(buffer, key, value, index) {
3301
3383
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3302
3384
  index = index + numberOfWrittenBytes;
3303
3385
  buffer[index++] = 0;
3304
- buffer[index++] = value & 0xff;
3305
- buffer[index++] = (value >> 8) & 0xff;
3306
- buffer[index++] = (value >> 16) & 0xff;
3307
- buffer[index++] = (value >> 24) & 0xff;
3386
+ index += NumberUtils.setInt32LE(buffer, index, value);
3308
3387
  return index;
3309
3388
  }
3310
3389
  function serializeDouble(buffer, key, value, index) {
@@ -3312,9 +3391,7 @@ function serializeDouble(buffer, key, value, index) {
3312
3391
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3313
3392
  index = index + numberOfWrittenBytes;
3314
3393
  buffer[index++] = 0;
3315
- NUMBER_SPACE.setFloat64(0, value.value, true);
3316
- buffer.set(EIGHT_BYTE_VIEW_ON_NUMBER, index);
3317
- index = index + 8;
3394
+ index += NumberUtils.setFloat64LE(buffer, index, value.value);
3318
3395
  return index;
3319
3396
  }
3320
3397
  function serializeFunction(buffer, key, value, index) {
@@ -3324,10 +3401,7 @@ function serializeFunction(buffer, key, value, index) {
3324
3401
  buffer[index++] = 0;
3325
3402
  const functionString = value.toString();
3326
3403
  const size = ByteUtils.encodeUTF8Into(buffer, functionString, index + 4) + 1;
3327
- buffer[index] = size & 0xff;
3328
- buffer[index + 1] = (size >> 8) & 0xff;
3329
- buffer[index + 2] = (size >> 16) & 0xff;
3330
- buffer[index + 3] = (size >> 24) & 0xff;
3404
+ NumberUtils.setInt32LE(buffer, index, size);
3331
3405
  index = index + 4 + size - 1;
3332
3406
  buffer[index++] = 0;
3333
3407
  return index;
@@ -3342,19 +3416,13 @@ function serializeCode(buffer, key, value, index, checkKeys = false, depth = 0,
3342
3416
  const functionString = value.code;
3343
3417
  index = index + 4;
3344
3418
  const codeSize = ByteUtils.encodeUTF8Into(buffer, functionString, index + 4) + 1;
3345
- buffer[index] = codeSize & 0xff;
3346
- buffer[index + 1] = (codeSize >> 8) & 0xff;
3347
- buffer[index + 2] = (codeSize >> 16) & 0xff;
3348
- buffer[index + 3] = (codeSize >> 24) & 0xff;
3419
+ NumberUtils.setInt32LE(buffer, index, codeSize);
3349
3420
  buffer[index + 4 + codeSize - 1] = 0;
3350
3421
  index = index + codeSize + 4;
3351
3422
  const endIndex = serializeInto(buffer, value.scope, checkKeys, index, depth + 1, serializeFunctions, ignoreUndefined, path);
3352
3423
  index = endIndex - 1;
3353
3424
  const totalSize = endIndex - startIndex;
3354
- buffer[startIndex++] = totalSize & 0xff;
3355
- buffer[startIndex++] = (totalSize >> 8) & 0xff;
3356
- buffer[startIndex++] = (totalSize >> 16) & 0xff;
3357
- buffer[startIndex++] = (totalSize >> 24) & 0xff;
3425
+ startIndex += NumberUtils.setInt32LE(buffer, startIndex, totalSize);
3358
3426
  buffer[index++] = 0;
3359
3427
  }
3360
3428
  else {
@@ -3364,10 +3432,7 @@ function serializeCode(buffer, key, value, index, checkKeys = false, depth = 0,
3364
3432
  buffer[index++] = 0;
3365
3433
  const functionString = value.code.toString();
3366
3434
  const size = ByteUtils.encodeUTF8Into(buffer, functionString, index + 4) + 1;
3367
- buffer[index] = size & 0xff;
3368
- buffer[index + 1] = (size >> 8) & 0xff;
3369
- buffer[index + 2] = (size >> 16) & 0xff;
3370
- buffer[index + 3] = (size >> 24) & 0xff;
3435
+ NumberUtils.setInt32LE(buffer, index, size);
3371
3436
  index = index + 4 + size - 1;
3372
3437
  buffer[index++] = 0;
3373
3438
  }
@@ -3382,19 +3447,19 @@ function serializeBinary(buffer, key, value, index) {
3382
3447
  let size = value.position;
3383
3448
  if (value.sub_type === Binary.SUBTYPE_BYTE_ARRAY)
3384
3449
  size = size + 4;
3385
- buffer[index++] = size & 0xff;
3386
- buffer[index++] = (size >> 8) & 0xff;
3387
- buffer[index++] = (size >> 16) & 0xff;
3388
- buffer[index++] = (size >> 24) & 0xff;
3450
+ index += NumberUtils.setInt32LE(buffer, index, size);
3389
3451
  buffer[index++] = value.sub_type;
3390
3452
  if (value.sub_type === Binary.SUBTYPE_BYTE_ARRAY) {
3391
3453
  size = size - 4;
3392
- buffer[index++] = size & 0xff;
3393
- buffer[index++] = (size >> 8) & 0xff;
3394
- buffer[index++] = (size >> 16) & 0xff;
3395
- buffer[index++] = (size >> 24) & 0xff;
3454
+ index += NumberUtils.setInt32LE(buffer, index, size);
3455
+ }
3456
+ if (size <= 16) {
3457
+ for (let i = 0; i < size; i++)
3458
+ buffer[index + i] = data[i];
3459
+ }
3460
+ else {
3461
+ buffer.set(data, index);
3396
3462
  }
3397
- buffer.set(data, index);
3398
3463
  index = index + value.position;
3399
3464
  return index;
3400
3465
  }
@@ -3404,12 +3469,9 @@ function serializeSymbol(buffer, key, value, index) {
3404
3469
  index = index + numberOfWrittenBytes;
3405
3470
  buffer[index++] = 0;
3406
3471
  const size = ByteUtils.encodeUTF8Into(buffer, value.value, index + 4) + 1;
3407
- buffer[index] = size & 0xff;
3408
- buffer[index + 1] = (size >> 8) & 0xff;
3409
- buffer[index + 2] = (size >> 16) & 0xff;
3410
- buffer[index + 3] = (size >> 24) & 0xff;
3472
+ NumberUtils.setInt32LE(buffer, index, size);
3411
3473
  index = index + 4 + size - 1;
3412
- buffer[index++] = 0x00;
3474
+ buffer[index++] = 0;
3413
3475
  return index;
3414
3476
  }
3415
3477
  function serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path) {
@@ -3428,10 +3490,7 @@ function serializeDBRef(buffer, key, value, index, depth, serializeFunctions, pa
3428
3490
  output = Object.assign(output, value.fields);
3429
3491
  const endIndex = serializeInto(buffer, output, false, index, depth + 1, serializeFunctions, true, path);
3430
3492
  const size = endIndex - startIndex;
3431
- buffer[startIndex++] = size & 0xff;
3432
- buffer[startIndex++] = (size >> 8) & 0xff;
3433
- buffer[startIndex++] = (size >> 16) & 0xff;
3434
- buffer[startIndex++] = (size >> 24) & 0xff;
3493
+ startIndex += NumberUtils.setInt32LE(buffer, index, size);
3435
3494
  return endIndex;
3436
3495
  }
3437
3496
  function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializeFunctions, ignoreUndefined, path) {
@@ -3567,7 +3626,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3567
3626
  if ('$' === key[0]) {
3568
3627
  throw new BSONError('key ' + key + " must not start with '$'");
3569
3628
  }
3570
- else if (~key.indexOf('.')) {
3629
+ else if (key.includes('.')) {
3571
3630
  throw new BSONError('key ' + key + " must not contain '.'");
3572
3631
  }
3573
3632
  }
@@ -3665,7 +3724,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3665
3724
  if ('$' === key[0]) {
3666
3725
  throw new BSONError('key ' + key + " must not start with '$'");
3667
3726
  }
3668
- else if (~key.indexOf('.')) {
3727
+ else if (key.includes('.')) {
3669
3728
  throw new BSONError('key ' + key + " must not contain '.'");
3670
3729
  }
3671
3730
  }
@@ -3749,10 +3808,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3749
3808
  path.delete(object);
3750
3809
  buffer[index++] = 0x00;
3751
3810
  const size = index - startingIndex;
3752
- buffer[startingIndex++] = size & 0xff;
3753
- buffer[startingIndex++] = (size >> 8) & 0xff;
3754
- buffer[startingIndex++] = (size >> 16) & 0xff;
3755
- buffer[startingIndex++] = (size >> 24) & 0xff;
3811
+ startingIndex += NumberUtils.setInt32LE(buffer, startingIndex, size);
3756
3812
  return index;
3757
3813
  }
3758
3814
 
@@ -4082,7 +4138,7 @@ function serialize(object, options = {}) {
4082
4138
  buffer = ByteUtils.allocate(minInternalBufferSize);
4083
4139
  }
4084
4140
  const serializationIndex = serializeInto(buffer, object, checkKeys, 0, 0, serializeFunctions, ignoreUndefined, null);
4085
- const finishedBuffer = ByteUtils.allocate(serializationIndex);
4141
+ const finishedBuffer = ByteUtils.allocateUnsafe(serializationIndex);
4086
4142
  finishedBuffer.set(buffer.subarray(0, serializationIndex), 0);
4087
4143
  return finishedBuffer;
4088
4144
  }
@@ -4109,10 +4165,7 @@ function deserializeStream(data, startIndex, numberOfDocuments, documents, docSt
4109
4165
  const bufferData = ByteUtils.toLocalBufferType(data);
4110
4166
  let index = startIndex;
4111
4167
  for (let i = 0; i < numberOfDocuments; i++) {
4112
- const size = bufferData[index] |
4113
- (bufferData[index + 1] << 8) |
4114
- (bufferData[index + 2] << 16) |
4115
- (bufferData[index + 3] << 24);
4168
+ const size = NumberUtils.getInt32LE(bufferData, index);
4116
4169
  internalOptions.index = index;
4117
4170
  documents[docStartIndex + i] = internalDeserialize(bufferData, internalOptions);
4118
4171
  index = index + size;