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.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,132 @@ 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
+ FLOAT[0] = -1;
2127
+ const isBigEndian = FLOAT_BYTES[7] === 0;
2128
+ const NumberUtils = {
2129
+ getInt32LE(source, offset) {
2130
+ return (source[offset] |
2131
+ (source[offset + 1] << 8) |
2132
+ (source[offset + 2] << 16) |
2133
+ (source[offset + 3] << 24));
2134
+ },
2135
+ getUint32LE(source, offset) {
2136
+ return (source[offset] +
2137
+ source[offset + 1] * 256 +
2138
+ source[offset + 2] * 65536 +
2139
+ source[offset + 3] * 16777216);
2140
+ },
2141
+ getUint32BE(source, offset) {
2142
+ return (source[offset + 3] +
2143
+ source[offset + 2] * 256 +
2144
+ source[offset + 1] * 65536 +
2145
+ source[offset] * 16777216);
2146
+ },
2147
+ getBigInt64LE(source, offset) {
2148
+ const hi = BigInt(source[offset + 4] +
2149
+ source[offset + 5] * 256 +
2150
+ source[offset + 6] * 65536 +
2151
+ (source[offset + 7] << 24));
2152
+ const lo = BigInt(source[offset] +
2153
+ source[offset + 1] * 256 +
2154
+ source[offset + 2] * 65536 +
2155
+ source[offset + 3] * 16777216);
2156
+ return (hi << BigInt(32)) + lo;
2157
+ },
2158
+ getFloat64LE: isBigEndian
2159
+ ? (source, offset) => {
2160
+ FLOAT_BYTES[7] = source[offset];
2161
+ FLOAT_BYTES[6] = source[offset + 1];
2162
+ FLOAT_BYTES[5] = source[offset + 2];
2163
+ FLOAT_BYTES[4] = source[offset + 3];
2164
+ FLOAT_BYTES[3] = source[offset + 4];
2165
+ FLOAT_BYTES[2] = source[offset + 5];
2166
+ FLOAT_BYTES[1] = source[offset + 6];
2167
+ FLOAT_BYTES[0] = source[offset + 7];
2168
+ return FLOAT[0];
2169
+ }
2170
+ : (source, offset) => {
2171
+ FLOAT_BYTES[0] = source[offset];
2172
+ FLOAT_BYTES[1] = source[offset + 1];
2173
+ FLOAT_BYTES[2] = source[offset + 2];
2174
+ FLOAT_BYTES[3] = source[offset + 3];
2175
+ FLOAT_BYTES[4] = source[offset + 4];
2176
+ FLOAT_BYTES[5] = source[offset + 5];
2177
+ FLOAT_BYTES[6] = source[offset + 6];
2178
+ FLOAT_BYTES[7] = source[offset + 7];
2179
+ return FLOAT[0];
2180
+ },
2181
+ setInt32BE(destination, offset, value) {
2182
+ destination[offset + 3] = value;
2183
+ value >>>= 8;
2184
+ destination[offset + 2] = value;
2185
+ value >>>= 8;
2186
+ destination[offset + 1] = value;
2187
+ value >>>= 8;
2188
+ destination[offset] = value;
2189
+ return 4;
2190
+ },
2191
+ setInt32LE(destination, offset, value) {
2192
+ destination[offset] = value;
2193
+ value >>>= 8;
2194
+ destination[offset + 1] = value;
2195
+ value >>>= 8;
2196
+ destination[offset + 2] = value;
2197
+ value >>>= 8;
2198
+ destination[offset + 3] = value;
2199
+ return 4;
2200
+ },
2201
+ setBigInt64LE(destination, offset, value) {
2202
+ const mask32bits = BigInt(4294967295);
2203
+ let lo = Number(value & mask32bits);
2204
+ destination[offset] = lo;
2205
+ lo >>= 8;
2206
+ destination[offset + 1] = lo;
2207
+ lo >>= 8;
2208
+ destination[offset + 2] = lo;
2209
+ lo >>= 8;
2210
+ destination[offset + 3] = lo;
2211
+ let hi = Number((value >> BigInt(32)) & mask32bits);
2212
+ destination[offset + 4] = hi;
2213
+ hi >>= 8;
2214
+ destination[offset + 5] = hi;
2215
+ hi >>= 8;
2216
+ destination[offset + 6] = hi;
2217
+ hi >>= 8;
2218
+ destination[offset + 7] = hi;
2219
+ return 8;
2220
+ },
2221
+ setFloat64LE: isBigEndian
2222
+ ? (destination, offset, value) => {
2223
+ FLOAT[0] = value;
2224
+ destination[offset] = FLOAT_BYTES[7];
2225
+ destination[offset + 1] = FLOAT_BYTES[6];
2226
+ destination[offset + 2] = FLOAT_BYTES[5];
2227
+ destination[offset + 3] = FLOAT_BYTES[4];
2228
+ destination[offset + 4] = FLOAT_BYTES[3];
2229
+ destination[offset + 5] = FLOAT_BYTES[2];
2230
+ destination[offset + 6] = FLOAT_BYTES[1];
2231
+ destination[offset + 7] = FLOAT_BYTES[0];
2232
+ return 8;
2233
+ }
2234
+ : (destination, offset, value) => {
2235
+ FLOAT[0] = value;
2236
+ destination[offset] = FLOAT_BYTES[0];
2237
+ destination[offset + 1] = FLOAT_BYTES[1];
2238
+ destination[offset + 2] = FLOAT_BYTES[2];
2239
+ destination[offset + 3] = FLOAT_BYTES[3];
2240
+ destination[offset + 4] = FLOAT_BYTES[4];
2241
+ destination[offset + 5] = FLOAT_BYTES[5];
2242
+ destination[offset + 6] = FLOAT_BYTES[6];
2243
+ destination[offset + 7] = FLOAT_BYTES[7];
2244
+ return 8;
2245
+ }
2246
+ };
2247
+
2110
2248
  const checkForHexRegExp = new RegExp('^[0-9a-fA-F]{24}$');
