cbor-x 1.5.9 → 1.6.3
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/README.md +20 -7
- package/decode.d.ts +1 -1
- package/decode.js +51 -7
- package/dist/decode-no-eval.cjs +49 -7
- package/dist/decode-no-eval.cjs.map +1 -1
- package/dist/index-no-eval.cjs +74 -13
- package/dist/index-no-eval.cjs.map +1 -1
- package/dist/index-no-eval.min.js +1 -1
- package/dist/index-no-eval.min.js.map +1 -1
- package/dist/index.js +74 -13
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/node.cjs +75 -13
- package/dist/node.cjs.map +1 -1
- package/dist/test.js +102 -20
- package/dist/test.js.map +1 -1
- package/encode.js +26 -6
- package/index.d.ts +6 -1
- package/index.js +1 -1
- package/node-index.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ This `encode` function will generate standard CBOR without any extensions that s
|
|
|
29
29
|
Cbor-x modules are standard ESM modules and can be loaded directly from the [deno.land registry for cbor](https://deno.land/x/cbor) for use in Deno. The standard encode and decode functionality is available on Deno, like other platforms.
|
|
30
30
|
|
|
31
31
|
### Streams
|
|
32
|
-
We can use the including streaming functionality (which further improves performance). The `EncoderStream` is a NodeJS transform stream that can be used to serialize objects to a binary stream (writing to network/socket, IPC, etc.), and the `DecoderStream` can be used to deserialize objects from a binary
|
|
32
|
+
We can use the including streaming functionality (which further improves performance). The `EncoderStream` is a NodeJS transform stream that can be used to serialize objects to a binary stream (writing to network/socket, IPC, etc.), and the `DecoderStream` can be used to deserialize objects from a binary stream (reading from network/socket, etc.):
|
|
33
33
|
|
|
34
34
|
```JavaScript
|
|
35
35
|
import { EncoderStream } from 'cbor-x';
|
|
@@ -89,23 +89,22 @@ import { decode } from 'cbor-x/decode' // if you only need to decode
|
|
|
89
89
|
```
|
|
90
90
|
|
|
91
91
|
## Structured Cloning
|
|
92
|
-
You can also use cbor-x for [structured cloning](https://html.spec.whatwg.org/multipage/structured-data.html). By enabling the `structuredClone` option, you can include references to other objects or cyclic references, and object identity will be preserved.
|
|
92
|
+
You can also use cbor-x for [structured cloning](https://html.spec.whatwg.org/multipage/structured-data.html). By enabling the `structuredClone` option, you can include references to other objects or cyclic references, and object identity will be preserved.For example:
|
|
93
93
|
```JavaScript
|
|
94
94
|
let obj = {
|
|
95
|
-
set: new Set(['a', 'b']),
|
|
96
|
-
regular: /a\spattern/
|
|
97
95
|
};
|
|
98
96
|
obj.self = obj;
|
|
99
97
|
let encoder = new Encoder({ structuredClone: true });
|
|
100
98
|
let serialized = encoder.encode(obj);
|
|
101
99
|
let copy = encoder.decode(serialized);
|
|
102
100
|
copy.self === copy // true
|
|
103
|
-
copy.set.has('a') // true
|
|
104
101
|
|
|
105
102
|
```
|
|
106
103
|
|
|
107
104
|
This option is disabled by default because reference checking degrades performance (by about 25-30%). (Note this implementation doesn't serialize every class/type specified in the HTML specification since not all of them make sense for storing across platforms.)
|
|
108
105
|
|
|
106
|
+
cbor-x also preserves certain typed objects like `Error`, `Set`, `RegExp` and TypedArray instances, using [registered CBOR tag extensions](https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml). This works with or without structured cloning enabled.
|
|
107
|
+
|
|
109
108
|
## Record / Object Structures
|
|
110
109
|
There is a critical difference between maps (or dictionaries) that hold an arbitrary set of keys and values (JavaScript `Map` is designed for these), and records or object structures that have a well-defined set of fields. Typical JS objects/records may have many instances re(use) the same structure. By using the record extension, this distinction is preserved in CBOR and the encoding can reuse structures and not only provides better type preservation, but yield much more compact encodings and increase decoding performance by 2-3x. Cbor-x automatically generates record definitions that are reused and referenced by objects with the same structure. Records use CBOR's tags to align well CBOR's tag/extension mechanism. There are a number of ways to use this to our advantage. For large object structures with repeating nested objects with similar structures, simply serializing with the record extension can yield significant benefits. To use the record structures extension, we create a new `Encoder` instance. By default a new `Encoder` instance will have the record extension enabled:
|
|
111
110
|
```JavaScript
|
|
@@ -166,7 +165,7 @@ The principle driver for this feature is to support `application/senml+cbor`cont
|
|
|
166
165
|
Records are also supported in conjunction with keyMaps, but these are disabled by default when keyMaps are specified as use of the two features does not introduce any additional compression efficiency unless that the data arrays are quite large (> 10 items).
|
|
167
166
|
|
|
168
167
|
```JavaScript
|
|
169
|
-
import { Encoder } from 'cbor-x'
|
|
168
|
+
import { Decoder, Encoder } from 'cbor-x'
|
|
170
169
|
const data = [
|
|
171
170
|
{ bn: '/3303/0/5700', bt: 1278887, v: 35.5 },
|
|
172
171
|
{ t: 10, v: 34 },
|
|
@@ -183,7 +182,8 @@ let senmlBuff = senmlCbor.encode(data)
|
|
|
183
182
|
let basicBuff = basicCbor.encode(data)
|
|
184
183
|
console.log('Senml CBOR size:', senmlBuff.length) // 77
|
|
185
184
|
console.log('Basic CBOR size:', basicBuff.length) // 90
|
|
186
|
-
|
|
185
|
+
let senmlDecoder = new Decoder({ keyMap: senmlKeys });
|
|
186
|
+
assert.deepEqual(senmlDecoder.decode(senmlBuff), data)
|
|
187
187
|
|
|
188
188
|
```
|
|
189
189
|
|
|
@@ -213,6 +213,7 @@ The following options properties can be provided to the Encoder or Decoder const
|
|
|
213
213
|
* `useTag259ForMaps` - This flag indicates if [tag 259 (explicit maps)](https://github.com/shanewholloway/js-cbor-codec/blob/master/docs/CBOR-259-spec--explicit-maps.md) should be used to encode JS `Map`s. When using records is enabled, this is disabled by default, since plain objects are encoded with record structures and unambigiously differentiated from `Map`s, which are encoded as CBOR maps. Without using records, this enabled by default and is necessary to distinguish plain objects from `Map`s (but can be disabled by setting this to `false`).
|
|
214
214
|
* `tagUint8Array` - Indicates if tag 64 should be used for `Uint8Array`s.
|
|
215
215
|
* `int64AsNumber` - This will decode uint64 and int64 numbers as standard JS numbers rather than as bigint numbers.
|
|
216
|
+
* `skipFunction` - This skip functions in encode object.
|
|
216
217
|
|
|
217
218
|
### 32-bit Float Options
|
|
218
219
|
By default all non-integer numbers are serialized as 64-bit float (double). This is fast, and ensures maximum precision. However, often real-world data doesn't not need 64-bits of precision, and using 32-bit encoding can be much more space efficient. There are several options that provide more efficient encodings. Using the decimal rounding options for encoding and decoding provides lossless storage of common decimal representations like 7.99, in more efficient 32-bit format (rather than 64-bit). The `useFloat32` property has several possible options, available from the module as constants:
|
|
@@ -228,6 +229,18 @@ Note, that the performance is decreased with decimal rounding by about 20-25%, a
|
|
|
228
229
|
|
|
229
230
|
In addition, msgpackr exports a `roundFloat32(number)` function that can be used to round floating point numbers to the maximum significant decimal digits that can be stored in 32-bit float, just as DECIMAL_ROUND does when decoding. This can be useful for determining how a number will be decoded prior to encoding it.
|
|
230
231
|
|
|
232
|
+
### Setting Size Limits
|
|
233
|
+
You can set size limits on objects, arrays, and maps to prevent resource exhaustion when decoding. This can be done by calling the setMaxLimits export. Each of the properties are optional (only provide
|
|
234
|
+
the properties you want to change), for example (with the defaults):
|
|
235
|
+
```JavaScript
|
|
236
|
+
import { setMaxLimits } from 'cbor-x';
|
|
237
|
+
setMaxLimits({
|
|
238
|
+
maxArraySize: 112810000,
|
|
239
|
+
maxMapSize: 16810000,
|
|
240
|
+
maxObjectSize : 16710000
|
|
241
|
+
});
|
|
242
|
+
```
|
|
243
|
+
|
|
231
244
|
## Performance
|
|
232
245
|
Cbor-x is fast. Really fast. Here is comparison with the next fastest JS projects using the benchmark tool from `msgpack-lite` (and the sample data is from some clinical research data we use that has a good mix of different value types and structures). It also includes comparison to V8 native JSON functionality, and JavaScript Avro (`avsc`, a very optimized Avro implementation):
|
|
233
246
|
|
package/decode.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { decode, decodeMultiple, Decoder, addExtension, clearSource,roundFloat32, isNativeAccelerationEnabled,
|
|
2
|
-
Extension, Options, FLOAT32_OPTIONS} from '.'
|
|
2
|
+
Extension, Options, FLOAT32_OPTIONS, setMaxLimits, MAX_LIMITS_OPTIONS } from '.'
|
package/decode.js
CHANGED
|
@@ -14,6 +14,13 @@ const BUNDLED_STRINGS_ID = 0xdff9
|
|
|
14
14
|
const PACKED_TABLE_TAG_ID = 51
|
|
15
15
|
const PACKED_REFERENCE_TAG_ID = 6
|
|
16
16
|
const STOP_CODE = {}
|
|
17
|
+
let maxArraySize = 112810000 // This is the maximum array size in V8. We would potentially detect and set it higher
|
|
18
|
+
// for JSC, but this is pretty large and should be sufficient for most use cases
|
|
19
|
+
let maxMapSize = 16810000 // JavaScript has a fixed maximum map size of about 16710000, but JS itself enforces this,
|
|
20
|
+
// so we don't need to
|
|
21
|
+
|
|
22
|
+
let maxObjectSize = 16710000; // This is the maximum number of keys in a Map. It takes over a minute to create this
|
|
23
|
+
// many keys in an object, so also probably a reasonable choice there.
|
|
17
24
|
let strings = EMPTY_ARRAY
|
|
18
25
|
let stringPosition = 0
|
|
19
26
|
let currentDecoder = {}
|
|
@@ -266,6 +273,7 @@ export function read() {
|
|
|
266
273
|
}
|
|
267
274
|
token = dataView.getUint32(position)
|
|
268
275
|
position += 4
|
|
276
|
+
if (majorType === 1) return -1 - token; // can't safely use negation operator here
|
|
269
277
|
break
|
|
270
278
|
case 0x1b:
|
|
271
279
|
if (majorType == 7) {
|
|
@@ -280,8 +288,7 @@ export function read() {
|
|
|
280
288
|
} else if (currentDecoder.int64AsNumber) {
|
|
281
289
|
token = dataView.getUint32(position) * 0x100000000
|
|
282
290
|
token += dataView.getUint32(position + 4)
|
|
283
|
-
} else
|
|
284
|
-
token = dataView.getBigUint64(position)
|
|
291
|
+
} else token = dataView.getBigUint64(position)
|
|
285
292
|
position += 8
|
|
286
293
|
break
|
|
287
294
|
case 0x1f:
|
|
@@ -294,6 +301,7 @@ export function read() {
|
|
|
294
301
|
let array = []
|
|
295
302
|
let value, i = 0
|
|
296
303
|
while ((value = read()) != STOP_CODE) {
|
|
304
|
+
if (i >= maxArraySize) throw new Error(`Array length exceeds ${maxArraySize}`)
|
|
297
305
|
array[i++] = value
|
|
298
306
|
}
|
|
299
307
|
return majorType == 4 ? array : majorType == 3 ? array.join('') : Buffer.concat(array)
|
|
@@ -301,8 +309,19 @@ export function read() {
|
|
|
301
309
|
let key
|
|
302
310
|
if (currentDecoder.mapsAsObjects) {
|
|
303
311
|
let object = {}
|
|
304
|
-
|
|
305
|
-
|
|
312
|
+
let i = 0;
|
|
313
|
+
if (currentDecoder.keyMap) {
|
|
314
|
+
while((key = read()) != STOP_CODE) {
|
|
315
|
+
if (i++ >= maxMapSize) throw new Error(`Property count exceeds ${maxMapSize}`)
|
|
316
|
+
object[safeKey(currentDecoder.decodeKey(key))] = read()
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
320
|
+
while ((key = read()) != STOP_CODE) {
|
|
321
|
+
if (i++ >= maxMapSize) throw new Error(`Property count exceeds ${maxMapSize}`)
|
|
322
|
+
object[safeKey(key)] = read()
|
|
323
|
+
}
|
|
324
|
+
}
|
|
306
325
|
return object
|
|
307
326
|
} else {
|
|
308
327
|
if (restoreMapsAsObject) {
|
|
@@ -310,8 +329,24 @@ export function read() {
|
|
|
310
329
|
restoreMapsAsObject = false
|
|
311
330
|
}
|
|
312
331
|
let map = new Map()
|
|
313
|
-
if (currentDecoder.keyMap)
|
|
314
|
-
|
|
332
|
+
if (currentDecoder.keyMap) {
|
|
333
|
+
let i = 0;
|
|
334
|
+
while((key = read()) != STOP_CODE) {
|
|
335
|
+
if (i++ >= maxMapSize) {
|
|
336
|
+
throw new Error(`Map size exceeds ${maxMapSize}`);
|
|
337
|
+
}
|
|
338
|
+
map.set(currentDecoder.decodeKey(key), read())
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
else {
|
|
342
|
+
let i = 0;
|
|
343
|
+
while ((key = read()) != STOP_CODE) {
|
|
344
|
+
if (i++ >= maxMapSize) {
|
|
345
|
+
throw new Error(`Map size exceeds ${maxMapSize}`);
|
|
346
|
+
}
|
|
347
|
+
map.set(key, read())
|
|
348
|
+
}
|
|
349
|
+
}
|
|
315
350
|
return map
|
|
316
351
|
}
|
|
317
352
|
case 7:
|
|
@@ -342,12 +377,14 @@ export function read() {
|
|
|
342
377
|
}
|
|
343
378
|
return readFixedString(token)
|
|
344
379
|
case 4: // array
|
|
380
|
+
if (token >= maxArraySize) throw new Error(`Array length exceeds ${maxArraySize}`)
|
|
345
381
|
let array = new Array(token)
|
|
346
382
|
//if (currentDecoder.keyMap) for (let i = 0; i < token; i++) array[i] = currentDecoder.decodeKey(read())
|
|
347
383
|
//else
|
|
348
384
|
for (let i = 0; i < token; i++) array[i] = read()
|
|
349
385
|
return array
|
|
350
386
|
case 5: // map
|
|
387
|
+
if (token >= maxMapSize) throw new Error(`Map size exceeds ${maxArraySize}`)
|
|
351
388
|
if (currentDecoder.mapsAsObjects) {
|
|
352
389
|
let object = {}
|
|
353
390
|
if (currentDecoder.keyMap) for (let i = 0; i < token; i++) object[safeKey(currentDecoder.decodeKey(read()))] = read()
|
|
@@ -449,6 +486,7 @@ export function read() {
|
|
|
449
486
|
}
|
|
450
487
|
const validName = /^[a-zA-Z_$][a-zA-Z\d_$]*$/
|
|
451
488
|
function createStructureReader(structure) {
|
|
489
|
+
if (!structure) throw new Error('Structure is required in record definition');
|
|
452
490
|
function readObject() {
|
|
453
491
|
// get the array size from the header
|
|
454
492
|
let length = src[position++]
|
|
@@ -886,7 +924,7 @@ currentExtensions[2] = (buffer) => {
|
|
|
886
924
|
// bigint extension
|
|
887
925
|
let value = BigInt(0)
|
|
888
926
|
for (let i = 0, l = buffer.byteLength; i < l; i++) {
|
|
889
|
-
value = BigInt(buffer[i]) + value << BigInt(8)
|
|
927
|
+
value = BigInt(buffer[i]) + (value << BigInt(8))
|
|
890
928
|
}
|
|
891
929
|
return value
|
|
892
930
|
}
|
|
@@ -1236,6 +1274,12 @@ export function addExtension(extension) {
|
|
|
1236
1274
|
currentExtensions[extension.tag] = extension.decode
|
|
1237
1275
|
}
|
|
1238
1276
|
|
|
1277
|
+
export function setSizeLimits(limits) {
|
|
1278
|
+
if (limits.maxMapSize) maxMapSize = limits.maxMapSize;
|
|
1279
|
+
if (limits.maxArraySize) maxArraySize = limits.maxArraySize;
|
|
1280
|
+
if (limits.maxObjectSize) maxObjectSize = limits.maxObjectSize;
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1239
1283
|
export const mult10 = new Array(147) // this is a table matching binary exponents to the multiplier to determine significant digit rounding
|
|
1240
1284
|
for (let i = 0; i < 256; i++) {
|
|
1241
1285
|
mult10[i] = +('1e' + Math.floor(45.15 - i * 0.30103))
|
package/dist/decode-no-eval.cjs
CHANGED
|
@@ -18,6 +18,10 @@
|
|
|
18
18
|
const BUNDLED_STRINGS_ID = 0xdff9;
|
|
19
19
|
const PACKED_REFERENCE_TAG_ID = 6;
|
|
20
20
|
const STOP_CODE = {};
|
|
21
|
+
let maxArraySize = 112810000; // This is the maximum array size in V8. We would potentially detect and set it higher
|
|
22
|
+
// for JSC, but this is pretty large and should be sufficient for most use cases
|
|
23
|
+
let maxMapSize = 16810000; // JavaScript has a fixed maximum map size of about 16710000, but JS itself enforces this,
|
|
24
|
+
// many keys in an object, so also probably a reasonable choice there.
|
|
21
25
|
let strings = EMPTY_ARRAY;
|
|
22
26
|
let stringPosition = 0;
|
|
23
27
|
let currentDecoder = {};
|
|
@@ -270,6 +274,7 @@
|
|
|
270
274
|
}
|
|
271
275
|
token = dataView.getUint32(position);
|
|
272
276
|
position += 4;
|
|
277
|
+
if (majorType === 1) return -1 - token; // can't safely use negation operator here
|
|
273
278
|
break
|
|
274
279
|
case 0x1b:
|
|
275
280
|
if (majorType == 7) {
|
|
@@ -284,8 +289,7 @@
|
|
|
284
289
|
} else if (currentDecoder.int64AsNumber) {
|
|
285
290
|
token = dataView.getUint32(position) * 0x100000000;
|
|
286
291
|
token += dataView.getUint32(position + 4);
|
|
287
|
-
} else
|
|
288
|
-
token = dataView.getBigUint64(position);
|
|
292
|
+
} else token = dataView.getBigUint64(position);
|
|
289
293
|
position += 8;
|
|
290
294
|
break
|
|
291
295
|
case 0x1f:
|
|
@@ -298,6 +302,7 @@
|
|
|
298
302
|
let array = [];
|
|
299
303
|
let value, i = 0;
|
|
300
304
|
while ((value = read()) != STOP_CODE) {
|
|
305
|
+
if (i >= maxArraySize) throw new Error(`Array length exceeds ${maxArraySize}`)
|
|
301
306
|
array[i++] = value;
|
|
302
307
|
}
|
|
303
308
|
return majorType == 4 ? array : majorType == 3 ? array.join('') : Buffer.concat(array)
|
|
@@ -305,8 +310,19 @@
|
|
|
305
310
|
let key;
|
|
306
311
|
if (currentDecoder.mapsAsObjects) {
|
|
307
312
|
let object = {};
|
|
308
|
-
|
|
309
|
-
|
|
313
|
+
let i = 0;
|
|
314
|
+
if (currentDecoder.keyMap) {
|
|
315
|
+
while((key = read()) != STOP_CODE) {
|
|
316
|
+
if (i++ >= maxMapSize) throw new Error(`Property count exceeds ${maxMapSize}`)
|
|
317
|
+
object[safeKey(currentDecoder.decodeKey(key))] = read();
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
while ((key = read()) != STOP_CODE) {
|
|
322
|
+
if (i++ >= maxMapSize) throw new Error(`Property count exceeds ${maxMapSize}`)
|
|
323
|
+
object[safeKey(key)] = read();
|
|
324
|
+
}
|
|
325
|
+
}
|
|
310
326
|
return object
|
|
311
327
|
} else {
|
|
312
328
|
if (restoreMapsAsObject) {
|
|
@@ -314,8 +330,24 @@
|
|
|
314
330
|
restoreMapsAsObject = false;
|
|
315
331
|
}
|
|
316
332
|
let map = new Map();
|
|
317
|
-
if (currentDecoder.keyMap)
|
|
318
|
-
|
|
333
|
+
if (currentDecoder.keyMap) {
|
|
334
|
+
let i = 0;
|
|
335
|
+
while((key = read()) != STOP_CODE) {
|
|
336
|
+
if (i++ >= maxMapSize) {
|
|
337
|
+
throw new Error(`Map size exceeds ${maxMapSize}`);
|
|
338
|
+
}
|
|
339
|
+
map.set(currentDecoder.decodeKey(key), read());
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
let i = 0;
|
|
344
|
+
while ((key = read()) != STOP_CODE) {
|
|
345
|
+
if (i++ >= maxMapSize) {
|
|
346
|
+
throw new Error(`Map size exceeds ${maxMapSize}`);
|
|
347
|
+
}
|
|
348
|
+
map.set(key, read());
|
|
349
|
+
}
|
|
350
|
+
}
|
|
319
351
|
return map
|
|
320
352
|
}
|
|
321
353
|
case 7:
|
|
@@ -346,12 +378,14 @@
|
|
|
346
378
|
}
|
|
347
379
|
return readFixedString(token)
|
|
348
380
|
case 4: // array
|
|
381
|
+
if (token >= maxArraySize) throw new Error(`Array length exceeds ${maxArraySize}`)
|
|
349
382
|
let array = new Array(token);
|
|
350
383
|
//if (currentDecoder.keyMap) for (let i = 0; i < token; i++) array[i] = currentDecoder.decodeKey(read())
|
|
351
384
|
//else
|
|
352
385
|
for (let i = 0; i < token; i++) array[i] = read();
|
|
353
386
|
return array
|
|
354
387
|
case 5: // map
|
|
388
|
+
if (token >= maxMapSize) throw new Error(`Map size exceeds ${maxArraySize}`)
|
|
355
389
|
if (currentDecoder.mapsAsObjects) {
|
|
356
390
|
let object = {};
|
|
357
391
|
if (currentDecoder.keyMap) for (let i = 0; i < token; i++) object[safeKey(currentDecoder.decodeKey(read()))] = read();
|
|
@@ -453,6 +487,7 @@
|
|
|
453
487
|
}
|
|
454
488
|
const validName = /^[a-zA-Z_$][a-zA-Z\d_$]*$/;
|
|
455
489
|
function createStructureReader(structure) {
|
|
490
|
+
if (!structure) throw new Error('Structure is required in record definition');
|
|
456
491
|
function readObject() {
|
|
457
492
|
// get the array size from the header
|
|
458
493
|
let length = src[position++];
|
|
@@ -814,7 +849,7 @@
|
|
|
814
849
|
// bigint extension
|
|
815
850
|
let value = BigInt(0);
|
|
816
851
|
for (let i = 0, l = buffer.byteLength; i < l; i++) {
|
|
817
|
-
value = BigInt(buffer[i]) + value << BigInt(8);
|
|
852
|
+
value = BigInt(buffer[i]) + (value << BigInt(8));
|
|
818
853
|
}
|
|
819
854
|
return value
|
|
820
855
|
};
|
|
@@ -1164,6 +1199,12 @@
|
|
|
1164
1199
|
currentExtensions[extension.tag] = extension.decode;
|
|
1165
1200
|
}
|
|
1166
1201
|
|
|
1202
|
+
function setSizeLimits(limits) {
|
|
1203
|
+
if (limits.maxMapSize) maxMapSize = limits.maxMapSize;
|
|
1204
|
+
if (limits.maxArraySize) maxArraySize = limits.maxArraySize;
|
|
1205
|
+
if (limits.maxObjectSize) limits.maxObjectSize;
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1167
1208
|
const mult10 = new Array(147); // this is a table matching binary exponents to the multiplier to determine significant digit rounding
|
|
1168
1209
|
for (let i = 0; i < 256; i++) {
|
|
1169
1210
|
mult10[i] = +('1e' + Math.floor(45.15 - i * 0.30103));
|
|
@@ -1196,6 +1237,7 @@
|
|
|
1196
1237
|
exports.read = read;
|
|
1197
1238
|
exports.roundFloat32 = roundFloat32;
|
|
1198
1239
|
exports.setExtractor = setExtractor;
|
|
1240
|
+
exports.setSizeLimits = setSizeLimits;
|
|
1199
1241
|
exports.typedArrays = typedArrays;
|
|
1200
1242
|
|
|
1201
1243
|
}));
|