bson 6.3.0 → 6.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/bson.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,99 @@ 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
+ 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 lo = NumberUtils.getUint32LE(source, offset);
2149
+ const hi = NumberUtils.getUint32LE(source, offset + 4);
2150
+ return (BigInt(hi) << BigInt(32)) + BigInt(lo);
2151
+ },
2152
+ getFloat64LE(source, offset) {
2153
+ FLOAT_BYTES[0] = source[offset];
2154
+ FLOAT_BYTES[1] = source[offset + 1];
2155
+ FLOAT_BYTES[2] = source[offset + 2];
2156
+ FLOAT_BYTES[3] = source[offset + 3];
2157
+ FLOAT_BYTES[4] = source[offset + 4];
2158
+ FLOAT_BYTES[5] = source[offset + 5];
2159
+ FLOAT_BYTES[6] = source[offset + 6];
2160
+ FLOAT_BYTES[7] = source[offset + 7];
2161
+ return FLOAT[0];
2162
+ },
2163
+ setInt32BE(destination, offset, value) {
2164
+ destination[offset + 3] = value;
2165
+ value >>>= 8;
2166
+ destination[offset + 2] = value;
2167
+ value >>>= 8;
2168
+ destination[offset + 1] = value;
2169
+ value >>>= 8;
2170
+ destination[offset] = value;
2171
+ return 4;
2172
+ },
2173
+ setInt32LE(destination, offset, value) {
2174
+ destination[offset] = value;
2175
+ value >>>= 8;
2176
+ destination[offset + 1] = value;
2177
+ value >>>= 8;
2178
+ destination[offset + 2] = value;
2179
+ value >>>= 8;
2180
+ destination[offset + 3] = value;
2181
+ return 4;
2182
+ },
2183
+ setBigInt64LE(destination, offset, value) {
2184
+ const mask32bits = BigInt(4294967295);
2185
+ let lo = Number(value & mask32bits);
2186
+ destination[offset] = lo;
2187
+ lo >>= 8;
2188
+ destination[offset + 1] = lo;
2189
+ lo >>= 8;
2190
+ destination[offset + 2] = lo;
2191
+ lo >>= 8;
2192
+ destination[offset + 3] = lo;
2193
+ let hi = Number((value >> BigInt(32)) & mask32bits);
2194
+ destination[offset + 4] = hi;
2195
+ hi >>= 8;
2196
+ destination[offset + 5] = hi;
2197
+ hi >>= 8;
2198
+ destination[offset + 6] = hi;
2199
+ hi >>= 8;
2200
+ destination[offset + 7] = hi;
2201
+ return 8;
2202
+ },
2203
+ setFloat64LE(destination, offset, value) {
2204
+ FLOAT[0] = value;
2205
+ destination[offset] = FLOAT_BYTES[0];
2206
+ destination[offset + 1] = FLOAT_BYTES[1];
2207
+ destination[offset + 2] = FLOAT_BYTES[2];
2208
+ destination[offset + 3] = FLOAT_BYTES[3];
2209
+ destination[offset + 4] = FLOAT_BYTES[4];
2210
+ destination[offset + 5] = FLOAT_BYTES[5];
2211
+ destination[offset + 6] = FLOAT_BYTES[6];
2212
+ destination[offset + 7] = FLOAT_BYTES[7];
2213
+ return 8;
2214
+ }
2215
+ };
2216
+
2112
2217
  const checkForHexRegExp = new RegExp('^[0-9a-fA-F]{24}$');
2113
2218
  let PROCESS_UNIQUE = null;