2111
2249
  let PROCESS_UNIQUE = null;
2112
- const kId = Symbol('id');
2113
2250
  class ObjectId extends BSONValue {
2114
2251
  get _bsontype() {
2115
2252
  return 'ObjectId';
@@ -2132,14 +2269,14 @@ class ObjectId extends BSONValue {
2132
2269
  workingId = inputId;
2133
2270
  }
2134
2271
  if (workingId == null || typeof workingId === 'number') {
2135
- this[kId] = ObjectId.generate(typeof workingId === 'number' ? workingId : undefined);
2272
+ this.buffer = ObjectId.generate(typeof workingId === 'number' ? workingId : undefined);
2136
2273
  }
2137
2274
  else if (ArrayBuffer.isView(workingId) && workingId.byteLength === 12) {
2138
- this[kId] = ByteUtils.toLocalBufferType(workingId);
2275
+ this.buffer = ByteUtils.toLocalBufferType(workingId);
2139
2276
  }
2140
2277
  else if (typeof workingId === 'string') {
2141
2278
  if (workingId.length === 24 && checkForHexRegExp.test(workingId)) {
2142
- this[kId] = ByteUtils.fromHex(workingId);
2279
+ this.buffer = ByteUtils.fromHex(workingId);
2143
2280
  }
2144
2281
  else {
2145
2282
  throw new BSONError('input must be a 24 character hex string, 12 byte Uint8Array, or an integer');
@@ -2153,10 +2290,10 @@ class ObjectId extends BSONValue {
2153
2290
  }
2154
2291
  }
2155
2292
  get id() {
2156
- return this[kId];
2293
+ return this.buffer;
2157
2294
  }
2158
2295
  set id(value) {
2159
- this[kId] = value;
2296
+ this.buffer = value;
2160
2297
  if (ObjectId.cacheHexString) {
2161
2298
  this.__id = ByteUtils.toHex(value);
2162
2299
  }
@@ -2179,8 +2316,8 @@ class ObjectId extends BSONValue {
2179
2316
  time = Math.floor(Date.now() / 1000);
2180
2317
  }
2181
2318
  const inc = ObjectId.getInc();
2182
- const buffer = ByteUtils.allocate(12);
2183
- BSONDataView.fromUint8Array(buffer).setUint32(0, time, false);
2319
+ const buffer = ByteUtils.allocateUnsafe(12);
2320
+ NumberUtils.setInt32BE(buffer, 0, time);
2184
2321
  if (PROCESS_UNIQUE === null) {
2185
2322
  PROCESS_UNIQUE = ByteUtils.randomBytes(5);
2186
2323
  }
@@ -2215,7 +2352,7 @@ class ObjectId extends BSONValue {
2215
2352
  return false;
2216
2353
  }
2217
2354
  if (ObjectId.is(otherId)) {
2218
- return this[kId][11] === otherId[kId][11] && ByteUtils.equals(this[kId], otherId[kId]);
2355
+ return (this.buffer[11] === otherId.buffer[11] && ByteUtils.equals(this.buffer, otherId.buffer));
2219
2356
  }
2220
2357
  if (typeof otherId === 'string') {
2221
2358
  return otherId.toLowerCase() === this.toHexString();
@@ -2229,16 +2366,33 @@ class ObjectId extends BSONValue {
2229
2366
  }
2230
2367
  getTimestamp() {
2231
2368
  const timestamp = new Date();
2232
- const time = BSONDataView.fromUint8Array(this.id).getUint32(0, false);
2369
+ const time = NumberUtils.getUint32BE(this.buffer, 0);
2233
2370
  timestamp.setTime(Math.floor(time) * 1000);
2234
2371
  return timestamp;
2235
2372
  }
2236
2373
  static createPk() {
2237
2374
  return new ObjectId();
2238
2375
  }
2376
+ serializeInto(uint8array, index) {
2377
+ uint8array[index] = this.buffer[0];
2378
+ uint8array[index + 1] = this.buffer[1];
2379
+ uint8array[index + 2] = this.buffer[2];
2380
+ uint8array[index + 3] = this.buffer[3];
2381
+ uint8array[index + 4] = this.buffer[4];
2382
+ uint8array[index + 5] = this.buffer[5];
2383
+ uint8array[index + 6] = this.buffer[6];
2384
+ uint8array[index + 7] = this.buffer[7];
2385
+ uint8array[index + 8] = this.buffer[8];
2386
+ uint8array[index + 9] = this.buffer[9];
2387
+ uint8array[index + 10] = this.buffer[10];
2388
+ uint8array[index + 11] = this.buffer[11];
2389
+ return 12;
2390
+ }
2239
2391
  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);
2392
+ const buffer = ByteUtils.allocate(12);
2393
+ for (let i = 11; i >= 4; i--)
2394
+ buffer[i] = 0;
2395
+ NumberUtils.setInt32BE(buffer, 0, time);
2242
2396
  return new ObjectId(buffer);
2243
2397
  }
2244
2398
  static createFromHexString(hexString) {
@@ -2610,10 +2764,7 @@ const JS_INT_MIN_LONG = Long.fromNumber(JS_INT_MIN);
2610
2764
  function internalDeserialize(buffer, options, isArray) {
2611
2765
  options = options == null ? {} : options;
2612
2766
  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);
2767
+ const size = NumberUtils.getInt32LE(buffer, index);
2617
2768
  if (size < 5) {
2618
2769
  throw new BSONError(`bson size must be >= 5, is ${size}`);
2619
2770
  }
@@ -2649,7 +2800,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2649
2800
  const validation = options.validation == null ? { utf8: true } : options.validation;
2650
2801
  let globalUTFValidation = true;
2651
2802
  let validationSetting;
2652
- const utf8KeysSet = new Set();
2803
+ let utf8KeysSet;
2653
2804
  const utf8ValidatedKeys = validation.utf8;
2654
2805
  if (typeof utf8ValidatedKeys === 'boolean') {
2655
2806
  validationSetting = utf8ValidatedKeys;
@@ -2671,6 +2822,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2671
2822
  }
2672
2823
  }
2673
2824
  if (!globalUTFValidation) {
2825
+ utf8KeysSet = new Set();
2674
2826
  for (const key of Object.keys(utf8ValidatedKeys)) {
2675
2827
  utf8KeysSet.add(key);
2676
2828
  }
@@ -2678,14 +2830,14 @@ function deserializeObject(buffer, index, options, isArray = false) {
2678
2830
  const startIndex = index;
2679
2831
  if (buffer.length < 5)
2680
2832
  throw new BSONError('corrupt bson message < 5 bytes long');
2681
- const size = buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24);
2833
+ const size = NumberUtils.getInt32LE(buffer, index);
2834
+ index += 4;
2682
2835
  if (size < 5 || size > buffer.length)
2683
2836
  throw new BSONError('corrupt bson message');
2684
2837
  const object = isArray ? [] : {};
2685
2838
  let arrayIndex = 0;
2686
2839
  const done = false;
2687
2840
  let isPossibleDBRef = isArray ? false : null;
2688
- const dataview = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
2689
2841
  while (!done) {
2690
2842
  const elementType = buffer[index++];
2691
2843
  if (elementType === 0)
@@ -2698,7 +2850,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2698
2850
  throw new BSONError('Bad BSON Document: illegal CString');
2699
2851
  const name = isArray ? arrayIndex++ : ByteUtils.toUTF8(buffer, index, i, false);
2700
2852
  let shouldValidateKey = true;
2701
- if (globalUTFValidation || utf8KeysSet.has(name)) {
2853
+ if (globalUTFValidation || utf8KeysSet?.has(name)) {
2702
2854
  shouldValidateKey = validationSetting;
2703
2855
  }
2704
2856
  else {
@@ -2710,10 +2862,8 @@ function deserializeObject(buffer, index, options, isArray = false) {
2710
2862
  let value;
2711
2863
  index = i + 1;
2712
2864
  if (elementType === BSON_DATA_STRING) {
2713
- const stringSize = buffer[index++] |
2714
- (buffer[index++] << 8) |
2715
- (buffer[index++] << 16) |
2716
- (buffer[index++] << 24);
2865
+ const stringSize = NumberUtils.getInt32LE(buffer, index);
2866
+ index += 4;
2717
2867
  if (stringSize <= 0 ||
2718
2868
  stringSize > buffer.length - index ||
2719
2869
  buffer[index + stringSize - 1] !== 0) {
@@ -2723,38 +2873,30 @@ function deserializeObject(buffer, index, options, isArray = false) {
2723
2873
  index = index + stringSize;
2724
2874
  }
2725
2875
  else if (elementType === BSON_DATA_OID) {
2726
- const oid = ByteUtils.allocate(12);
2727
- oid.set(buffer.subarray(index, index + 12));
2876
+ const oid = ByteUtils.allocateUnsafe(12);
2877
+ for (let i = 0; i < 12; i++)
2878
+ oid[i] = buffer[index + i];
2728
2879
  value = new ObjectId(oid);
2729
2880
  index = index + 12;
2730
2881
  }
2731
2882
  else if (elementType === BSON_DATA_INT && promoteValues === false) {
2732
- value = new Int32(buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24));
2883
+ value = new Int32(NumberUtils.getInt32LE(buffer, index));
2884
+ index += 4;
2733
2885
  }
2734
2886
  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;
2887
+ value = NumberUtils.getInt32LE(buffer, index);
2888
+ index += 4;
2744
2889
  }
2745
2890
  else if (elementType === BSON_DATA_NUMBER) {
2746
- value = dataview.getFloat64(index, true);
2747
- index = index + 8;
2891
+ value = NumberUtils.getFloat64LE(buffer, index);
2892
+ index += 8;
2893
+ if (promoteValues === false)
2894
+ value = new Double(value);
2748
2895
  }
2749
2896
  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);
2897
+ const lowBits = NumberUtils.getInt32LE(buffer, index);
2898
+ const highBits = NumberUtils.getInt32LE(buffer, index + 4);
2899
+ index += 8;
2758
2900
  value = new Date(new Long(lowBits, highBits).toNumber());
2759
2901
  }
2760
2902
  else if (elementType === BSON_DATA_BOOLEAN) {
@@ -2764,10 +2906,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2764
2906
  }
2765
2907
  else if (elementType === BSON_DATA_OBJECT) {
2766
2908
  const _index = index;
2767
- const objectSize = buffer[index] |
2768
- (buffer[index + 1] << 8) |
2769
- (buffer[index + 2] << 16) |
2770
- (buffer[index + 3] << 24);
2909
+ const objectSize = NumberUtils.getInt32LE(buffer, index);
2771
2910
  if (objectSize <= 0 || objectSize > buffer.length - index)
2772
2911
  throw new BSONError('bad embedded document length in bson');
2773
2912
  if (raw) {
@@ -2784,10 +2923,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2784
2923
  }
2785
2924
  else if (elementType === BSON_DATA_ARRAY) {
2786
2925
  const _index = index;
2787
- const objectSize = buffer[index] |
2788
- (buffer[index + 1] << 8) |
2789
- (buffer[index + 2] << 16) |
2790
- (buffer[index + 3] << 24);
2926
+ const objectSize = NumberUtils.getInt32LE(buffer, index);
2791
2927
  let arrayOptions = options;
2792
2928
  const stopIndex = index + objectSize;
2793
2929
  if (fieldsAsRaw && fieldsAsRaw[name]) {
@@ -2810,40 +2946,36 @@ function deserializeObject(buffer, index, options, isArray = false) {
2810
2946
  value = null;
2811
2947
  }
2812
2948
  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
2949
  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;
2950
+ value = NumberUtils.getBigInt64LE(buffer, index);
2951
+ index += 8;
2831
2952
  }
2832
2953
  else {
2833
- value = long;
2954
+ const lowBits = NumberUtils.getInt32LE(buffer, index);
2955
+ const highBits = NumberUtils.getInt32LE(buffer, index + 4);
2956
+ index += 8;
2957
+ const long = new Long(lowBits, highBits);
2958
+ if (promoteLongs && promoteValues === true) {
2959
+ value =
2960
+ long.lessThanOrEqual(JS_INT_MAX_LONG) && long.greaterThanOrEqual(JS_INT_MIN_LONG)
2961
+ ? long.toNumber()
2962
+ : long;
2963
+ }
2964
+ else {
2965
+ value = long;
2966
+ }
2834
2967
  }
2835
2968
  }
2836
2969
  else if (elementType === BSON_DATA_DECIMAL128) {
2837
- const bytes = ByteUtils.allocate(16);
2838
- bytes.set(buffer.subarray(index, index + 16), 0);
2970
+ const bytes = ByteUtils.allocateUnsafe(16);
2971
+ for (let i = 0; i < 16; i++)
2972
+ bytes[i] = buffer[index + i];
2839
2973
  index = index + 16;
2840
2974
  value = new Decimal128(bytes);
2841
2975
  }
2842
2976
  else if (elementType === BSON_DATA_BINARY) {
2843
- let binarySize = buffer[index++] |
2844
- (buffer[index++] << 8) |
2845
- (buffer[index++] << 16) |
2846
- (buffer[index++] << 24);
2977
+ let binarySize = NumberUtils.getInt32LE(buffer, index);
2978
+ index += 4;
2847
2979
  const totalBinarySize = binarySize;
2848
2980
  const subType = buffer[index++];
2849
2981
  if (binarySize < 0)
@@ -2852,11 +2984,8 @@ function deserializeObject(buffer, index, options, isArray = false) {
2852
2984
  throw new BSONError('Binary type size larger than document size');
2853
2985
  if (buffer['slice'] != null) {
2854
2986
  if (subType === Binary.SUBTYPE_BYTE_ARRAY) {
2855
- binarySize =
2856
- buffer[index++] |
2857
- (buffer[index++] << 8) |
2858
- (buffer[index++] << 16) |
2859
- (buffer[index++] << 24);
2987
+ binarySize = NumberUtils.getInt32LE(buffer, index);
2988
+ index += 4;
2860
2989
  if (binarySize < 0)
2861
2990
  throw new BSONError('Negative binary type element size found for subtype 0x02');
2862
2991
  if (binarySize > totalBinarySize - 4)
@@ -2875,13 +3004,9 @@ function deserializeObject(buffer, index, options, isArray = false) {
2875
3004
  }
2876
3005
  }
2877
3006
  else {
2878
- const _buffer = ByteUtils.allocate(binarySize);
2879
3007
  if (subType === Binary.SUBTYPE_BYTE_ARRAY) {
2880
- binarySize =
2881
- buffer[index++] |
2882
- (buffer[index++] << 8) |
2883
- (buffer[index++] << 16) |
2884
- (buffer[index++] << 24);
3008
+ binarySize = NumberUtils.getInt32LE(buffer, index);
3009
+ index += 4;
2885
3010
  if (binarySize < 0)
2886
3011
  throw new BSONError('Negative binary type element size found for subtype 0x02');
2887
3012
  if (binarySize > totalBinarySize - 4)
@@ -2889,11 +3014,11 @@ function deserializeObject(buffer, index, options, isArray = false) {
2889
3014
  if (binarySize < totalBinarySize - 4)
2890
3015
  throw new BSONError('Binary type with subtype 0x02 contains too short binary size');
2891
3016
  }
2892
- for (i = 0; i < binarySize; i++) {
2893
- _buffer[i] = buffer[index + i];
2894
- }
2895
3017
  if (promoteBuffers && promoteValues) {
2896
- value = _buffer;
3018
+ value = ByteUtils.allocateUnsafe(binarySize);
3019
+ for (i = 0; i < binarySize; i++) {
3020
+ value[i] = buffer[index + i];
3021
+ }
2897
3022
  }
2898
3023
  else {
2899
3024
  value = new Binary(buffer.slice(index, index + binarySize), subType);
@@ -2957,10 +3082,8 @@ function deserializeObject(buffer, index, options, isArray = false) {
2957
3082
  value = new BSONRegExp(source, regExpOptions);
2958
3083
  }
2959
3084
  else if (elementType === BSON_DATA_SYMBOL) {
2960
- const stringSize = buffer[index++] |
2961
- (buffer[index++] << 8) |
2962
- (buffer[index++] << 16) |
2963
- (buffer[index++] << 24);
3085
+ const stringSize = NumberUtils.getInt32LE(buffer, index);
3086
+ index += 4;
2964
3087
  if (stringSize <= 0 ||
2965
3088
  stringSize > buffer.length - index ||
2966
3089
  buffer[index + stringSize - 1] !== 0) {
@@ -2971,15 +3094,11 @@ function deserializeObject(buffer, index, options, isArray = false) {
2971
3094
  index = index + stringSize;
2972
3095
  }
2973
3096
  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 });
3097
+ value = new Timestamp({
3098
+ i: NumberUtils.getUint32LE(buffer, index),
3099
+ t: NumberUtils.getUint32LE(buffer, index + 4)
3100
+ });
3101
+ index += 8;
2983
3102
  }
2984
3103
  else if (elementType === BSON_DATA_MIN_KEY) {
2985
3104
  value = new MinKey();
@@ -2988,10 +3107,8 @@ function deserializeObject(buffer, index, options, isArray = false) {
2988
3107
  value = new MaxKey();
2989
3108
  }
2990
3109
  else if (elementType === BSON_DATA_CODE) {
2991
- const stringSize = buffer[index++] |
2992
- (buffer[index++] << 8) |
2993
- (buffer[index++] << 16) |
2994
- (buffer[index++] << 24);
3110
+ const stringSize = NumberUtils.getInt32LE(buffer, index);
3111
+ index += 4;
2995
3112
  if (stringSize <= 0 ||
2996
3113
  stringSize > buffer.length - index ||
2997
3114
  buffer[index + stringSize - 1] !== 0) {
@@ -3002,17 +3119,13 @@ function deserializeObject(buffer, index, options, isArray = false) {
3002
3119
  index = index + stringSize;
3003
3120
  }
3004
3121
  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);
3122
+ const totalSize = NumberUtils.getInt32LE(buffer, index);
3123
+ index += 4;
3009
3124
  if (totalSize < 4 + 4 + 4 + 1) {
3010
3125
  throw new BSONError('code_w_scope total size shorter minimum expected length');
3011
3126
  }
3012
- const stringSize = buffer[index++] |
3013
- (buffer[index++] << 8) |
3014
- (buffer[index++] << 16) |
3015
- (buffer[index++] << 24);
3127
+ const stringSize = NumberUtils.getInt32LE(buffer, index);
3128
+ index += 4;
3016
3129
  if (stringSize <= 0 ||
3017
3130
  stringSize > buffer.length - index ||
3018
3131
  buffer[index + stringSize - 1] !== 0) {
@@ -3021,10 +3134,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
3021
3134
  const functionString = ByteUtils.toUTF8(buffer, index, index + stringSize - 1, shouldValidateKey);
3022
3135
  index = index + stringSize;
3023
3136
  const _index = index;
3024
- const objectSize = buffer[index] |
3025
- (buffer[index + 1] << 8) |
3026
- (buffer[index + 2] << 16) |
3027
- (buffer[index + 3] << 24);
3137
+ const objectSize = NumberUtils.getInt32LE(buffer, index);
3028
3138
  const scopeObject = deserializeObject(buffer, _index, options, false);
3029
3139
  index = index + objectSize;
3030
3140
  if (totalSize < 4 + 4 + objectSize + stringSize) {
@@ -3036,10 +3146,8 @@ function deserializeObject(buffer, index, options, isArray = false) {
3036
3146
  value = new Code(functionString, scopeObject);
3037
3147
  }
3038
3148
  else if (elementType === BSON_DATA_DBPOINTER) {
3039
- const stringSize = buffer[index++] |
3040
- (buffer[index++] << 8) |
3041
- (buffer[index++] << 16) |
3042
- (buffer[index++] << 24);
3149
+ const stringSize = NumberUtils.getInt32LE(buffer, index);
3150
+ index += 4;
3043
3151
  if (stringSize <= 0 ||
3044
3152
  stringSize > buffer.length - index ||
3045
3153
  buffer[index + stringSize - 1] !== 0)
@@ -3051,8 +3159,9 @@ function deserializeObject(buffer, index, options, isArray = false) {
3051
3159
  }
3052
3160
  const namespace = ByteUtils.toUTF8(buffer, index, index + stringSize - 1, false);
3053
3161
  index = index + stringSize;
3054
- const oidBuffer = ByteUtils.allocate(12);
3055
- oidBuffer.set(buffer.subarray(index, index + 12), 0);
3162
+ const oidBuffer = ByteUtils.allocateUnsafe(12);
3163
+ for (let i = 0; i < 12; i++)
3164
+ oidBuffer[i] = buffer[index + i];
3056
3165
  const oid = new ObjectId(oidBuffer);
3057
3166
  index = index + 12;
3058
3167
  value = new DBRef(namespace, oid);
@@ -3097,17 +3206,11 @@ function serializeString(buffer, key, value, index) {
3097
3206
  index = index + numberOfWrittenBytes + 1;
3098
3207
  buffer[index - 1] = 0;
3099
3208
  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;
3209
+ NumberUtils.setInt32LE(buffer, index, size + 1);
3104
3210
  index = index + 4 + size;
3105
3211
  buffer[index++] = 0;
3106
3212
  return index;
3107
3213
  }
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
3214
  function serializeNumber(buffer, key, value, index) {
3112
3215
  const isNegativeZero = Object.is(value, -0);
3113
3216
  const type = !isNegativeZero &&
@@ -3116,19 +3219,16 @@ function serializeNumber(buffer, key, value, index) {
3116
3219
  value >= BSON_INT32_MIN
3117
3220
  ? BSON_DATA_INT
3118
3221
  : 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
3222
  buffer[index++] = type;
3127
3223
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3128
3224
  index = index + numberOfWrittenBytes;
3129
3225
  buffer[index++] = 0x00;
3130
- buffer.set(bytes, index);
3131
- index += bytes.byteLength;
3226
+ if (type === BSON_DATA_INT) {
3227
+ index += NumberUtils.setInt32LE(buffer, index, value);
3228
+ }
3229
+ else {
3230
+ index += NumberUtils.setFloat64LE(buffer, index, value);
3231
+ }
3132
3232
  return index;
3133
3233
  }
3134
3234
  function serializeBigInt(buffer, key, value, index) {
@@ -3136,9 +3236,7 @@ function serializeBigInt(buffer, key, value, index) {
3136
3236
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3137
3237
  index += numberOfWrittenBytes;
3138
3238
  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;
3239
+ index += NumberUtils.setBigInt64LE(buffer, index, value);
3142
3240
  return index;
3143
3241
  }
3144
3242
  function serializeNull(buffer, key, _, index) {
@@ -3164,14 +3262,8 @@ function serializeDate(buffer, key, value, index) {
3164
3262
  const dateInMilis = Long.fromNumber(value.getTime());
3165
3263
  const lowBits = dateInMilis.getLowBits();
3166
3264
  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;
3265
+ index += NumberUtils.setInt32LE(buffer, index, lowBits);
3266
+ index += NumberUtils.setInt32LE(buffer, index, highBits);
3175
3267
  return index;
3176
3268
  }
3177
3269
  function serializeRegExp(buffer, key, value, index) {
@@ -3228,15 +3320,7 @@ function serializeObjectId(buffer, key, value, index) {
3228
3320
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3229
3321
  index = index + numberOfWrittenBytes;
3230
3322
  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
- }
3323
+ index += value.serializeInto(buffer, index);
3240
3324
  return index;
3241
3325
  }
3242
3326
  function serializeBuffer(buffer, key, value, index) {
@@ -3245,12 +3329,15 @@ function serializeBuffer(buffer, key, value, index) {
3245
3329
  index = index + numberOfWrittenBytes;
3246
3330
  buffer[index++] = 0;
3247
3331
  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;
3332
+ index += NumberUtils.setInt32LE(buffer, index, size);
3252
3333
  buffer[index++] = BSON_BINARY_SUBTYPE_DEFAULT;
3253
- buffer.set(value, index);
3334
+ if (size <= 16) {
3335
+ for (let i = 0; i < size; i++)
3336
+ buffer[index + i] = value[i];
3337
+ }
3338
+ else {
3339
+ buffer.set(value, index);
3340
+ }
3254
3341
  index = index + size;
3255
3342
  return index;
3256
3343
  }
@@ -3272,7 +3359,8 @@ function serializeDecimal128(buffer, key, value, index) {
3272
3359
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3273
3360
  index = index + numberOfWrittenBytes;
3274
3361
  buffer[index++] = 0;
3275
- buffer.set(value.bytes.subarray(0, 16), index);
3362
+ for (let i = 0; i < 16; i++)
3363
+ buffer[index + i] = value.bytes[i];
3276
3364
  return index + 16;
3277
3365
  }
3278
3366
  function serializeLong(buffer, key, value, index) {
@@ -3283,14 +3371,8 @@ function serializeLong(buffer, key, value, index) {
3283
3371
  buffer[index++] = 0;
3284
3372
  const lowBits = value.getLowBits();
3285
3373
  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;
3374
+ index += NumberUtils.setInt32LE(buffer, index, lowBits);
3375
+ index += NumberUtils.setInt32LE(buffer, index, highBits);
3294
3376
  return index;
3295
3377
  }
3296
3378
  function serializeInt32(buffer, key, value, index) {
@@ -3299,10 +3381,7 @@ function serializeInt32(buffer, key, value, index) {
3299
3381
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3300
3382
  index = index + numberOfWrittenBytes;
3301
3383
  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;
3384
+ index += NumberUtils.setInt32LE(buffer, index, value);
3306
3385
  return index;
3307
3386
  }
3308
3387
  function serializeDouble(buffer, key, value, index) {
@@ -3310,9 +3389,7 @@ function serializeDouble(buffer, key, value, index) {
3310
3389
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3311
3390
  index = index + numberOfWrittenBytes;
3312
3391
  buffer[index++] = 0;
3313
- NUMBER_SPACE.setFloat64(0, value.value, true);
3314
- buffer.set(EIGHT_BYTE_VIEW_ON_NUMBER, index);
3315
- index = index + 8;
3392
+ index += NumberUtils.setFloat64LE(buffer, index, value.value);
3316
3393
  return index;
3317
3394
  }
3318
3395
  function serializeFunction(buffer, key, value, index) {
@@ -3322,10 +3399,7 @@ function serializeFunction(buffer, key, value, index) {
3322
3399
  buffer[index++] = 0;
3323
3400
  const functionString = value.toString();
3324
3401
  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;
3402
+ NumberUtils.setInt32LE(buffer, index, size);
3329
3403
  index = index + 4 + size - 1;
3330
3404
  buffer[index++] = 0;
3331
3405
  return index;
@@ -3340,19 +3414,13 @@ function serializeCode(buffer, key, value, index, checkKeys = false, depth = 0,
3340
3414
  const functionString = value.code;
3341
3415
  index = index + 4;
3342
3416
  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;
3417
+ NumberUtils.setInt32LE(buffer, index, codeSize);
3347
3418
  buffer[index + 4 + codeSize - 1] = 0;
3348
3419
  index = index + codeSize + 4;
3349
3420
  const endIndex = serializeInto(buffer, value.scope, checkKeys, index, depth + 1, serializeFunctions, ignoreUndefined, path);
3350
3421
  index = endIndex - 1;
3351
3422
  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;
3423
+ startIndex += NumberUtils.setInt32LE(buffer, startIndex, totalSize);
3356
3424
  buffer[index++] = 0;
3357
3425
  }
3358
3426
  else {
@@ -3362,10 +3430,7 @@ function serializeCode(buffer, key, value, index, checkKeys = false, depth = 0,
3362
3430
  buffer[index++] = 0;
3363
3431
  const functionString = value.code.toString();
3364
3432
  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;
3433
+ NumberUtils.setInt32LE(buffer, index, size);
3369
3434
  index = index + 4 + size - 1;
3370
3435
  buffer[index++] = 0;
3371
3436
  }
@@ -3380,19 +3445,19 @@ function serializeBinary(buffer, key, value, index) {
3380
3445
  let size = value.position;
3381
3446
  if (value.sub_type === Binary.SUBTYPE_BYTE_ARRAY)
3382
3447
  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;
3448
+ index += NumberUtils.setInt32LE(buffer, index, size);
3387
3449
  buffer[index++] = value.sub_type;
3388
3450
  if (value.sub_type === Binary.SUBTYPE_BYTE_ARRAY) {
3389
3451
  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;
3452
+ index += NumberUtils.setInt32LE(buffer, index, size);
3453
+ }
3454
+ if (size <= 16) {
3455
+ for (let i = 0; i < size; i++)
3456
+ buffer[index + i] = data[i];
3457
+ }
3458
+ else {
3459
+ buffer.set(data, index);
3394
3460
  }
3395
- buffer.set(data, index);
3396
3461
  index = index + value.position;
3397
3462
  return index;
3398
3463
  }
@@ -3402,12 +3467,9 @@ function serializeSymbol(buffer, key, value, index) {
3402
3467
  index = index + numberOfWrittenBytes;
3403
3468
  buffer[index++] = 0;
3404
3469
  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;
3470
+ NumberUtils.setInt32LE(buffer, index, size);
3409
3471
  index = index + 4 + size - 1;
3410
- buffer[index++] = 0x00;
3472
+ buffer[index++] = 0;
3411
3473
  return index;
3412
3474
  }
3413
3475
  function serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path) {
@@ -3426,10 +3488,7 @@ function serializeDBRef(buffer, key, value, index, depth, serializeFunctions, pa
3426
3488
  output = Object.assign(output, value.fields);
3427
3489
  const endIndex = serializeInto(buffer, output, false, index, depth + 1, serializeFunctions, true, path);
3428
3490
  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;
3491
+ startIndex += NumberUtils.setInt32LE(buffer, index, size);
3433
3492
  return endIndex;
3434
3493
  }
3435
3494
  function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializeFunctions, ignoreUndefined, path) {
@@ -3565,7 +3624,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3565
3624
  if ('$' === key[0]) {
3566
3625
  throw new BSONError('key ' + key + " must not start with '$'");
3567
3626
  }
3568
- else if (~key.indexOf('.')) {
3627
+ else if (key.includes('.')) {
3569
3628
  throw new BSONError('key ' + key + " must not contain '.'");
3570
3629
  }
3571
3630
  }
@@ -3663,7 +3722,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3663
3722
  if ('$' === key[0]) {
3664
3723
  throw new BSONError('key ' + key + " must not start with '$'");
3665
3724
  }
3666
- else if (~key.indexOf('.')) {
3725
+ else if (key.includes('.')) {
3667
3726
  throw new BSONError('key ' + key + " must not contain '.'");
3668
3727
  }
3669
3728
  }
@@ -3747,10 +3806,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3747
3806
  path.delete(object);
3748
3807
  buffer[index++] = 0x00;
3749
3808
  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;
3809
+ startingIndex += NumberUtils.setInt32LE(buffer, startingIndex, size);
3754
3810
  return index;
3755
3811
  }
3756
3812
 
@@ -4080,7 +4136,7 @@ function serialize(object, options = {}) {
4080
4136
  buffer = ByteUtils.allocate(minInternalBufferSize);
4081
4137
  }
4082
4138
  const serializationIndex = serializeInto(buffer, object, checkKeys, 0, 0, serializeFunctions, ignoreUndefined, null);
4083
- const finishedBuffer = ByteUtils.allocate(serializationIndex);
4139
+ const finishedBuffer = ByteUtils.allocateUnsafe(serializationIndex);
4084
4140
  finishedBuffer.set(buffer.subarray(0, serializationIndex), 0);
4085
4141
  return finishedBuffer;
4086
4142
  }
@@ -4107,10 +4163,7 @@ function deserializeStream(data, startIndex, numberOfDocuments, documents, docSt
4107
4163
  const bufferData = ByteUtils.toLocalBufferType(data);
4108
4164
  let index = startIndex;
4109
4165
  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);
4166
+ const size = NumberUtils.getInt32LE(bufferData, index);
4114
4167
  internalOptions.index = index;
4115
4168
  documents[docStartIndex + i] = internalDeserialize(bufferData, internalOptions);
4116
4169
  index = index + size;