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