2114
- const kId = Symbol('id');
2115
2219
  class ObjectId extends BSONValue {
2116
2220
  get _bsontype() {
2117
2221
  return 'ObjectId';
@@ -2134,14 +2238,14 @@ class ObjectId extends BSONValue {
2134
2238
  workingId = inputId;
2135
2239
  }
2136
2240
  if (workingId == null || typeof workingId === 'number') {
2137
- this[kId] = ObjectId.generate(typeof workingId === 'number' ? workingId : undefined);
2241
+ this.buffer = ObjectId.generate(typeof workingId === 'number' ? workingId : undefined);
2138
2242
  }
2139
2243
  else if (ArrayBuffer.isView(workingId) && workingId.byteLength === 12) {
2140
- this[kId] = ByteUtils.toLocalBufferType(workingId);
2244
+ this.buffer = ByteUtils.toLocalBufferType(workingId);
2141
2245
  }
2142
2246
  else if (typeof workingId === 'string') {
2143
2247
  if (workingId.length === 24 && checkForHexRegExp.test(workingId)) {
2144
- this[kId] = ByteUtils.fromHex(workingId);
2248
+ this.buffer = ByteUtils.fromHex(workingId);
2145
2249
  }
2146
2250
  else {
2147
2251
  throw new BSONError('input must be a 24 character hex string, 12 byte Uint8Array, or an integer');
@@ -2155,10 +2259,10 @@ class ObjectId extends BSONValue {
2155
2259
  }
2156
2260
  }
2157
2261
  get id() {
2158
- return this[kId];
2262
+ return this.buffer;
2159
2263
  }
2160
2264
  set id(value) {
2161
- this[kId] = value;
2265
+ this.buffer = value;
2162
2266
  if (ObjectId.cacheHexString) {
2163
2267
  this.__id = ByteUtils.toHex(value);
2164
2268
  }
@@ -2181,8 +2285,8 @@ class ObjectId extends BSONValue {
2181
2285
  time = Math.floor(Date.now() / 1000);
2182
2286
  }
2183
2287
  const inc = ObjectId.getInc();
2184
- const buffer = ByteUtils.allocate(12);
2185
- BSONDataView.fromUint8Array(buffer).setUint32(0, time, false);
2288
+ const buffer = ByteUtils.allocateUnsafe(12);
2289
+ NumberUtils.setInt32BE(buffer, 0, time);
2186
2290
  if (PROCESS_UNIQUE === null) {
2187
2291
  PROCESS_UNIQUE = ByteUtils.randomBytes(5);
2188
2292
  }
@@ -2217,7 +2321,7 @@ class ObjectId extends BSONValue {
2217
2321
  return false;
2218
2322
  }
2219
2323
  if (ObjectId.is(otherId)) {
2220
- return this[kId][11] === otherId[kId][11] && ByteUtils.equals(this[kId], otherId[kId]);
2324
+ return (this.buffer[11] === otherId.buffer[11] && ByteUtils.equals(this.buffer, otherId.buffer));
2221
2325
  }
2222
2326
  if (typeof otherId === 'string') {
2223
2327
  return otherId.toLowerCase() === this.toHexString();
@@ -2231,16 +2335,33 @@ class ObjectId extends BSONValue {
2231
2335
  }
2232
2336
  getTimestamp() {
2233
2337
  const timestamp = new Date();
2234
- const time = BSONDataView.fromUint8Array(this.id).getUint32(0, false);
2338
+ const time = NumberUtils.getUint32BE(this.buffer, 0);
2235
2339
  timestamp.setTime(Math.floor(time) * 1000);
2236
2340
  return timestamp;
2237
2341
  }
2238
2342
  static createPk() {
2239
2343
  return new ObjectId();
2240
2344
  }
2345
+ serializeInto(uint8array, index) {
2346
+ uint8array[index] = this.buffer[0];
2347
+ uint8array[index + 1] = this.buffer[1];
2348
+ uint8array[index + 2] = this.buffer[2];
2349
+ uint8array[index + 3] = this.buffer[3];
2350
+ uint8array[index + 4] = this.buffer[4];
2351
+ uint8array[index + 5] = this.buffer[5];
2352
+ uint8array[index + 6] = this.buffer[6];
2353
+ uint8array[index + 7] = this.buffer[7];
2354
+ uint8array[index + 8] = this.buffer[8];
2355
+ uint8array[index + 9] = this.buffer[9];
2356
+ uint8array[index + 10] = this.buffer[10];
2357
+ uint8array[index + 11] = this.buffer[11];
2358
+ return 12;
2359
+ }
2241
2360
  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);
2361
+ const buffer = ByteUtils.allocate(12);
2362
+ for (let i = 11; i >= 4; i--)
2363
+ buffer[i] = 0;
2364
+ NumberUtils.setInt32BE(buffer, 0, time);
2244
2365
  return new ObjectId(buffer);
2245
2366
  }
2246
2367
  static createFromHexString(hexString) {
@@ -2612,10 +2733,7 @@ const JS_INT_MIN_LONG = Long.fromNumber(JS_INT_MIN);
2612
2733
  function internalDeserialize(buffer, options, isArray) {
2613
2734
  options = options == null ? {} : options;
2614
2735
  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);
2736
+ const size = NumberUtils.getInt32LE(buffer, index);
2619
2737
  if (size < 5) {
2620
2738
  throw new BSONError(`bson size must be >= 5, is ${size}`);
2621
2739
  }
@@ -2651,7 +2769,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2651
2769
  const validation = options.validation == null ? { utf8: true } : options.validation;
2652
2770
  let globalUTFValidation = true;
2653
2771
  let validationSetting;
2654
- const utf8KeysSet = new Set();
2772
+ let utf8KeysSet;
2655
2773
  const utf8ValidatedKeys = validation.utf8;
2656
2774
  if (typeof utf8ValidatedKeys === 'boolean') {
2657
2775
  validationSetting = utf8ValidatedKeys;
@@ -2673,6 +2791,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2673
2791
  }
2674
2792
  }
2675
2793
  if (!globalUTFValidation) {
2794
+ utf8KeysSet = new Set();
2676
2795
  for (const key of Object.keys(utf8ValidatedKeys)) {
2677
2796
  utf8KeysSet.add(key);
2678
2797
  }
@@ -2680,14 +2799,14 @@ function deserializeObject(buffer, index, options, isArray = false) {
2680
2799
  const startIndex = index;
2681
2800
  if (buffer.length < 5)
2682
2801
  throw new BSONError('corrupt bson message < 5 bytes long');
2683
- const size = buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24);
2802
+ const size = NumberUtils.getInt32LE(buffer, index);
2803
+ index += 4;
2684
2804
  if (size < 5 || size > buffer.length)
2685
2805
  throw new BSONError('corrupt bson message');
2686
2806
  const object = isArray ? [] : {};
2687
2807
  let arrayIndex = 0;
2688
2808
  const done = false;
2689
2809
  let isPossibleDBRef = isArray ? false : null;
2690
- const dataview = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
2691
2810
  while (!done) {
2692
2811
  const elementType = buffer[index++];
2693
2812
  if (elementType === 0)
@@ -2700,7 +2819,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2700
2819
  throw new BSONError('Bad BSON Document: illegal CString');
2701
2820
  const name = isArray ? arrayIndex++ : ByteUtils.toUTF8(buffer, index, i, false);
2702
2821
  let shouldValidateKey = true;
2703
- if (globalUTFValidation || utf8KeysSet.has(name)) {
2822
+ if (globalUTFValidation || utf8KeysSet?.has(name)) {
2704
2823
  shouldValidateKey = validationSetting;
2705
2824
  }
2706
2825
  else {
@@ -2712,10 +2831,8 @@ function deserializeObject(buffer, index, options, isArray = false) {
2712
2831
  let value;
2713
2832
  index = i + 1;
2714
2833
  if (elementType === BSON_DATA_STRING) {
2715
- const stringSize = buffer[index++] |
2716
- (buffer[index++] << 8) |
2717
- (buffer[index++] << 16) |
2718
- (buffer[index++] << 24);
2834
+ const stringSize = NumberUtils.getInt32LE(buffer, index);
2835
+ index += 4;
2719
2836
  if (stringSize <= 0 ||
2720
2837
  stringSize > buffer.length - index ||
2721
2838
  buffer[index + stringSize - 1] !== 0) {
@@ -2725,38 +2842,30 @@ function deserializeObject(buffer, index, options, isArray = false) {
2725
2842
  index = index + stringSize;
2726
2843
  }
2727
2844
  else if (elementType === BSON_DATA_OID) {
2728
- const oid = ByteUtils.allocate(12);
2729
- oid.set(buffer.subarray(index, index + 12));
2845
+ const oid = ByteUtils.allocateUnsafe(12);
2846
+ for (let i = 0; i < 12; i++)
2847
+ oid[i] = buffer[index + i];
2730
2848
  value = new ObjectId(oid);
2731
2849
  index = index + 12;
2732
2850
  }
2733
2851
  else if (elementType === BSON_DATA_INT && promoteValues === false) {
2734
- value = new Int32(buffer[index++] | (buffer[index++] << 8) | (buffer[index++] << 16) | (buffer[index++] << 24));
2852
+ value = new Int32(NumberUtils.getInt32LE(buffer, index));
2853
+ index += 4;
2735
2854
  }
2736
2855
  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;
2856
+ value = NumberUtils.getInt32LE(buffer, index);
2857
+ index += 4;
2746
2858
  }
2747
2859
  else if (elementType === BSON_DATA_NUMBER) {
2748
- value = dataview.getFloat64(index, true);
2749
- index = index + 8;
2860
+ value = NumberUtils.getFloat64LE(buffer, index);
2861
+ index += 8;
2862
+ if (promoteValues === false)
2863
+ value = new Double(value);
2750
2864
  }
2751
2865
  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);
2866
+ const lowBits = NumberUtils.getInt32LE(buffer, index);
2867
+ const highBits = NumberUtils.getInt32LE(buffer, index + 4);
2868
+ index += 8;
2760
2869
  value = new Date(new Long(lowBits, highBits).toNumber());
2761
2870
  }
2762
2871
  else if (elementType === BSON_DATA_BOOLEAN) {
@@ -2766,10 +2875,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2766
2875
  }
2767
2876
  else if (elementType === BSON_DATA_OBJECT) {
2768
2877
  const _index = index;
2769
- const objectSize = buffer[index] |
2770
- (buffer[index + 1] << 8) |
2771
- (buffer[index + 2] << 16) |
2772
- (buffer[index + 3] << 24);
2878
+ const objectSize = NumberUtils.getInt32LE(buffer, index);
2773
2879
  if (objectSize <= 0 || objectSize > buffer.length - index)
2774
2880
  throw new BSONError('bad embedded document length in bson');
2775
2881
  if (raw) {
@@ -2786,10 +2892,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
2786
2892
  }
2787
2893
  else if (elementType === BSON_DATA_ARRAY) {
2788
2894
  const _index = index;
2789
- const objectSize = buffer[index] |
2790
- (buffer[index + 1] << 8) |
2791
- (buffer[index + 2] << 16) |
2792
- (buffer[index + 3] << 24);
2895
+ const objectSize = NumberUtils.getInt32LE(buffer, index);
2793
2896
  let arrayOptions = options;
2794
2897
  const stopIndex = index + objectSize;
2795
2898
  if (fieldsAsRaw && fieldsAsRaw[name]) {
@@ -2812,40 +2915,36 @@ function deserializeObject(buffer, index, options, isArray = false) {
2812
2915
  value = null;
2813
2916
  }
2814
2917
  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
2918
  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;
2919
+ value = NumberUtils.getBigInt64LE(buffer, index);
2920
+ index += 8;
2833
2921
  }
2834
2922
  else {
2835
- value = long;
2923
+ const lowBits = NumberUtils.getInt32LE(buffer, index);
2924
+ const highBits = NumberUtils.getInt32LE(buffer, index + 4);
2925
+ index += 8;
2926
+ const long = new Long(lowBits, highBits);
2927
+ if (promoteLongs && promoteValues === true) {
2928
+ value =
2929
+ long.lessThanOrEqual(JS_INT_MAX_LONG) && long.greaterThanOrEqual(JS_INT_MIN_LONG)
2930
+ ? long.toNumber()
2931
+ : long;
2932
+ }
2933
+ else {
2934
+ value = long;
2935
+ }
2836
2936
  }
2837
2937
  }
2838
2938
  else if (elementType === BSON_DATA_DECIMAL128) {
2839
- const bytes = ByteUtils.allocate(16);
2840
- bytes.set(buffer.subarray(index, index + 16), 0);
2939
+ const bytes = ByteUtils.allocateUnsafe(16);
2940
+ for (let i = 0; i < 16; i++)
2941
+ bytes[i] = buffer[index + i];
2841
2942
  index = index + 16;
2842
2943
  value = new Decimal128(bytes);
2843
2944
  }
2844
2945
  else if (elementType === BSON_DATA_BINARY) {
2845
- let binarySize = buffer[index++] |
2846
- (buffer[index++] << 8) |
2847
- (buffer[index++] << 16) |
2848
- (buffer[index++] << 24);
2946
+ let binarySize = NumberUtils.getInt32LE(buffer, index);
2947
+ index += 4;
2849
2948
  const totalBinarySize = binarySize;
2850
2949
  const subType = buffer[index++];
2851
2950
  if (binarySize < 0)
@@ -2854,11 +2953,8 @@ function deserializeObject(buffer, index, options, isArray = false) {
2854
2953
  throw new BSONError('Binary type size larger than document size');
2855
2954
  if (buffer['slice'] != null) {
2856
2955
  if (subType === Binary.SUBTYPE_BYTE_ARRAY) {
2857
- binarySize =
2858
- buffer[index++] |
2859
- (buffer[index++] << 8) |
2860
- (buffer[index++] << 16) |
2861
- (buffer[index++] << 24);
2956
+ binarySize = NumberUtils.getInt32LE(buffer, index);
2957
+ index += 4;
2862
2958
  if (binarySize < 0)
2863
2959
  throw new BSONError('Negative binary type element size found for subtype 0x02');
2864
2960
  if (binarySize > totalBinarySize - 4)
@@ -2877,13 +2973,9 @@ function deserializeObject(buffer, index, options, isArray = false) {
2877
2973
  }
2878
2974
  }
2879
2975
  else {
2880
- const _buffer = ByteUtils.allocate(binarySize);
2881
2976
  if (subType === Binary.SUBTYPE_BYTE_ARRAY) {
2882
- binarySize =
2883
- buffer[index++] |
2884
- (buffer[index++] << 8) |
2885
- (buffer[index++] << 16) |
2886
- (buffer[index++] << 24);
2977
+ binarySize = NumberUtils.getInt32LE(buffer, index);
2978
+ index += 4;
2887
2979
  if (binarySize < 0)
2888
2980
  throw new BSONError('Negative binary type element size found for subtype 0x02');
2889
2981
  if (binarySize > totalBinarySize - 4)
@@ -2891,11 +2983,11 @@ function deserializeObject(buffer, index, options, isArray = false) {
2891
2983
  if (binarySize < totalBinarySize - 4)
2892
2984
  throw new BSONError('Binary type with subtype 0x02 contains too short binary size');
2893
2985
  }
2894
- for (i = 0; i < binarySize; i++) {
2895
- _buffer[i] = buffer[index + i];
2896
- }
2897
2986
  if (promoteBuffers && promoteValues) {
2898
- value = _buffer;
2987
+ value = ByteUtils.allocateUnsafe(binarySize);
2988
+ for (i = 0; i < binarySize; i++) {
2989
+ value[i] = buffer[index + i];
2990
+ }
2899
2991
  }
2900
2992
  else {
2901
2993
  value = new Binary(buffer.slice(index, index + binarySize), subType);
@@ -2959,10 +3051,8 @@ function deserializeObject(buffer, index, options, isArray = false) {
2959
3051
  value = new BSONRegExp(source, regExpOptions);
2960
3052
  }
2961
3053
  else if (elementType === BSON_DATA_SYMBOL) {
2962
- const stringSize = buffer[index++] |
2963
- (buffer[index++] << 8) |
2964
- (buffer[index++] << 16) |
2965
- (buffer[index++] << 24);
3054
+ const stringSize = NumberUtils.getInt32LE(buffer, index);
3055
+ index += 4;
2966
3056
  if (stringSize <= 0 ||
2967
3057
  stringSize > buffer.length - index ||
2968
3058
  buffer[index + stringSize - 1] !== 0) {
@@ -2973,15 +3063,11 @@ function deserializeObject(buffer, index, options, isArray = false) {
2973
3063
  index = index + stringSize;
2974
3064
  }
2975
3065
  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 });
3066
+ value = new Timestamp({
3067
+ i: NumberUtils.getUint32LE(buffer, index),
3068
+ t: NumberUtils.getUint32LE(buffer, index + 4)
3069
+ });
3070
+ index += 8;
2985
3071
  }
2986
3072
  else if (elementType === BSON_DATA_MIN_KEY) {
2987
3073
  value = new MinKey();
@@ -2990,10 +3076,8 @@ function deserializeObject(buffer, index, options, isArray = false) {
2990
3076
  value = new MaxKey();
2991
3077
  }
2992
3078
  else if (elementType === BSON_DATA_CODE) {
2993
- const stringSize = buffer[index++] |
2994
- (buffer[index++] << 8) |
2995
- (buffer[index++] << 16) |
2996
- (buffer[index++] << 24);
3079
+ const stringSize = NumberUtils.getInt32LE(buffer, index);
3080
+ index += 4;
2997
3081
  if (stringSize <= 0 ||
2998
3082
  stringSize > buffer.length - index ||
2999
3083
  buffer[index + stringSize - 1] !== 0) {
@@ -3004,17 +3088,13 @@ function deserializeObject(buffer, index, options, isArray = false) {
3004
3088
  index = index + stringSize;
3005
3089
  }
3006
3090
  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);
3091
+ const totalSize = NumberUtils.getInt32LE(buffer, index);
3092
+ index += 4;
3011
3093
  if (totalSize < 4 + 4 + 4 + 1) {
3012
3094
  throw new BSONError('code_w_scope total size shorter minimum expected length');
3013
3095
  }
3014
- const stringSize = buffer[index++] |
3015
- (buffer[index++] << 8) |
3016
- (buffer[index++] << 16) |
3017
- (buffer[index++] << 24);
3096
+ const stringSize = NumberUtils.getInt32LE(buffer, index);
3097
+ index += 4;
3018
3098
  if (stringSize <= 0 ||
3019
3099
  stringSize > buffer.length - index ||
3020
3100
  buffer[index + stringSize - 1] !== 0) {
@@ -3023,10 +3103,7 @@ function deserializeObject(buffer, index, options, isArray = false) {
3023
3103
  const functionString = ByteUtils.toUTF8(buffer, index, index + stringSize - 1, shouldValidateKey);
3024
3104
  index = index + stringSize;
3025
3105
  const _index = index;
3026
- const objectSize = buffer[index] |
3027
- (buffer[index + 1] << 8) |
3028
- (buffer[index + 2] << 16) |
3029
- (buffer[index + 3] << 24);
3106
+ const objectSize = NumberUtils.getInt32LE(buffer, index);
3030
3107
  const scopeObject = deserializeObject(buffer, _index, options, false);
3031
3108
  index = index + objectSize;
3032
3109
  if (totalSize < 4 + 4 + objectSize + stringSize) {
@@ -3038,10 +3115,8 @@ function deserializeObject(buffer, index, options, isArray = false) {
3038
3115
  value = new Code(functionString, scopeObject);
3039
3116
  }
3040
3117
  else if (elementType === BSON_DATA_DBPOINTER) {
3041
- const stringSize = buffer[index++] |
3042
- (buffer[index++] << 8) |
3043
- (buffer[index++] << 16) |
3044
- (buffer[index++] << 24);
3118
+ const stringSize = NumberUtils.getInt32LE(buffer, index);
3119
+ index += 4;
3045
3120
  if (stringSize <= 0 ||
3046
3121
  stringSize > buffer.length - index ||
3047
3122
  buffer[index + stringSize - 1] !== 0)
@@ -3053,8 +3128,9 @@ function deserializeObject(buffer, index, options, isArray = false) {
3053
3128
  }
3054
3129
  const namespace = ByteUtils.toUTF8(buffer, index, index + stringSize - 1, false);
3055
3130
  index = index + stringSize;
3056
- const oidBuffer = ByteUtils.allocate(12);
3057
- oidBuffer.set(buffer.subarray(index, index + 12), 0);
3131
+ const oidBuffer = ByteUtils.allocateUnsafe(12);
3132
+ for (let i = 0; i < 12; i++)
3133
+ oidBuffer[i] = buffer[index + i];
3058
3134
  const oid = new ObjectId(oidBuffer);
3059
3135
  index = index + 12;
3060
3136
  value = new DBRef(namespace, oid);
@@ -3099,17 +3175,11 @@ function serializeString(buffer, key, value, index) {
3099
3175
  index = index + numberOfWrittenBytes + 1;
3100
3176
  buffer[index - 1] = 0;
3101
3177
  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;
3178
+ NumberUtils.setInt32LE(buffer, index, size + 1);
3106
3179
  index = index + 4 + size;
3107
3180
  buffer[index++] = 0;
3108
3181
  return index;
3109
3182
  }
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
3183
  function serializeNumber(buffer, key, value, index) {
3114
3184
  const isNegativeZero = Object.is(value, -0);
3115
3185
  const type = !isNegativeZero &&
@@ -3118,19 +3188,16 @@ function serializeNumber(buffer, key, value, index) {
3118
3188
  value >= BSON_INT32_MIN
3119
3189
  ? BSON_DATA_INT
3120
3190
  : 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
3191
  buffer[index++] = type;
3129
3192
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3130
3193
  index = index + numberOfWrittenBytes;
3131
3194
  buffer[index++] = 0x00;
3132
- buffer.set(bytes, index);
3133
- index += bytes.byteLength;
3195
+ if (type === BSON_DATA_INT) {
3196
+ index += NumberUtils.setInt32LE(buffer, index, value);
3197
+ }
3198
+ else {
3199
+ index += NumberUtils.setFloat64LE(buffer, index, value);
3200
+ }
3134
3201
  return index;
3135
3202
  }
3136
3203
  function serializeBigInt(buffer, key, value, index) {
@@ -3138,9 +3205,7 @@ function serializeBigInt(buffer, key, value, index) {
3138
3205
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3139
3206
  index += numberOfWrittenBytes;
3140
3207
  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;
3208
+ index += NumberUtils.setBigInt64LE(buffer, index, value);
3144
3209
  return index;
3145
3210
  }
3146
3211
  function serializeNull(buffer, key, _, index) {
@@ -3166,14 +3231,8 @@ function serializeDate(buffer, key, value, index) {
3166
3231
  const dateInMilis = Long.fromNumber(value.getTime());
3167
3232
  const lowBits = dateInMilis.getLowBits();
3168
3233
  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;
3234
+ index += NumberUtils.setInt32LE(buffer, index, lowBits);
3235
+ index += NumberUtils.setInt32LE(buffer, index, highBits);
3177
3236
  return index;
3178
3237
  }
3179
3238
  function serializeRegExp(buffer, key, value, index) {
@@ -3230,15 +3289,7 @@ function serializeObjectId(buffer, key, value, index) {
3230
3289
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3231
3290
  index = index + numberOfWrittenBytes;
3232
3291
  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
- }
3292
+ index += value.serializeInto(buffer, index);
3242
3293
  return index;
3243
3294
  }
3244
3295
  function serializeBuffer(buffer, key, value, index) {
@@ -3247,12 +3298,15 @@ function serializeBuffer(buffer, key, value, index) {
3247
3298
  index = index + numberOfWrittenBytes;
3248
3299
  buffer[index++] = 0;
3249
3300
  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;
3301
+ index += NumberUtils.setInt32LE(buffer, index, size);
3254
3302
  buffer[index++] = BSON_BINARY_SUBTYPE_DEFAULT;
3255
- buffer.set(value, index);
3303
+ if (size <= 16) {
3304
+ for (let i = 0; i < size; i++)
3305
+ buffer[index + i] = value[i];
3306
+ }
3307
+ else {
3308
+ buffer.set(value, index);
3309
+ }
3256
3310
  index = index + size;
3257
3311
  return index;
3258
3312
  }
@@ -3274,7 +3328,8 @@ function serializeDecimal128(buffer, key, value, index) {
3274
3328
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3275
3329
  index = index + numberOfWrittenBytes;
3276
3330
  buffer[index++] = 0;
3277
- buffer.set(value.bytes.subarray(0, 16), index);
3331
+ for (let i = 0; i < 16; i++)
3332
+ buffer[index + i] = value.bytes[i];
3278
3333
  return index + 16;
3279
3334
  }
3280
3335
  function serializeLong(buffer, key, value, index) {
@@ -3285,14 +3340,8 @@ function serializeLong(buffer, key, value, index) {
3285
3340
  buffer[index++] = 0;
3286
3341
  const lowBits = value.getLowBits();
3287
3342
  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;
3343
+ index += NumberUtils.setInt32LE(buffer, index, lowBits);
3344
+ index += NumberUtils.setInt32LE(buffer, index, highBits);
3296
3345
  return index;
3297
3346
  }
3298
3347
  function serializeInt32(buffer, key, value, index) {
@@ -3301,10 +3350,7 @@ function serializeInt32(buffer, key, value, index) {
3301
3350
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3302
3351
  index = index + numberOfWrittenBytes;
3303
3352
  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;
3353
+ index += NumberUtils.setInt32LE(buffer, index, value);
3308
3354
  return index;
3309
3355
  }
3310
3356
  function serializeDouble(buffer, key, value, index) {
@@ -3312,9 +3358,7 @@ function serializeDouble(buffer, key, value, index) {
3312
3358
  const numberOfWrittenBytes = ByteUtils.encodeUTF8Into(buffer, key, index);
3313
3359
  index = index + numberOfWrittenBytes;
3314
3360
  buffer[index++] = 0;
3315
- NUMBER_SPACE.setFloat64(0, value.value, true);
3316
- buffer.set(EIGHT_BYTE_VIEW_ON_NUMBER, index);
3317
- index = index + 8;
3361
+ index += NumberUtils.setFloat64LE(buffer, index, value.value);
3318
3362
  return index;
3319
3363
  }
3320
3364
  function serializeFunction(buffer, key, value, index) {
@@ -3324,10 +3368,7 @@ function serializeFunction(buffer, key, value, index) {
3324
3368
  buffer[index++] = 0;
3325
3369
  const functionString = value.toString();
3326
3370
  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;
3371
+ NumberUtils.setInt32LE(buffer, index, size);
3331
3372
  index = index + 4 + size - 1;
3332
3373
  buffer[index++] = 0;
3333
3374
  return index;
@@ -3342,19 +3383,13 @@ function serializeCode(buffer, key, value, index, checkKeys = false, depth = 0,
3342
3383
  const functionString = value.code;
3343
3384
  index = index + 4;
3344
3385
  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;
3386
+ NumberUtils.setInt32LE(buffer, index, codeSize);
3349
3387
  buffer[index + 4 + codeSize - 1] = 0;
3350
3388
  index = index + codeSize + 4;
3351
3389
  const endIndex = serializeInto(buffer, value.scope, checkKeys, index, depth + 1, serializeFunctions, ignoreUndefined, path);
3352
3390
  index = endIndex - 1;
3353
3391
  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;
3392
+ startIndex += NumberUtils.setInt32LE(buffer, startIndex, totalSize);
3358
3393
  buffer[index++] = 0;
3359
3394
  }
3360
3395
  else {
@@ -3364,10 +3399,7 @@ function serializeCode(buffer, key, value, index, checkKeys = false, depth = 0,
3364
3399
  buffer[index++] = 0;
3365
3400
  const functionString = value.code.toString();
3366
3401
  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;
3402
+ NumberUtils.setInt32LE(buffer, index, size);
3371
3403
  index = index + 4 + size - 1;
3372
3404
  buffer[index++] = 0;
3373
3405
  }
@@ -3382,19 +3414,19 @@ function serializeBinary(buffer, key, value, index) {
3382
3414
  let size = value.position;
3383
3415
  if (value.sub_type === Binary.SUBTYPE_BYTE_ARRAY)
3384
3416
  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;
3417
+ index += NumberUtils.setInt32LE(buffer, index, size);
3389
3418
  buffer[index++] = value.sub_type;
3390
3419
  if (value.sub_type === Binary.SUBTYPE_BYTE_ARRAY) {
3391
3420
  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;
3421
+ index += NumberUtils.setInt32LE(buffer, index, size);
3422
+ }
3423
+ if (size <= 16) {
3424
+ for (let i = 0; i < size; i++)
3425
+ buffer[index + i] = data[i];
3426
+ }
3427
+ else {
3428
+ buffer.set(data, index);
3396
3429
  }
3397
- buffer.set(data, index);
3398
3430
  index = index + value.position;
3399
3431
  return index;
3400
3432
  }
@@ -3404,12 +3436,9 @@ function serializeSymbol(buffer, key, value, index) {
3404
3436
  index = index + numberOfWrittenBytes;
3405
3437
  buffer[index++] = 0;
3406
3438
  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;
3439
+ NumberUtils.setInt32LE(buffer, index, size);
3411
3440
  index = index + 4 + size - 1;
3412
- buffer[index++] = 0x00;
3441
+ buffer[index++] = 0;
3413
3442
  return index;
3414
3443
  }
3415
3444
  function serializeDBRef(buffer, key, value, index, depth, serializeFunctions, path) {
@@ -3428,10 +3457,7 @@ function serializeDBRef(buffer, key, value, index, depth, serializeFunctions, pa
3428
3457
  output = Object.assign(output, value.fields);
3429
3458
  const endIndex = serializeInto(buffer, output, false, index, depth + 1, serializeFunctions, true, path);
3430
3459
  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;
3460
+ startIndex += NumberUtils.setInt32LE(buffer, index, size);
3435
3461
  return endIndex;
3436
3462
  }
3437
3463
  function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializeFunctions, ignoreUndefined, path) {
@@ -3567,7 +3593,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3567
3593
  if ('$' === key[0]) {
3568
3594
  throw new BSONError('key ' + key + " must not start with '$'");
3569
3595
  }
3570
- else if (~key.indexOf('.')) {
3596
+ else if (key.includes('.')) {
3571
3597
  throw new BSONError('key ' + key + " must not contain '.'");
3572
3598
  }
3573
3599
  }
@@ -3665,7 +3691,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3665
3691
  if ('$' === key[0]) {
3666
3692
  throw new BSONError('key ' + key + " must not start with '$'");
3667
3693
  }
3668
- else if (~key.indexOf('.')) {
3694
+ else if (key.includes('.')) {
3669
3695
  throw new BSONError('key ' + key + " must not contain '.'");
3670
3696
  }
3671
3697
  }
@@ -3749,10 +3775,7 @@ function serializeInto(buffer, object, checkKeys, startingIndex, depth, serializ
3749
3775
  path.delete(object);
3750
3776
  buffer[index++] = 0x00;
3751
3777
  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;
3778
+ startingIndex += NumberUtils.setInt32LE(buffer, startingIndex, size);
3756
3779
  return index;
3757
3780
  }
3758
3781
 
@@ -4082,7 +4105,7 @@ function serialize(object, options = {}) {
4082
4105
  buffer = ByteUtils.allocate(minInternalBufferSize);
4083
4106
  }
4084
4107
  const serializationIndex = serializeInto(buffer, object, checkKeys, 0, 0, serializeFunctions, ignoreUndefined, null);
4085
- const finishedBuffer = ByteUtils.allocate(serializationIndex);
4108
+ const finishedBuffer = ByteUtils.allocateUnsafe(serializationIndex);
4086
4109
  finishedBuffer.set(buffer.subarray(0, serializationIndex), 0);
4087
4110
  return finishedBuffer;
4088
4111
  }
@@ -4109,10 +4132,7 @@ function deserializeStream(data, startIndex, numberOfDocuments, documents, docSt
4109
4132
  const bufferData = ByteUtils.toLocalBufferType(data);
4110
4133
  let index = startIndex;
4111
4134
  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);
4135
+ const size = NumberUtils.getInt32LE(bufferData, index);
4116
4136
  internalOptions.index = index;
4117
4137
  documents[docStartIndex + i] = internalDeserialize(bufferData, internalOptions);
4118
4138
  index = index + size;