bson 6.3.0 → 6.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -165,7 +165,7 @@ function validateUtf8(bytes, start, end) {
165
165
  return !continuation;
166
166
  }
167
167
 
168
- function tryLatin(uint8array, start, end) {
168
+ function tryReadBasicLatin(uint8array, start, end) {
169
169
  if (uint8array.length === 0) {
170
170
  return '';
171
171
  }
@@ -200,6 +200,21 @@ function tryLatin(uint8array, start, end) {
200
200
  }
201
201
  return String.fromCharCode(...latinBytes);
202
202
  }
203
+ function tryWriteBasicLatin(destination, source, offset) {
204
+ if (source.length === 0)
205
+ return 0;
206
+ if (source.length > 25)
207
+ return null;
208
+ if (destination.length - offset < source.length)
209
+ return null;
210
+ for (let charOffset = 0, destinationOffset = offset; charOffset < source.length; charOffset++, destinationOffset++) {
211
+ const char = source.charCodeAt(charOffset);
212
+ if (char > 127)
213
+ return null;
214
+ destination[destinationOffset] = char;
215
+ }
216
+ return source.length;
217
+ }
203
218
 
204
219
  function nodejsMathRandomBytes(byteLength) {
205
220
  return nodeJsByteUtils.fromNumberArray(Array.from({ length: byteLength }, () => Math.floor(Math.random() * 256)));
@@ -232,6 +247,9 @@ const nodeJsByteUtils = {
232
247
  allocate(size) {
233
248
  return Buffer.alloc(size);
234
249
  },
250
+ allocateUnsafe(size) {
251
+ return Buffer.allocUnsafe(size);
252
+ },
235
253
  equals(a, b) {
236
254
  return nodeJsByteUtils.toLocalBufferType(a).equals(b);
237
255
  },
@@ -256,11 +274,8 @@ const nodeJsByteUtils = {
256
274
  toHex(buffer) {
257
275
  return nodeJsByteUtils.toLocalBufferType(buffer).toString('hex');
258
276
  },
259
- fromUTF8(text) {
260
- return Buffer.from(text, 'utf8');
261
- },
262
277
  toUTF8(buffer, start, end, fatal) {
263
- const basicLatin = end - start <= 20 ? tryLatin(buffer, start, end) : null;
278
+ const basicLatin = end - start <= 20 ? tryReadBasicLatin(buffer, start, end) : null;
264
279
  if (basicLatin != null) {
265
280
  return basicLatin;
266
281
  }
@@ -281,6 +296,10 @@ const nodeJsByteUtils = {
281
296
  return Buffer.byteLength(input, 'utf8');
282
297
  },
283
298
  encodeUTF8Into(buffer, source, byteOffset) {
299
+ const latinBytesWritten = tryWriteBasicLatin(buffer, source, byteOffset);
300
+ if (latinBytesWritten != null) {
301
+ return latinBytesWritten;
302
+ }
284
303
  return nodeJsByteUtils.toLocalBufferType(buffer).write(source, byteOffset, undefined, 'utf8');
285
304
  },
286
305
  randomBytes: nodejsRandomBytes
@@ -336,6 +355,9 @@ const webByteUtils = {
336
355
  }
337
356
  return new Uint8Array(size);
338
357
  },
358
+ allocateUnsafe(size) {
359
+ return webByteUtils.allocate(size);
360
+ },
339
361
  equals(a, b) {
340
362
  if (a.byteLength !== b.byteLength) {
341
363
  return false;
@@ -382,11 +404,8 @@ const webByteUtils = {
382
404
  toHex(uint8array) {
383
405
  return Array.from(uint8array, byte => byte.toString(16).padStart(2, '0')).join('');
384
406
  },
385
- fromUTF8(text) {
386
- return new TextEncoder().encode(text);
387
- },
388
407
  toUTF8(uint8array, start, end, fatal) {
389
- const basicLatin = end - start <= 20 ? tryLatin(uint8array, start, end) : null;
408
+ const basicLatin = end - start <= 20 ? tryReadBasicLatin(uint8array, start, end) : null;
390
409
  if (basicLatin != null) {
391
410
  return basicLatin;
392
411
  }
@@ -401,11 +420,11 @@ const webByteUtils = {
401
420
  return new TextDecoder('utf8', { fatal }).decode(uint8array.slice(start, end));
402
421
  },
403
422
  utf8ByteLength(input) {
404
- return webByteUtils.fromUTF8(input).byteLength;
423
+ return new TextEncoder().encode(input).byteLength;
405
424
  },
406
- encodeUTF8Into(buffer, source, byteOffset) {
407
- const bytes = webByteUtils.fromUTF8(source);
408
- buffer.set(bytes, byteOffset);
425
+ encodeUTF8Into(uint8array, source, byteOffset) {
426
+ const bytes = new TextEncoder().encode(source);
427
+ uint8array.set(bytes, byteOffset);
409
428
  return bytes.byteLength;
410
429
  },
411
430
  randomBytes: webRandomBytes
@@ -413,11 +432,6 @@ const webByteUtils = {
413
432
 
414
433
  const hasGlobalBuffer = typeof Buffer === 'function' && Buffer.prototype?._isBuffer !== true;
415
434
  const ByteUtils = hasGlobalBuffer ? nodeJsByteUtils : webByteUtils;
416
- class BSONDataView extends DataView {
417
- static fromUint8Array(input) {
418
- return new DataView(input.buffer, input.byteOffset, input.byteLength);
419
- }
420
- }
421
435
 
422
436
  class BSONValue {
423
437
  get [Symbol.for('@@mdb.bson.version')]() {
@@ -1837,7 +1851,7 @@ class Decimal128 extends BSONValue {
1837
1851
  if (isNegative) {
1838
1852
  dec.high = dec.high.or(Long.fromString('9223372036854775808'));
1839
1853
  }
1840
- const buffer = ByteUtils.allocate(16);
1854
+ const buffer = ByteUtils.allocateUnsafe(16);
1841
1855
  index = 0;
1842
1856
  buffer[index++] = dec.low.low & 0xff;
1843
1857
  buffer[index++] = (dec.low.low >> 8) & 0xff;
@@ -2110,9 +2124,99 @@ class MinKey extends BSONValue {
2110
2124
  }
2111
2125
  }
2112
2126
 
2127
+ const FLOAT = new Float64Array(1);
2128
+ const FLOAT_BYTES = new Uint8Array(FLOAT.buffer, 0, 8);
2129
+ const NumberUtils = {
2130
+ getInt32LE(source, offset) {
2131
+ return (source[offset] |
2132
+ (source[offset + 1] << 8) |
2133
+ (source[offset + 2] << 16) |
2134
+ (source[offset + 3] << 24));
2135
+ },
2136
+ getUint32LE(source, offset) {
2137
+ return (source[offset] +
2138
+ source[offset + 1] * 256 +
2139
+ source[offset + 2] * 65536 +
2140
+ source[offset + 3] * 16777216);
2141
+ },
2142
+ getUint32BE(source, offset) {
2143
+ return (source[offset + 3] +
2144
+ source[offset + 2] * 256 +
2145
+ source[offset + 1] * 65536 +
2146
+ source[offset] * 16777216);
2147
+ },
2148
+ getBigInt64LE(source, offset) {
2149
+ const lo = NumberUtils.getUint32LE(source, offset);
2150
+ const hi = NumberUtils.getUint32LE(source, offset + 4);
2151
+ return (BigInt(hi) << BigInt(32)) + BigInt(lo);
2152
+ },
2153
+ getFloat64LE(source, offset) {
2154
+ FLOAT_BYTES[0] = source[offset];
2155
+ FLOAT_BYTES[1] = source[offset + 1];
2156
+ FLOAT_BYTES[2] = source[offset + 2];
2157
+ FLOAT_BYTES[3] = source[offset + 3];
2158
+ FLOAT_BYTES[4] = source[offset + 4];
2159
+ FLOAT_BYTES[5] = source[offset + 5];
2160
+ FLOAT_BYTES[6] = source[offset + 6];
2161
+ FLOAT_BYTES[7] = source[offset + 7];
2162
+ return FLOAT[0];
2163
+ },
2164
+ setInt32BE(destination, offset, value) {
2165
+ destination[offset + 3] = value;
2166
+ value >>>= 8;
2167
+ destination[offset + 2] = value;
2168
+ value >>>= 8;
2169
+ destination[offset + 1] = value;
2170
+ value >>>= 8;
2171
+ destination[offset] = value;
2172
+ return 4;
2173
+ },
2174
+ setInt32LE(destination, offset, value) {
2175
+ destination[offset] = value;
2176
+ value >>>= 8;
2177
+ destination[offset + 1] = value;
2178
+ value >>>= 8;
2179
+ destination[offset + 2] = value;
2180
+ value >>>= 8;
2181
+ destination[offset + 3] = value;
2182
+ return 4;
2183
+ },
2184
+ setBigInt64LE(destination, offset, value) {
2185
+ const mask32bits = BigInt(4294967295);
2186
+ let lo = Number(value & mask32bits);
2187
+ destination[offset] = lo;
2188
+ lo >>= 8;
2189
+ destination[offset + 1] = lo;
2190
+ lo >>= 8;
2191
+ destination[offset + 2] = lo;
2192
+ lo >>= 8;
2193
+ destination[offset + 3] = lo;
2194
+ let hi = Number((value >> BigInt(32)) & mask32bits);
2195
+ destination[offset + 4] = hi;
2196
+ hi >>= 8;
2197
+ destination[offset + 5] = hi;
2198
+ hi >>= 8;
2199
+ destination[offset + 6] = hi;
2200
+ hi >>= 8;
2201
+ destination[offset + 7] = hi;
2202
+ return 8;
2203
+ },
2204
+ setFloat64LE(destination, offset, value) {
2205
+ FLOAT[0] = value;
2206
+ destination[offset] = FLOAT_BYTES[0];
2207
+ destination[offset + 1] = FLOAT_BYTES[1];
2208
+ destination[offset + 2] = FLOAT_BYTES[2];
2209
+ destination[offset + 3] = FLOAT_BYTES[3];
2210
+ destination[offset + 4] = FLOAT_BYTES[4];
2211
+ destination[offset + 5] = FLOAT_BYTES[5];
2212
+ destination[offset + 6] = FLOAT_BYTES[6];
2213
+ destination[offset + 7] = FLOAT_BYTES[7];
2214
+ return 8;
2215
+ }
2216
+ };
2217
+
2113
2218
  const checkForHexRegExp = new RegExp('^[0-9a-fA-F]{24}$');
2114
2219
  let PROCESS_UNIQUE = null;
2115
- const kId = Symbol('id');
2116
2220
  class ObjectId extends BSONValue {
2117
2221
  get _bsontype() {
2118
2222
  return 'ObjectId';
@@ -2135,14 +2239,14 @@ class ObjectId extends BSONValue {
2135
2239
  workingId = inputId;
2136
2240
  }
2137
2241
  if (workingId == null || typeof workingId === 'number') {
2138
- this[kId] = ObjectId.generate(typeof workingId === 'number' ? workingId : undefined);
2242
+ this.buffer = ObjectId.generate(typeof workingId === 'number' ? workingId : undefined);
2139
2243
  }
2140
2244
  else if (ArrayBuffer.isView(workingId) && workingId.byteLength === 12) {
2141
- this[kId] = ByteUtils.toLocalBufferType(workingId);
2245
+ this.buffer = ByteUtils.toLocalBufferType(workingId);
2142
2246
  }
2143
2247
  else if (typeof workingId === 'string') {
2144
2248
  if (workingId.length === 24 && checkForHexRegExp.test(workingId)) {
2145
- this[kId] = ByteUtils.fromHex(workingId);
2249
+ this.buffer = ByteUtils.fromHex(workingId);
2146
2250
  }
2147
2251
  else {
2148
2252
  throw new BSONError('input must be a 24 character hex string, 12 byte Uint8Array, or an integer');
@@ -2156,10 +2260,10 @@ class ObjectId extends BSONValue {
2156
2260
  }
2157
2261
  }
2158
2262
  get id() {
2159
- return this[kId];
2263
+ return this.buffer;
2160
2264
  }
2161
2265
  set id(value) {
2162
- this[kId] = value;
2266
+ this.buffer = value;
2163
2267
  if (ObjectId.cacheHexString) {
2164
2268
  this.__id = ByteUtils.toHex(value);
2165
2269
  }
@@ -2182,8 +2286,8 @@ class ObjectId extends BSONValue {
2182
2286
  time = Math.floor(Date.now() / 1000);
2183
2287
  }
2184
2288
  const inc = ObjectId.getInc();
2185
- const buffer = ByteUtils.allocate(12);
2186
- BSONDataView.fromUint8Array(buffer).setUint32(0, time, false);
2289
+ const buffer = ByteUtils.allocateUnsafe(12);
2290
+ NumberUtils.setInt32BE(buffer, 0, time);
2187
2291
  if (PROCESS_UNIQUE === null) {
2188
2292
  PROCESS_UNIQUE = ByteUtils.randomBytes(5);
2189
2293
  }
@@ -2218,7 +2322,7 @@ class ObjectId extends BSONValue {
2218
2322
  return false;
2219
2323
  }
2220
2324
  if (ObjectId.is(otherId)) {
2221
- return this[kId][11] === otherId[kId][11] && ByteUtils.equals(this[kId], otherId[kId]);
2325
+ return (this.buffer[11] === otherId.buffer[11] && ByteUtils.equals(this.buffer, otherId.buffer));
2222
2326
  }
2223
2327
  if (typeof otherId === 'string') {
2224
2328
  return otherId.toLowerCase() === this.toHexString();
@@ -2232,16 +2336,33 @@ class ObjectId extends BSONValue {
2232
2336
  }
2233
2337
  getTimestamp() {
2234
2338
  const timestamp = new Date();
2235
- const time = BSONDataView.fromUint8Array(this.id).getUint32(0, false);
2339
+ const time = NumberUtils.getUint32BE(this.buffer, 0);
2236
2340
  timestamp.setTime(Math.floor(time) * 1000);
2237
2341
  return timestamp;
2238
2342
  }
2239
2343
  static createPk() {
2240
2344
  return new ObjectId();
2241
2345
  }
2346
+ serializeInto(uint8array, index) {
2347
+ uint8array[index] = this.buffer[0];
2348
+ uint8array[index + 1] = this.buffer[1];
2349
+ uint8array[index + 2] = this.buffer[2];
2350
+ uint8array[index + 3] = this.buffer[3];
2351
+ uint8array[index + 4] = this.buffer[4];
2352
+ uint8array[index + 5] = this.buffer[5];
2353
+ uint8array[index + 6] = this.buffer[6];
2354
+ uint8array[index + 7] = this.buffer[7];
2355
+ uint8array[index + 8] = this.buffer[8];
2356
+ uint8array[index + 9] = this.buffer[9];
2357
+ uint8array[index + 10] = this.buffer[10];
2358
+ uint8array[index + 11] = this.buffer[11];
2359
+ return 12;
2360
+ }
2242
2361
  static createFromTime(time) {
2243
- const buffer = ByteUtils.fromNumberArray([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
2244
- BSONDataView.fromUint8Array(buffer).setUint32(0, time, false);
2362
+ const buffer = ByteUtils.allocate(12);
2363
+ for (let i = 11; i >= 4; i--)
2364
+ buffer[i] = 0;
2365
+ NumberUtils.setInt32BE(buffer, 0, time);
2245
2366
  return new ObjectId(buffer);
2246
2367
  }
2247
2368
  static createFromHexString(hexString) {
@@ -2613,10 +2734,7 @@ const JS_INT_MIN_LONG = Long.fromNumber(JS_INT_MIN);
2613
2734
  function internalDeserialize(buffer, options, isArray) {
2614
2735
  options = options == null ? {} : options;
2615
2736
  const index = options && options.index ? options.index : 0;
2616
- const size = buffer[index] |
2617
- (buffer[index + 1] << 8) |
2618
- (buffer[index + 2] << 16) |
2619
- (buffer[index + 3] << 24);
2737
+ const size = NumberUtils.getInt32LE(buffer, index);
2620
2738
  if (size < 5) {
2621
2739
  throw new BSONError(`bson size must be >= 5, is ${size}`);
2622
2740
  }
@@ -2652,7 +2770,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2652
2770
  const validation = options.validation == null ? { utf8: true } : options.validation;
2653
2771
  let globalUTFValidation = true;
2654
2772
  let validationSetting;
2655
- const utf8KeysSet = new Set();
2773
+ let utf8KeysSet;
2656
2774
  const utf8ValidatedKeys = validation.utf8;
2657
2775
  if (typeof utf8ValidatedKeys === 'boolean') {
2658
2776
  validationSetting = utf8ValidatedKeys;
@@ -2674,6 +2792,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2674
2792
  }
2675
2793
  }
2676
2794
  if (!globalUTFValidation) {
2795
+ utf8KeysSet = new Set();
2677
2796
  for (const key of Object.keys(utf8ValidatedKeys)) {
2678
2797
  utf8KeysSet.add(key);
2679
2798
  }
@@ -2681,14 +2800,14 @@ function deserializeObject(buffer, index, options, isArray = false) {
2681
2800
  const startIndex = index;
2682
2801
  if (buffer.length < 5)
2683
2802
  throw new BSONError('corrupt bson message < 5 bytes long');
2684
- const size = buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24);
2803
+ const size = NumberUtils.getInt32LE(buffer, index);
2804
+ index += 4;
2685
2805
  if (size < 5 || size > buffer.length)
2686
2806
  throw new BSONError('corrupt bson message');
2687
2807
  const object = isArray ? [] : {};
2688
2808
  let arrayIndex = 0;
2689
2809
  const done = false;
2690
2810
  let isPossibleDBRef = isArray ? false : null;
2691
- const dataview = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
2692
2811
  while (!done) {
2693
2812
  const elementType = buffer[index++];
2694
2813
  if (elementType === 0)
@@ -2701,7 +2820,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2701
2820
  throw new BSONError('Bad BSON Document: illegal CString');
2702
2821
  const name = isArray ? arrayIndex++ : ByteUtils.toUTF8(buffer, index, i, false);
2703
2822
  let shouldValidateKey = true;
2704
- if (globalUTFValidation || utf8KeysSet.has(name)) {
2823
+ if (globalUTFValidation || utf8KeysSet?.has(name)) {
2705
2824
  shouldValidateKey = validationSetting;
2706
2825
  }
2707
2826
  else {
@@ -2713,10 +2832,8 @@ function deserializeObject(buffer, index, options, isArray = false) {
2713
2832
  let value;
2714
2833
  index = i + 1;
2715
2834
  if (elementType === BSON_DATA_STRING) {
2716
- const stringSize = buffer[index++] |
2717
- (buffer[index++] << 8) |
2718
- (buffer[index++] << 16) |
2719
- (buffer[index++] << 24);
2835
+ const stringSize = NumberUtils.getInt32LE(buffer, index);
2836
+ index += 4;
2720
2837
  if (stringSize <= 0 ||
2721
2838
  stringSize > buffer.length - index ||
2722
2839
  buffer[index + stringSize - 1] !== 0) {
@@ -2726,38 +2843,30 @@ function deserializeObject(buffer, index, options, isArray = false) {
2726
2843
  index = index + stringSize;
2727
2844
  }
2728
2845
  else if (elementType === BSON_DATA_OID) {
2729
- const oid = ByteUtils.allocate(12);
2730
- oid.set(buffer.subarray(index, index + 12));
2846
+ const oid = ByteUtils.allocateUnsafe(12);
2847
+ for (let i = 0; i < 12; i++)
2848
+ oid[i] = buffer[index + i];
2731
2849
  value = new ObjectId(oid);
2732
2850
  index = index + 12;
2733
2851
  }
2734
2852
  else if (elementType === BSON_DATA_INT && promoteValues === false) {
2735
- value = new Int32(buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24));
2853
+ value = new Int32(NumberUtils.getInt32LE(buffer, index));
2854
+ index += 4;
2736
2855
  }
2737
2856
  else if (elementType === BSON_DATA_INT) {
2738
- value =
2739
- buffer[index++] |
2740
- (buffer[index++] << 8) |
2741
- (buffer[index++] << 16) |
2742
- (buffer[index++] << 24);
2743
- }
2744
- else if (elementType === BSON_DATA_NUMBER && promoteValues === false) {
2745
- value = new Double(dataview.getFloat64(index, true));
2746
- index = index + 8;
2857
+ value = NumberUtils.getInt32LE(buffer, index);
2858
+ index += 4;
2747
2859
  }
2748
2860
  else if (elementType === BSON_DATA_NUMBER) {
2749
- value = dataview.getFloat64(index, true);
2750
- index = index + 8;
2861
+ value = NumberUtils.getFloat64LE(buffer, index);
2862
+ index += 8;
2863
+ if (promoteValues === false)
2864
+ value = new Double(value);
2751
2865
  }
2752
2866
  else if (elementType === BSON_DATA_DATE) {
2753
- const lowBits = buffer[index++] |
2754
- (buffer[index++] << 8) |
2755
- (buffer[index++] << 16) |
2756
- (buffer[index++] << 24);
2757
- const highBits = buffer[index++] |
2758
- (buffer[index++] << 8) |
2759
- (buffer[index++] << 16) |
2760
- (buffer[index++] << 24);
2867
+ const lowBits = NumberUtils.getInt32LE(buffer, index);
2868
+ const highBits = NumberUtils.getInt32LE(buffer, index + 4);
2869
+ index += 8;
2761
2870
  value = new Date(new Long(lowBits, highBits).toNumber());
2762
2871
  }
2763
2872
  else if (elementType === BSON_DATA_BOOLEAN) {
@@ -2767,10 +2876,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2767
2876
  }
2768
2877
  else if (elementType === BSON_DATA_OBJECT) {
2769
2878
  const _index = index;
2770
- const objectSize = buffer[index] |
2771
- (buffer[index + 1] << 8) |
2772
- (buffer[index + 2] << 16) |
2773
- (buffer[index + 3] << 24);
2879
+ const objectSize = NumberUtils.getInt32LE(buffer, index);
2774
2880
  if (objectSize <= 0 || objectSize > buffer.length - index)
2775
2881
  throw new BSONError('bad embedded document length in bson');
2776
2882
  if (raw) {
@@ -2787,10 +2893,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2787
2893
  }
2788
2894
  else if (elementType === BSON_DATA_ARRAY) {
2789
2895
  const _index = index;
2790
- const objectSize = buffer[index] |
2791
- (buffer[index + 1] << 8) |
2792
- (buffer[index + 2] << 16) |
2793
- (buffer[index + 3] << 24);
2896
+ const objectSize = NumberUtils.getInt32LE(buffer, index);
2794
2897
  let arrayOptions = options;
2795
2898
  const stopIndex = index + objectSize;
2796
2899
  if (fieldsAsRaw && fieldsAsRaw[name]) {
@@ -2813,40 +2916,36 @@ function deserializeObject(buffer, index, options, isArray = false) {
2813
2916
  value = null;
2814
2917
  }
2815
2918
  else if (elementType === BSON_DATA_LONG) {
2816
- const dataview = BSONDataView.fromUint8Array(buffer.subarray(index, index + 8));
2817
- const lowBits = buffer[index++] |
2818
- (buffer[index++] << 8) |
2819
- (buffer[index++] << 16) |
2820
- (buffer[index++] << 24);
2821
- const highBits = buffer[index++] |
2822
- (buffer[index++] << 8) |
2823
- (buffer[index++] << 16) |
2824
- (buffer[index++] << 24);
2825
- const long = new Long(lowBits, highBits);
2826
2919
  if (useBigInt64) {
2827
- value = dataview.getBigInt64(0, true);
2828
- }
2829
- else if (promoteLongs && promoteValues === true) {
2830
- value =
2831
- long.lessThanOrEqual(JS_INT_MAX_LONG) && long.greaterThanOrEqual(JS_INT_MIN_LONG)
2832
- ? long.toNumber()
2833
- : long;
2920
+ value = NumberUtils.getBigInt64LE(buffer, index);
2921
+ index += 8;
2834
2922
  }
2835
2923
  else {
2836
- value = long;
2924
+ const lowBits = NumberUtils.getInt32LE(buffer, index);
2925
+ const highBits = NumberUtils.getInt32LE(buffer, index + 4);
2926
+ index += 8;
2927
+ const long = new Long(lowBits, highBits);
2928
+ if (promoteLongs && promoteValues === true) {
2929
+ value =
2930
+ long.lessThanOrEqual(JS_INT_MAX_LONG) && long.greaterThanOrEqual(JS_INT_MIN_LONG)
2931
+ ? long.toNumber()
2932
+ : long;
2933
+ }
2934
+ else {
2935
+ value = long;
2936
+ }
2837
2937
  }
2838
2938
  }
2839
2939
  else if (elementType === BSON_DATA_DECIMAL128) {
2840
- const bytes = ByteUtils.allocate(16);
2841
- bytes.set(buffer.subarray(index, index + 16), 0);
2940
+ const bytes = ByteUtils.allocateUnsafe(16);
2941
+ for (let i = 0; i < 16; i++)
2942
+ bytes[i] = buffer[index + i];
2842
2943
  index = index + 16;
2843
2944
  value = new Decimal128(bytes);
2844
2945
  }
2845
2946
  else if (elementType === BSON_DATA_BINARY) {
2846
- let binarySize = buffer[index++] |
2847
- (buffer[index++] << 8) |
2848
- (buffer[index++] << 16) |
2849
- (buffer[index++] << 24);
2947
+ let binarySize = NumberUtils.getInt32LE(buffer, index);
2948
+ index += 4;
2850
2949
  const totalBinarySize = binarySize;
2851
2950
  const subType = buffer[index++];
2852
2951
  if (binarySize < 0)
@@ -2855,11 +2954,8 @@ function deserializeObject(buffer, index, options, isArray = false) {
2855
2954
  throw new BSONError('Binary type size larger than document size');
2856
2955
  if (buffer['slice'] != null) {
2857
2956
  if (subType === Binary.SUBTYPE_BYTE_ARRAY) {
2858
- binarySize =
2859
- buffer[index++] |
2860
- (buffer[index++] << 8) |
2861
- (buffer[index++] << 16) |
2862
- (buffer[index++] << 24);
2957
+ binarySize = NumberUtils.getInt32LE(buffer, index);
2958
+ index += 4;
2863
2959
  if (binarySize < 0)
2864
2960
  throw new BSONError('Negative binary type element size found for subtype 0x02');
2865
2961
  if (binarySize > totalBinarySize - 4)
@@ -2878,13 +2974,9 @@ function deserializeObject(buffer, index, options, isArray = false) {
2878
2974
  }
2879
2975
  }
2880
2976
  else {
2881
- const _buffer = ByteUtils.allocate(binarySize);
2882
2977
  if (subType === Binary.SUBTYPE_BYTE_ARRAY) {
2883
- binarySize =
2884
- buffer[index++] |
2885
- (buffer[index++] << 8) |
2886
- (buffer[index++] << 16) |
2887
- (buffer[index++] << 24);
2978
+ binarySize = NumberUtils.getInt32LE(buffer, index);
2979
+ index += 4;
2888
2980
  if (binarySize < 0)
2889
2981
  throw new BSONError('Negative binary type element size found for subtype 0x02');
2890
2982
  if (binarySize > totalBinarySize - 4)
@@ -2892,11 +2984,11 @@ function deserializeObject(buffer, index, options, isArray = false) {
2892
2984
  if (binarySize < totalBinarySize - 4)
2893
2985
  throw new BSONError('Binary type with subtype 0x02 contains too short binary size');
2894
2986
  }
2895
- for (i = 0; i < binarySize; i++) {
2896
- _buffer[i] = buffer[index + i];
2897
- }
2898
2987
  if (promoteBuffers && promoteValues) {
2899
- value = _buffer;
2988
+ value = ByteUtils.allocateUnsafe(binarySize);
2989
+ for (i = 0; i < binarySize; i++) {
2990
+ value[i] = buffer[index + i];
2991
+ }
2900
2992
  }
2901
2993
  else {
2902
2994
  value = new Binary(buffer.slice(index, index + binarySize), subType);
@@ -2960,10 +3052,8 @@ function deserializeObject(buffer, index, options, isArray = false) {
2960
3052
  value = new BSONRegExp(source, regExpOptions);
2961
3053
  }
2962
3054
  else if (elementType === BSON_DATA_SYMBOL) {
2963
- const stringSize = buffer[index++] |
2964
- (buffer[index++] << 8) |
2965
- (buffer[index++] << 16) |
2966
- (buffer[index++] << 24);
3055
+ const stringSize = NumberUtils.getInt32LE(buffer, index);
3056
+ index += 4;
2967
3057
  if (stringSize <= 0 ||
2968
3058
  stringSize > buffer.length - index ||
2969
3059
  buffer[index + stringSize - 1] !== 0) {
@@ -2974,15 +3064,11 @@ function deserializeObject(buffer, index, options, isArray = false) {
2974
3064
  index = index + stringSize;
2975
3065
  }
2976
3066
  else if (elementType === BSON_DATA_TIMESTAMP) {
2977
- const i = buffer[index++] +
2978
- buffer[index++] * (1 << 8) +
2979
- buffer[index++] * (1 << 16) +
2980
- buffer[index++] * (1 << 24);
2981
- const t = buffer[index++] +
2982
- buffer[index++] * (1 << 8) +
2983
- buffer[index++] * (1 << 16) +
2984
- buffer[index++] * (1 << 24);
2985
- value = new Timestamp({ i, t });
3067
+ value = new Timestamp({
3068
+ i: NumberUtils.getUint32LE(buffer, index),
3069
+ t: NumberUtils.getUint32LE(buffer, index + 4)
3070
+ });
3071
+ index += 8;
2986
3072
  }
2987
3073
  else if (elementType === BSON_DATA_MIN_KEY) {
2988
3074
  value = new MinKey();
@@ -2991,10 +3077,8 @@ function deserializeObject(buffer, index, options, isArray = false) {
2991
3077
  value = new MaxKey();
2992
3078
  }
2993
3079
  else if (elementType === BSON_DATA_CODE) {
2994
- const stringSize = buffer[index++] |
2995
- (buffer[index++] << 8) |
2996
- (buffer[index++] << 16) |
2997
- (buffer[index++] << 24);
3080
+ const stringSize = NumberUtils.getInt32LE(buffer, index);
3081
+ index += 4;
2998
3082
  if (stringSize <= 0 ||
2999
3083
  stringSize > buffer.length - index ||
3000
3084
  buffer[index + stringSize - 1] !== 0) {
@@ -3005,17 +3089,13 @@ function deserializeObject(buffer, index, options, isArray = false) {
3005
3089
  index = index + stringSize;
3006
3090
  }
3007
3091
  else if (elementType === BSON_DATA_CODE_W_SCOPE) {
3008
- const totalSize = buffer[index++] |
3009
- (buffer[index++] << 8) |
3010
- (buffer[index++] << 16) |
3011
- (buffer[index++] << 24);
3092
+ const totalSize = NumberUtils.getInt32LE(buffer, index);
3093
+ index += 4;
3012
3094
  if (totalSize < 4 + 4 + 4 + 1) {
3013
3095
  throw new BSONError('code_w_scope total size shorter minimum expected length');
3014
3096
  }
3015
- const stringSize = buffer[index++] |
3016
- (buffer[index++] << 8) |
3017
- (buffer[index++] << 16) |
3018
- (buffer[index++] << 24);
3097
+ const stringSize = NumberUtils.getInt32LE(buffer, index);
3098
+ index += 4;
3019
3099
  if (stringSize <= 0 ||
3020
3100
  stringSize > buffer.length - index ||
3021
3101
  buffer[index + stringSize - 1] !== 0) {
@@ -3024,10 +3104,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
3024
3104
  const functionString = ByteUtils.toUTF8(buffer, index, index + stringSize - 1, shouldValidateKey);
3025
3105
  index = index + stringSize;
3026
3106
  const _index = index;
3027
- const objectSize = buffer[index] |
3028
- (buffer[index + 1] << 8) |
3029
- (buffer[index + 2] << 16) |
3030
- (buffer[index + 3] << 24);
3107
+ const objectSize = NumberUtils.getInt32LE(buffer, index);
3031
3108
  const scopeObject = deserializeObject(buffer, _index, options, false);
3032
3109
  index = index + objectSize;
3033
3110
  if (totalSize < 4 + 4 + objectSize + stringSize) {
@@ -3039,10 +3116,8 @@ function deserializeObject(buffer, index, options, isArray = false) {
3039
3116
  value = new Code(functionString, scopeObject);
3040
3117
  }
3041
3118
  else if (elementType === BSON_DATA_DBPOINTER) {
3042
- const stringSize = buffer[index++] |
3043
- (buffer[index++] << 8) |
3044
- (buffer[index++] << 16) |
3045
- (buffer[index++] << 24);
3119
+ const stringSize = NumberUtils.getInt32LE(buffer, index);
3120
+ index += 4;
3046
3121
  if (stringSize <= 0 ||
3047
3122
  stringSize > buffer.length - index ||
3048
3123
  buffer[index + stringSize - 1] !== 0)
@@ -3054,8 +3129,9 @@ function deserializeObject(buffer, index, options, isArray = false) {
3054
3129
  }
3055
3130
  const namespace = ByteUtils.toUTF8(buffer, index, index + stringSize - 1, false);
3056
3131
  index = index + stringSize;
3057
- const oidBuffer = ByteUtils.allocate(12);
3058
- oidBuffer.set(buffer.subarray(index, index + 12), 0);
3132
+ const oidBuffer = ByteUtils.allocateUnsafe(12);
3133
+ for (let i = 0; i < 12; i++)
3134
+ oidBuffer[i] = buffer[index + i];
3059
3135
  const oid = new ObjectId(oidBuffer);
3060
3136
  index = index + 12;
3061
3137
  value = new DBRef(namespace, oid);
@@ -3100,17 +3176,11 @@ function serializeString(buffer, key, value, index) {
3100
3176
  index = index + numberOfWrittenBytes + 1;
3101
3177
  buffer[index - 1] = 0;
3102
3178
  const size = ByteUtils.encodeUTF8Into(buffer, value, index + 4);
3103
- buffer[index + 3] = ((size + 1) >> 24) & 0xff;
3104
- buffer[index + 2] = ((size + 1) >> 16) & 0xff;
3105
- buffer[index + 1] = ((size + 1) >> 8) & 0xff;
3106
- buffer[index] = (size + 1) & 0xff;
3179
+ NumberUtils.setInt32LE(buffer, index, size + 1);
3107
3180
  index = index + 4 + size;
3108
3181
  buffer[index++] = 0;
3109
3182
  return index;
3110
3183
  }
3111
- const NUMBER_SPACE = new DataView(new ArrayBuffer(8), 0, 8);
3112
- const FOUR_BYTE_VIEW_ON_NUMBER = new Uint8Array(NUMBER_SPACE.buffer, 0, 4);
3113
- const EIGHT_BYTE_VIEW_ON_NUMBER = new Uint8Array(NUMBER_SPACE.buffer, 0, 8);
3114
3184
  function serializeNumber(buffer, key, value, index) {
3115
3185
  const isNegativeZero = Object.is(value, -0);
3116
3186
  const type = !isNegativeZero &&
@@ -3119,19 +3189,16 @@ function serializeNumber(buffer, key, value, index) {
3119
3189
  value >= BSON_INT32_MIN
3120
3190
  ? BSON_DATA_INT
3121
3191
  : BSON_DATA_NUMBER;
3122
- if (type === BSON_DATA_INT) {
3123
- NUMBER_SPACE.setInt32(0, value, true);
3124
- }
3125
- else {
3126
- NUMBER_SPACE.setFloat64(0, value, true);
3127
- }
3128
- const bytes = type === BSON_DATA_INT ? FOUR_BYTE_VIEW_ON_NUMBER : EIGHT_BYTE_VIEW_ON_NUMBER;
3129
3192
  buffer[index++] = type;
3130
3193
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3131
3194
  index = index + numberOfWrittenBytes;
3132
3195
  buffer[index++] = 0x00;
3133
- buffer.set(bytes, index);
3134
- index += bytes.byteLength;
3196
+ if (type === BSON_DATA_INT) {
3197
+ index += NumberUtils.setInt32LE(buffer, index, value);
3198
+ }
3199
+ else {
3200
+ index += NumberUtils.setFloat64LE(buffer, index, value);
3201
+ }
3135
3202
  return index;
3136
3203
  }
3137
3204
  function serializeBigInt(buffer, key, value, index) {
@@ -3139,9 +3206,7 @@ function serializeBigInt(buffer, key, value, index) {
3139
3206
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3140
3207
  index += numberOfWrittenBytes;
3141
3208
  buffer[index++] = 0;
3142
- NUMBER_SPACE.setBigInt64(0, value, true);
3143
- buffer.set(EIGHT_BYTE_VIEW_ON_NUMBER, index);
3144
- index += EIGHT_BYTE_VIEW_ON_NUMBER.byteLength;
3209
+ index += NumberUtils.setBigInt64LE(buffer, index, value);
3145
3210
  return index;
3146
3211
  }
3147
3212
  function serializeNull(buffer, key, _, index) {
@@ -3167,14 +3232,8 @@ function serializeDate(buffer, key, value, index) {
3167
3232
  const dateInMilis = Long.fromNumber(value.getTime());
3168
3233
  const lowBits = dateInMilis.getLowBits();
3169
3234
  const highBits = dateInMilis.getHighBits();
3170
- buffer[index++] = lowBits & 0xff;
3171
- buffer[index++] = (lowBits >> 8) & 0xff;
3172
- buffer[index++] = (lowBits >> 16) & 0xff;
3173
- buffer[index++] = (lowBits >> 24) & 0xff;
3174
- buffer[index++] = highBits & 0xff;
3175
- buffer[index++] = (highBits >> 8) & 0xff;
3176
- buffer[index++] = (highBits >> 16) & 0xff;
3177
- buffer[index++] = (highBits >> 24) & 0xff;
3235
+ index += NumberUtils.setInt32LE(buffer, index, lowBits);
3236
+ index += NumberUtils.setInt32LE(buffer, index, highBits);
3178
3237
  return index;
3179
3238
  }
3180
3239
  function serializeRegExp(buffer, key, value, index) {
@@ -3231,15 +3290,7 @@ function serializeObjectId(buffer, key, value, index) {
3231
3290
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3232
3291
  index = index + numberOfWrittenBytes;
3233
3292
  buffer[index++] = 0;
3234
- const idValue = value.id;
3235
- if (isUint8Array(idValue)) {
3236
- for (let i = 0; i < 12; i++) {
3237
- buffer[index++] = idValue[i];
3238
- }
3239
- }
3240
- else {
3241
- throw new BSONError('object [' + JSON.stringify(value) + '] is not a valid ObjectId');
3242
- }
3293
+ index += value.serializeInto(buffer, index);
3243
3294
  return index;
3244
3295
  }
3245
3296
  function serializeBuffer(buffer, key, value, index) {
@@ -3248,12 +3299,15 @@ function serializeBuffer(buffer, key, value, index) {
3248
3299
  index = index + numberOfWrittenBytes;
3249
3300
  buffer[index++] = 0;
3250
3301
  const size = value.length;
3251
- buffer[index++] = size & 0xff;
3252
- buffer[index++] = (size >> 8) & 0xff;
3253
- buffer[index++] = (size >> 16) & 0xff;
3254
- buffer[index++] = (size >> 24) & 0xff;
3302
+ index += NumberUtils.setInt32LE(buffer, index, size);
3255
3303
  buffer[index++] = BSON_BINARY_SUBTYPE_DEFAULT;
3256
- buffer.set(value, index);
3304
+ if (size <= 16) {
3305
+ for (let i = 0; i < size; i++)
3306
+ buffer[index + i] = value[i];
3307
+ }
3308
+ else {
3309
+ buffer.set(value, index);
3310
+ }
3257
3311
  index = index + size;
3258
3312
  return index;
3259
3313
  }
@@ -3275,7 +3329,8 @@ function serializeDecimal128(buffer, key, value, index) {
3275
3329
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3276
3330
  index = index + numberOfWrittenBytes;
3277
3331
  buffer[index++] = 0;
3278
- buffer.set(value.bytes.subarray(0, 16), index);
3332
+ for (let i = 0; i < 16; i++)
3333
+ buffer[index + i] = value.bytes[i];
3279
3334
  return index + 16;
3280
3335
  }
3281
3336
  function serializeLong(buffer, key, value, index) {
@@ -3286,14 +3341,8 @@ function serializeLong(buffer, key, value, index) {
3286
3341
  buffer[index++] = 0;
3287
3342
  const lowBits = value.getLowBits();
3288
3343
  const highBits = value.getHighBits();
3289
- buffer[index++] = lowBits & 0xff;
3290
- buffer[index++] = (lowBits >> 8) & 0xff;
3291
- buffer[index++] = (lowBits >> 16) & 0xff;
3292
- buffer[index++] = (lowBits >> 24) & 0xff;
3293
- buffer[index++] = highBits & 0xff;
3294
- buffer[index++] = (highBits >> 8) & 0xff;
3295
- buffer[index++] = (highBits >> 16) & 0xff;
3296
- buffer[index++] = (highBits >> 24) & 0xff;
3344
+ index += NumberUtils.setInt32LE(buffer, index, lowBits);
3345
+ index += NumberUtils.setInt32LE(buffer, index, highBits);
3297
3346
  return index;
3298
3347
  }
3299
3348
  function serializeInt32(buffer, key, value, index) {
@@ -3302,10 +3351,7 @@ function serializeInt32(buffer, key, value, index) {
3302
3351
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3303
3352
  index = index + numberOfWrittenBytes;
3304
3353
  buffer[index++] = 0;
3305
- buffer[index++] = value & 0xff;
3306
- buffer[index++] = (value >> 8) & 0xff;
3307
- buffer[index++] = (value >> 16) & 0xff;
3308
- buffer[index++] = (value >> 24) & 0xff;
3354
+ index += NumberUtils.setInt32LE(buffer, index, value);
3309
3355
  return index;
3310
3356
  }
3311
3357
  function serializeDouble(buffer, key, value, index) {
@@ -3313,9 +3359,7 @@ function serializeDouble(buffer, key, value, index) {
3313
3359
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3314
3360
  index = index + numberOfWrittenBytes;
3315
3361
  buffer[index++] = 0;
3316
- NUMBER_SPACE.setFloat64(0, value.value, true);
3317
- buffer.set(EIGHT_BYTE_VIEW_ON_NUMBER, index);
3318
- index = index + 8;
3362
+ index += NumberUtils.setFloat64LE(buffer, index, value.value);
3319
3363
  return index;
3320
3364
  }
3321
3365
  function serializeFunction(buffer, key, value, index) {
@@ -3325,10 +3369,7 @@ function serializeFunction(buffer, key, value, index) {
3325
3369
  buffer[index++] = 0;
3326
3370
  const functionString = value.toString();
3327
3371
  const size = ByteUtils.encodeUTF8Into(buffer, functionString, index + 4) + 1;
3328
- buffer[index] = size & 0xff;
3329
- buffer[index + 1] = (size >> 8) & 0xff;
3330
- buffer[index + 2] = (size >> 16) & 0xff;
3331
- buffer[index + 3] = (size >> 24) & 0xff;
3372
+ NumberUtils.setInt32LE(buffer, index, size);
3332
3373
  index = index + 4 + size - 1;
3333
3374
  buffer[index++] = 0;
3334
3375
  return index;
@@ -3343,19 +3384,13 @@ function serializeCode(buffer, key, value, index, checkKeys = false, depth = 0,
3343
3384
  const functionString = value.code;
3344
3385
  index = index + 4;
3345
3386
  const codeSize = ByteUtils.encodeUTF8Into(buffer, functionString, index + 4) + 1;
3346
- buffer[index] = codeSize & 0xff;
3347
- buffer[index + 1] = (codeSize >> 8) & 0xff;
3348
- buffer[index + 2] = (codeSize >> 16) & 0xff;
3349
- buffer[index + 3] = (codeSize >> 24) & 0xff;
3387
+ NumberUtils.setInt32LE(buffer, index, codeSize);
3350
3388
  buffer[index + 4 + codeSize - 1] = 0;
3351
3389
  index = index + codeSize + 4;
3352
3390
  const endIndex = serializeInto(buffer, value.scope, checkKeys, index, depth + 1, serializeFunctions, ignoreUndefined, path);
3353
3391
  index = endIndex - 1;
3354
3392
  const totalSize = endIndex - startIndex;
3355
- buffer[startIndex++] = totalSize & 0xff;
3356
- buffer[startIndex++] = (totalSize >> 8) & 0xff;
3357
- buffer[startIndex++] = (totalSize >> 16) & 0xff;
3358
- buffer[startIndex++] = (totalSize >> 24) & 0xff;
3393
+ startIndex += NumberUtils.setInt32LE(buffer, startIndex, totalSize);
3359
3394
  buffer[index++] = 0;
3360
3395
  }
3361
3396
  else {
@@ -3365,10 +3400,7 @@ function serializeCode(buffer, key, value, index, checkKeys = false, depth = 0,
3365
3400
  buffer[index++] = 0;
3366
3401
  const functionString = value.code.toString();
3367
3402
  const size = ByteUtils.encodeUTF8Into(buffer, functionString, index + 4) + 1;
3368
- buffer[index] = size & 0xff;
3369
- buffer[index + 1] = (size >> 8) & 0xff;
3370
- buffer[index + 2] = (size >> 16) & 0xff;
3371
- buffer[index + 3] = (size >> 24) & 0xff;
3403
+ NumberUtils.setInt32LE(buffer, index, size);
3372
3404
  index = index + 4 + size - 1;
3373
3405
  buffer[index++] = 0;
3374
3406
  }
@@ -3383,19 +3415,19 @@ function serializeBinary(buffer, key, value, index) {
3383
3415
  let size = value.position;
3384
3416
  if (value.sub_type === Binary.SUBTYPE_BYTE_ARRAY)
3385
3417
  size = size + 4;
3386
- buffer[index++] = size & 0xff;
3387
- buffer[index++] = (size >> 8) & 0xff;
3388
- buffer[index++] = (size >> 16) & 0xff;
3389
- buffer[index++] = (size >> 24) & 0xff;
3418
+ index += NumberUtils.setInt32LE(buffer, index, size);
3390
3419
  buffer[index++] = value.sub_type;
3391
3420
  if (value.sub_type === Binary.SUBTYPE_BYTE_ARRAY) {
3392
3421
  size = size - 4;
3393
- buffer[index++] = size & 0xff;
3394
- buffer[index++] = (size >> 8) & 0xff;
3395
- buffer[index++] = (size >> 16) & 0xff;
3396
- buffer[index++] = (size >> 24) & 0xff;
3422
+ index += NumberUtils.setInt32LE(buffer, index, size);
3423
+ }
3424
+ if (size <= 16) {
3425
+ for (let i = 0; i < size; i++)
3426
+ buffer[index + i] = data[i];
3427
+ }
3428
+ else {
3429
+ buffer.set(data, index);
3397
3430
  }
3398
- buffer.set(data, index);
3399
3431
  index = index + value.position;
3400
3432
  return index;
3401
3433
  }
@@ -3405,12 +3437,9 @@ function serializeSymbol(buffer, key, value, index) {
3405
3437
  index = index + numberOfWrittenBytes;
3406
3438
  buffer[index++] = 0;
3407
3439
  const size = ByteUtils.encodeUTF8Into(buffer, value.value, index + 4) + 1;
3408
- buffer[index] = size & 0xff;
3409
- buffer[index + 1] = (size >> 8) & 0xff;
3410
- buffer[index + 2] = (size >> 16) & 0xff;
3411
- buffer[index + 3] = (size >> 24) & 0xff;
3440
+ NumberUtils.setInt32LE(buffer, index, size);
3412
3441
  index = index + 4 + size - 1;
3413
- buffer[index++] = 0x00;
3442
+ buffer[index++] = 0;
3414
3443
  return index;
3415
3444
  }
3416
3445
  function serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path) {
@@ -3429,10 +3458,7 @@ function serializeDBRef(buffer, key, value, index, depth, serializeFunctions, pa
3429
3458
  output = Object.assign(output, value.fields);
3430
3459
  const endIndex = serializeInto(buffer, output, false, index, depth + 1, serializeFunctions, true, path);
3431
3460
  const size = endIndex - startIndex;
3432
- buffer[startIndex++] = size & 0xff;
3433
- buffer[startIndex++] = (size >> 8) & 0xff;
3434
- buffer[startIndex++] = (size >> 16) & 0xff;
3435
- buffer[startIndex++] = (size >> 24) & 0xff;
3461
+ startIndex += NumberUtils.setInt32LE(buffer, index, size);
3436
3462
  return endIndex;
3437
3463
  }
3438
3464
  function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializeFunctions, ignoreUndefined, path) {
@@ -3568,7 +3594,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3568
3594
  if ('$' === key[0]) {
3569
3595
  throw new BSONError('key ' + key + " must not start with '$'");
3570
3596
  }
3571
- else if (~key.indexOf('.')) {
3597
+ else if (key.includes('.')) {
3572
3598
  throw new BSONError('key ' + key + " must not contain '.'");
3573
3599
  }
3574
3600
  }
@@ -3666,7 +3692,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3666
3692
  if ('$' === key[0]) {
3667
3693
  throw new BSONError('key ' + key + " must not start with '$'");
3668
3694
  }
3669
- else if (~key.indexOf('.')) {
3695
+ else if (key.includes('.')) {
3670
3696
  throw new BSONError('key ' + key + " must not contain '.'");
3671
3697
  }
3672
3698
  }
@@ -3750,10 +3776,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3750
3776
  path.delete(object);
3751
3777
  buffer[index++] = 0x00;
3752
3778
  const size = index - startingIndex;
3753
- buffer[startingIndex++] = size & 0xff;
3754
- buffer[startingIndex++] = (size >> 8) & 0xff;
3755
- buffer[startingIndex++] = (size >> 16) & 0xff;
3756
- buffer[startingIndex++] = (size >> 24) & 0xff;
3779
+ startingIndex += NumberUtils.setInt32LE(buffer, startingIndex, size);
3757
3780
  return index;
3758
3781
  }
3759
3782
 
@@ -4083,7 +4106,7 @@ function serialize(object, options = {}) {
4083
4106
  buffer = ByteUtils.allocate(minInternalBufferSize);
4084
4107
  }
4085
4108
  const serializationIndex = serializeInto(buffer, object, checkKeys, 0, 0, serializeFunctions, ignoreUndefined, null);
4086
- const finishedBuffer = ByteUtils.allocate(serializationIndex);
4109
+ const finishedBuffer = ByteUtils.allocateUnsafe(serializationIndex);
4087
4110
  finishedBuffer.set(buffer.subarray(0, serializationIndex), 0);
4088
4111
  return finishedBuffer;
4089
4112
  }
@@ -4110,10 +4133,7 @@ function deserializeStream(data, startIndex, numberOfDocuments, documents, docSt
4110
4133
  const bufferData = ByteUtils.toLocalBufferType(data);
4111
4134
  let index = startIndex;
4112
4135
  for (let i = 0; i < numberOfDocuments; i++) {
4113
- const size = bufferData[index] |
4114
- (bufferData[index + 1] << 8) |
4115
- (bufferData[index + 2] << 16) |
4116
- (bufferData[index + 3] << 24);
4136
+ const size = NumberUtils.getInt32LE(bufferData, index);
4117
4137
  internalOptions.index = index;
4118
4138
  documents[docStartIndex + i] = internalDeserialize(bufferData, internalOptions);
4119
4139
  index = index + size;