cbor-x 0.9.1 → 1.0.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/README.md +67 -21
- package/decode.d.ts +4 -0
- package/decode.js +323 -117
- package/dist/index.js +563 -270
- package/dist/index.min.js +101 -69
- package/dist/node.cjs +560 -265
- package/dist/test.js +62 -8
- package/encode.d.ts +1 -1
- package/encode.js +236 -89
- package/index.d.ts +1 -1
- package/index.js +2 -4
- package/node-index.js +2 -4
- package/package.json +13 -4
- package/.vscode/launch.json +0 -22
- package/dist/index.js.map +0 -1
- package/tests/benchmark-stream.cjs +0 -282
- package/tests/benchmark.cjs +0 -245
- package/tests/example.json +0 -52
- package/tests/example2.json +0 -26
- package/tests/example3.json +0 -22
- package/tests/example4.json +0 -1
- package/tests/example5.json +0 -12
- package/tests/floats.json +0 -1
- package/tests/index.html +0 -28
- package/tests/sample-large.json +0 -231
- package/tests/strings2.json +0 -1
- package/tests/test-compatibility.cjs +0 -36
- package/tests/test-incomplete.js +0 -41
- package/tests/test-node-iterators.js +0 -72
- package/tests/test-node-stream.js +0 -60
- package/tests/test.js +0 -586
package/dist/node.cjs
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
require('fs');
|
|
6
5
|
var stream = require('stream');
|
|
7
6
|
var module$1 = require('module');
|
|
8
7
|
|
|
@@ -14,7 +13,10 @@ let src;
|
|
|
14
13
|
let srcEnd;
|
|
15
14
|
let position = 0;
|
|
16
15
|
const EMPTY_ARRAY = [];
|
|
17
|
-
const
|
|
16
|
+
const LEGACY_RECORD_INLINE_ID = 105;
|
|
17
|
+
const RECORD_DEFINITIONS_ID = 0xdffe;
|
|
18
|
+
const RECORD_INLINE_ID = 0xdfff; // temporary first-come first-serve tag // proposed tag: 0x7265 // 're'
|
|
19
|
+
const BUNDLED_STRINGS_ID = 0xdff9;
|
|
18
20
|
const PACKED_REFERENCE_TAG_ID = 6;
|
|
19
21
|
const STOP_CODE = {};
|
|
20
22
|
let strings = EMPTY_ARRAY;
|
|
@@ -24,6 +26,7 @@ let currentStructures;
|
|
|
24
26
|
let srcString;
|
|
25
27
|
let srcStringStart = 0;
|
|
26
28
|
let srcStringEnd = 0;
|
|
29
|
+
let bundledStrings;
|
|
27
30
|
let referenceMap;
|
|
28
31
|
let currentExtensions = [];
|
|
29
32
|
let currentExtensionRanges = [];
|
|
@@ -39,13 +42,70 @@ let sequentialMode = false;
|
|
|
39
42
|
class Decoder {
|
|
40
43
|
constructor(options) {
|
|
41
44
|
if (options) {
|
|
45
|
+
if ((options.keyMap || options._keyMap) && !options.useRecords) {
|
|
46
|
+
options.useRecords = false;
|
|
47
|
+
options.mapsAsObjects = true;
|
|
48
|
+
}
|
|
42
49
|
if (options.useRecords === false && options.mapsAsObjects === undefined)
|
|
43
50
|
options.mapsAsObjects = true;
|
|
44
|
-
if (options.getStructures
|
|
51
|
+
if (options.getStructures)
|
|
52
|
+
options.getShared = options.getStructures;
|
|
53
|
+
if (options.getShared && !options.structures)
|
|
45
54
|
(options.structures = []).uninitialized = true; // this is what we use to denote an uninitialized structures
|
|
55
|
+
if (options.keyMap) {
|
|
56
|
+
this.mapKey = new Map();
|
|
57
|
+
for (let [k,v] of Object.entries(options.keyMap)) this.mapKey.set(v,k);
|
|
58
|
+
}
|
|
46
59
|
}
|
|
47
60
|
Object.assign(this, options);
|
|
48
61
|
}
|
|
62
|
+
/*
|
|
63
|
+
decodeKey(key) {
|
|
64
|
+
return this.keyMap
|
|
65
|
+
? Object.keys(this.keyMap)[Object.values(this.keyMap).indexOf(key)] || key
|
|
66
|
+
: key
|
|
67
|
+
}
|
|
68
|
+
*/
|
|
69
|
+
decodeKey(key) {
|
|
70
|
+
return this.keyMap ? this.mapKey.get(key) || key : key
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
encodeKey(key) {
|
|
74
|
+
return this.keyMap && this.keyMap.hasOwnProperty(key) ? this.keyMap[key] : key
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
encodeKeys(rec) {
|
|
78
|
+
if (!this._keyMap) return rec
|
|
79
|
+
let map = new Map();
|
|
80
|
+
for (let [k,v] of Object.entries(rec)) map.set((this._keyMap.hasOwnProperty(k) ? this._keyMap[k] : k), v);
|
|
81
|
+
return map
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
decodeKeys(map) {
|
|
85
|
+
if (!this._keyMap || map.constructor.name != 'Map') return map
|
|
86
|
+
if (!this._mapKey) {
|
|
87
|
+
this._mapKey = new Map();
|
|
88
|
+
for (let [k,v] of Object.entries(this._keyMap)) this._mapKey.set(v,k);
|
|
89
|
+
}
|
|
90
|
+
let res = {};
|
|
91
|
+
//map.forEach((v,k) => res[Object.keys(this._keyMap)[Object.values(this._keyMap).indexOf(k)] || k] = v)
|
|
92
|
+
map.forEach((v,k) => res[this._mapKey.has(k) ? this._mapKey.get(k) : k] = v);
|
|
93
|
+
return res
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
mapDecode(source, end) {
|
|
97
|
+
|
|
98
|
+
let res = this.decode(source);
|
|
99
|
+
if (this._keyMap) {
|
|
100
|
+
//Experiemntal support for Optimised KeyMap decoding
|
|
101
|
+
switch (res.constructor.name) {
|
|
102
|
+
case 'Array': return res.map(r => this.decodeKeys(r))
|
|
103
|
+
//case 'Map': return this.decodeKeys(res)
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return res
|
|
107
|
+
}
|
|
108
|
+
|
|
49
109
|
decode(source, end) {
|
|
50
110
|
if (src) {
|
|
51
111
|
// re-entrant execution, save the state and restore it after we do this decode
|
|
@@ -60,12 +120,21 @@ class Decoder {
|
|
|
60
120
|
srcStringEnd = 0;
|
|
61
121
|
srcString = null;
|
|
62
122
|
strings = EMPTY_ARRAY;
|
|
123
|
+
bundledStrings = null;
|
|
63
124
|
src = source;
|
|
64
125
|
// this provides cached access to the data view for a buffer if it is getting reused, which is a recommend
|
|
65
126
|
// technique for getting data from a database where it can be copied into an existing buffer instead of creating
|
|
66
127
|
// new ones
|
|
67
|
-
|
|
68
|
-
|
|
128
|
+
try {
|
|
129
|
+
dataView = source.dataView || (source.dataView = new DataView(source.buffer, source.byteOffset, source.byteLength));
|
|
130
|
+
} catch(error) {
|
|
131
|
+
// if it doesn't have a buffer, maybe it is the wrong type of object
|
|
132
|
+
src = null;
|
|
133
|
+
if (source instanceof Uint8Array)
|
|
134
|
+
throw error
|
|
135
|
+
throw new Error('Source must be a Uint8Array or Buffer but was a ' + ((source && typeof source == 'object') ? source.constructor.name : typeof source))
|
|
136
|
+
}
|
|
137
|
+
if (this instanceof Decoder) {
|
|
69
138
|
currentDecoder = this;
|
|
70
139
|
packedValues = this.sharedValues &&
|
|
71
140
|
(this.pack ? new Array(this.maxPrivatePackedValues || 16).concat(this.sharedValues) :
|
|
@@ -122,6 +191,9 @@ class Decoder {
|
|
|
122
191
|
function checkedRead() {
|
|
123
192
|
try {
|
|
124
193
|
let result = read();
|
|
194
|
+
if (bundledStrings) // bundled strings to skip past
|
|
195
|
+
position = bundledStrings.postBundlePosition;
|
|
196
|
+
|
|
125
197
|
if (position == srcEnd) {
|
|
126
198
|
// finished reading this source, cleanup references
|
|
127
199
|
currentStructures = null;
|
|
@@ -184,10 +256,11 @@ function read() {
|
|
|
184
256
|
position += 8;
|
|
185
257
|
return value
|
|
186
258
|
}
|
|
187
|
-
if (currentDecoder.
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
259
|
+
if (currentDecoder.int64AsNumber) {
|
|
260
|
+
token = dataView.getUint32(position) * 0x100000000;
|
|
261
|
+
token += dataView.getUint32(position + 4);
|
|
262
|
+
} else
|
|
263
|
+
token = dataView.getBigUint64(position);
|
|
191
264
|
position += 8;
|
|
192
265
|
break
|
|
193
266
|
case 0x1f:
|
|
@@ -195,6 +268,7 @@ function read() {
|
|
|
195
268
|
switch(majorType) {
|
|
196
269
|
case 2: // byte string
|
|
197
270
|
case 3: // text string
|
|
271
|
+
throw new Error('Indefinite length not supported for byte or text strings')
|
|
198
272
|
case 4: // array
|
|
199
273
|
let array = [];
|
|
200
274
|
let value, i = 0;
|
|
@@ -206,8 +280,8 @@ function read() {
|
|
|
206
280
|
let key;
|
|
207
281
|
if (currentDecoder.mapsAsObjects) {
|
|
208
282
|
let object = {};
|
|
209
|
-
|
|
210
|
-
|
|
283
|
+
if (currentDecoder.keyMap) while((key = read()) != STOP_CODE) object[currentDecoder.decodeKey(key)] = read();
|
|
284
|
+
else while ((key = read()) != STOP_CODE) object[key] = read();
|
|
211
285
|
return object
|
|
212
286
|
} else {
|
|
213
287
|
if (restoreMapsAsObject) {
|
|
@@ -215,8 +289,8 @@ function read() {
|
|
|
215
289
|
restoreMapsAsObject = false;
|
|
216
290
|
}
|
|
217
291
|
let map = new Map();
|
|
218
|
-
|
|
219
|
-
|
|
292
|
+
if (currentDecoder.keyMap) while((key = read()) != STOP_CODE) map.set(currentDecoder.decodeKey(key), read());
|
|
293
|
+
else while ((key = read()) != STOP_CODE) map.set(key, read());
|
|
220
294
|
return map
|
|
221
295
|
}
|
|
222
296
|
case 7:
|
|
@@ -248,16 +322,15 @@ function read() {
|
|
|
248
322
|
return readFixedString(token)
|
|
249
323
|
case 4: // array
|
|
250
324
|
let array = new Array(token);
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
325
|
+
//if (currentDecoder.keyMap) for (let i = 0; i < token; i++) array[i] = currentDecoder.decodeKey(read())
|
|
326
|
+
//else
|
|
327
|
+
for (let i = 0; i < token; i++) array[i] = read();
|
|
254
328
|
return array
|
|
255
329
|
case 5: // map
|
|
256
330
|
if (currentDecoder.mapsAsObjects) {
|
|
257
331
|
let object = {};
|
|
258
|
-
for (let i = 0; i < token; i++)
|
|
259
|
-
|
|
260
|
-
}
|
|
332
|
+
if (currentDecoder.keyMap) for (let i = 0; i < token; i++) object[currentDecoder.decodeKey(read())] = read();
|
|
333
|
+
else for (let i = 0; i < token; i++) object[read()] = read();
|
|
261
334
|
return object
|
|
262
335
|
} else {
|
|
263
336
|
if (restoreMapsAsObject) {
|
|
@@ -265,63 +338,66 @@ function read() {
|
|
|
265
338
|
restoreMapsAsObject = false;
|
|
266
339
|
}
|
|
267
340
|
let map = new Map();
|
|
268
|
-
for (let i = 0; i < token; i++)
|
|
269
|
-
|
|
270
|
-
}
|
|
341
|
+
if (currentDecoder.keyMap) for (let i = 0; i < token; i++) map.set(currentDecoder.decodeKey(read()),read());
|
|
342
|
+
else for (let i = 0; i < token; i++) map.set(read(), read());
|
|
271
343
|
return map
|
|
272
344
|
}
|
|
273
345
|
case 6: // extension
|
|
274
|
-
if (
|
|
275
|
-
let structure = currentStructures[token &
|
|
346
|
+
if (token >= BUNDLED_STRINGS_ID) {
|
|
347
|
+
let structure = currentStructures[token & 0x1fff]; // check record structures first
|
|
348
|
+
// At some point we may provide an option for dynamic tag assignment with a range like token >= 8 && (token < 16 || (token > 0x80 && token < 0xc0) || (token > 0x130 && token < 0x4000))
|
|
276
349
|
if (structure) {
|
|
277
|
-
if (!structure.read)
|
|
278
|
-
structure.read = createStructureReader(structure);
|
|
350
|
+
if (!structure.read) structure.read = createStructureReader(structure);
|
|
279
351
|
return structure.read()
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
if (
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
if (extension.handlesRead)
|
|
303
|
-
return extension(read)
|
|
304
|
-
else
|
|
305
|
-
return extension(read())
|
|
306
|
-
} else {
|
|
307
|
-
let input = read();
|
|
308
|
-
for (let i = 0; i < currentExtensionRanges.length; i++) {
|
|
309
|
-
let value = currentExtensionRanges[i](token, input);
|
|
310
|
-
if (value !== undefined)
|
|
311
|
-
return value
|
|
352
|
+
}
|
|
353
|
+
if (token < 0x10000) {
|
|
354
|
+
if (token == RECORD_INLINE_ID) // we do a special check for this so that we can keep the currentExtensions as densely stored array (v8 stores arrays densely under about 3000 elements)
|
|
355
|
+
return recordDefinition(read())
|
|
356
|
+
else if (token == RECORD_DEFINITIONS_ID) {
|
|
357
|
+
let length = readJustLength();
|
|
358
|
+
let id = read();
|
|
359
|
+
for (let i = 2; i < length; i++) {
|
|
360
|
+
recordDefinition([id++, read()]);
|
|
361
|
+
}
|
|
362
|
+
return read()
|
|
363
|
+
} else if (token == BUNDLED_STRINGS_ID) {
|
|
364
|
+
return readBundleExt()
|
|
365
|
+
}
|
|
366
|
+
if (currentDecoder.getShared) {
|
|
367
|
+
loadShared();
|
|
368
|
+
structure = currentStructures[token & 0x1fff];
|
|
369
|
+
if (structure) {
|
|
370
|
+
if (!structure.read)
|
|
371
|
+
structure.read = createStructureReader(structure);
|
|
372
|
+
return structure.read()
|
|
373
|
+
}
|
|
312
374
|
}
|
|
313
|
-
return new Tag(input)
|
|
314
375
|
}
|
|
315
376
|
}
|
|
377
|
+
let extension = currentExtensions[token];
|
|
378
|
+
if (extension) {
|
|
379
|
+
if (extension.handlesRead)
|
|
380
|
+
return extension(read)
|
|
381
|
+
else
|
|
382
|
+
return extension(read())
|
|
383
|
+
} else {
|
|
384
|
+
let input = read();
|
|
385
|
+
for (let i = 0; i < currentExtensionRanges.length; i++) {
|
|
386
|
+
let value = currentExtensionRanges[i](token, input);
|
|
387
|
+
if (value !== undefined)
|
|
388
|
+
return value
|
|
389
|
+
}
|
|
390
|
+
return new Tag(input, token)
|
|
391
|
+
}
|
|
316
392
|
case 7: // fixed value
|
|
317
393
|
switch (token) {
|
|
318
394
|
case 0x14: return false
|
|
319
395
|
case 0x15: return true
|
|
320
396
|
case 0x16: return null
|
|
321
397
|
case 0x17: return; // undefined
|
|
322
|
-
case 0x1f:
|
|
398
|
+
case 0x1f:
|
|
323
399
|
default:
|
|
324
|
-
let packedValue = packedValues[token];
|
|
400
|
+
let packedValue = (packedValues || getPackedValues())[token];
|
|
325
401
|
if (packedValue !== undefined)
|
|
326
402
|
return packedValue
|
|
327
403
|
throw new Error('Unknown token ' + token)
|
|
@@ -337,49 +413,59 @@ function read() {
|
|
|
337
413
|
}
|
|
338
414
|
const validName = /^[a-zA-Z_$][a-zA-Z\d_$]*$/;
|
|
339
415
|
function createStructureReader(structure) {
|
|
340
|
-
let l = structure.length;
|
|
341
416
|
function readObject() {
|
|
417
|
+
// get the array size from the header
|
|
418
|
+
let length = src[position++];
|
|
419
|
+
//let majorType = token >> 5
|
|
420
|
+
length = length & 0x1f;
|
|
421
|
+
if (length > 0x17) {
|
|
422
|
+
switch (length) {
|
|
423
|
+
case 0x18:
|
|
424
|
+
length = src[position++];
|
|
425
|
+
break
|
|
426
|
+
case 0x19:
|
|
427
|
+
length = dataView.getUint16(position);
|
|
428
|
+
position += 2;
|
|
429
|
+
break
|
|
430
|
+
case 0x1a:
|
|
431
|
+
length = dataView.getUint32(position);
|
|
432
|
+
position += 4;
|
|
433
|
+
break
|
|
434
|
+
default:
|
|
435
|
+
throw new Error('Expected array header, but got ' + src[position - 1])
|
|
436
|
+
}
|
|
437
|
+
}
|
|
342
438
|
// This initial function is quick to instantiate, but runs slower. After several iterations pay the cost to build the faster function
|
|
343
|
-
if (
|
|
344
|
-
|
|
345
|
-
|
|
439
|
+
if (this.objectLiteralSize === length) // we have a fast object literal reader, use it (assuming it is the right length)
|
|
440
|
+
return this.objectLiteral(read)
|
|
441
|
+
if (this.count++ == 3) { // create a fast reader
|
|
442
|
+
this.objectLiteralSize = length;
|
|
443
|
+
this.objectLiteral = currentDecoder.keyMap
|
|
444
|
+
? new Function('r', 'return {' + this.map(k => currentDecoder.decodeKey(k)).map(k => validName.test(k) ? k + ':r()' : ('[' + JSON.stringify(k) + ']:r()')).join(',') + '}')
|
|
445
|
+
: new Function('r', 'return {' + this.map(key => validName.test(key) ? key + ':r()' : ('[' + JSON.stringify(key) + ']:r()')).join(',') + '}');
|
|
446
|
+
return this.objectLiteral(read)
|
|
346
447
|
}
|
|
347
|
-
readArrayHeader();
|
|
348
448
|
let object = {};
|
|
349
|
-
for (let i = 0; i <
|
|
350
|
-
|
|
351
|
-
object[key] = read();
|
|
352
|
-
}
|
|
449
|
+
if (currentDecoder.keyMap) for (let i = 0; i < length; i++) object[currentDecoder.decodeKey(this[i])] = read();
|
|
450
|
+
else for (let i = 0; i < length; i++) object[this[i]] = read();
|
|
353
451
|
return object
|
|
354
452
|
}
|
|
355
|
-
|
|
453
|
+
structure.count = 0;
|
|
356
454
|
return readObject
|
|
357
455
|
}
|
|
358
456
|
|
|
359
|
-
function readArrayHeader(expectedLength) {
|
|
360
|
-
// consume the array header, TODO: check expected length
|
|
361
|
-
let token = src[position++];
|
|
362
|
-
//let majorType = token >> 5
|
|
363
|
-
token = token & 0x1f;
|
|
364
|
-
if (token > 0x17) {
|
|
365
|
-
switch (token) {
|
|
366
|
-
case 0x18: position++;
|
|
367
|
-
break
|
|
368
|
-
case 0x19: position += 2;
|
|
369
|
-
break
|
|
370
|
-
case 0x1a: position += 4;
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
|
|
375
457
|
let readFixedString = readStringJS;
|
|
376
458
|
|
|
459
|
+
exports.isNativeAccelerationEnabled = false;
|
|
377
460
|
function setExtractor(extractStrings) {
|
|
461
|
+
exports.isNativeAccelerationEnabled = true;
|
|
378
462
|
readFixedString = readString();
|
|
379
463
|
function readString(headerLength) {
|
|
380
464
|
return function readString(length) {
|
|
381
465
|
let string = strings[stringPosition++];
|
|
382
466
|
if (string == null) {
|
|
467
|
+
if (bundledStrings)
|
|
468
|
+
return readStringJS(length)
|
|
383
469
|
let extraction = extractStrings(position, srcEnd, length, src);
|
|
384
470
|
if (typeof extraction == 'string') {
|
|
385
471
|
string = extraction;
|
|
@@ -634,76 +720,15 @@ function getFloat16() {
|
|
|
634
720
|
}
|
|
635
721
|
|
|
636
722
|
let keyCache = new Array(4096);
|
|
637
|
-
function readKey() {
|
|
638
|
-
let length = src[position++];
|
|
639
|
-
if (length >= 0x60 && length < 0x78) {
|
|
640
|
-
// fixstr, potentially use key cache
|
|
641
|
-
length = length - 0x60;
|
|
642
|
-
if (srcStringEnd >= position) // if it has been extracted, must use it (and faster anyway)
|
|
643
|
-
return srcString.slice(position - srcStringStart, (position += length) - srcStringStart)
|
|
644
|
-
else if (!(srcStringEnd == 0 && srcEnd < 180))
|
|
645
|
-
return readFixedString(length)
|
|
646
|
-
} else { // not cacheable, go back and do a standard read
|
|
647
|
-
position--;
|
|
648
|
-
return read()
|
|
649
|
-
}
|
|
650
|
-
let key = ((length << 5) ^ (length > 1 ? dataView.getUint16(position) : length > 0 ? src[position] : 0)) & 0xfff;
|
|
651
|
-
let entry = keyCache[key];
|
|
652
|
-
let checkPosition = position;
|
|
653
|
-
let end = position + length - 3;
|
|
654
|
-
let chunk;
|
|
655
|
-
let i = 0;
|
|
656
|
-
if (entry && entry.bytes == length) {
|
|
657
|
-
while (checkPosition < end) {
|
|
658
|
-
chunk = dataView.getUint32(checkPosition);
|
|
659
|
-
if (chunk != entry[i++]) {
|
|
660
|
-
checkPosition = 0x70000000;
|
|
661
|
-
break
|
|
662
|
-
}
|
|
663
|
-
checkPosition += 4;
|
|
664
|
-
}
|
|
665
|
-
end += 3;
|
|
666
|
-
while (checkPosition < end) {
|
|
667
|
-
chunk = src[checkPosition++];
|
|
668
|
-
if (chunk != entry[i++]) {
|
|
669
|
-
checkPosition = 0x70000000;
|
|
670
|
-
break
|
|
671
|
-
}
|
|
672
|
-
}
|
|
673
|
-
if (checkPosition === end) {
|
|
674
|
-
position = checkPosition;
|
|
675
|
-
return entry.string
|
|
676
|
-
}
|
|
677
|
-
end -= 3;
|
|
678
|
-
checkPosition = position;
|
|
679
|
-
}
|
|
680
|
-
entry = [];
|
|
681
|
-
keyCache[key] = entry;
|
|
682
|
-
entry.bytes = length;
|
|
683
|
-
while (checkPosition < end) {
|
|
684
|
-
chunk = dataView.getUint32(checkPosition);
|
|
685
|
-
entry.push(chunk);
|
|
686
|
-
checkPosition += 4;
|
|
687
|
-
}
|
|
688
|
-
end += 3;
|
|
689
|
-
while (checkPosition < end) {
|
|
690
|
-
chunk = src[checkPosition++];
|
|
691
|
-
entry.push(chunk);
|
|
692
|
-
}
|
|
693
|
-
// for small blocks, avoiding the overhead of the extract call is helpful
|
|
694
|
-
let string = length < 16 ? shortStringInJS(length) : longStringInJS(length);
|
|
695
|
-
if (string != null)
|
|
696
|
-
return entry.string = string
|
|
697
|
-
return entry.string = readFixedString(length)
|
|
698
|
-
}
|
|
699
723
|
|
|
700
724
|
class Tag {
|
|
701
|
-
constructor(value) {
|
|
725
|
+
constructor(value, tag) {
|
|
702
726
|
this.value = value;
|
|
727
|
+
this.tag = tag;
|
|
703
728
|
}
|
|
704
729
|
}
|
|
705
730
|
|
|
706
|
-
let glbl = typeof
|
|
731
|
+
let glbl = typeof self == 'object' ? self : global;
|
|
707
732
|
|
|
708
733
|
currentExtensions[0] = (dateString) => {
|
|
709
734
|
// string date extension
|
|
@@ -717,38 +742,62 @@ currentExtensions[1] = (epochSec) => {
|
|
|
717
742
|
|
|
718
743
|
currentExtensions[2] = (buffer) => {
|
|
719
744
|
// bigint extension
|
|
720
|
-
|
|
745
|
+
let value = BigInt(0);
|
|
746
|
+
for (let i = 0, l = buffer.byteLength; i < l; i++) {
|
|
747
|
+
value = BigInt(buffer[i]) + value << BigInt(8);
|
|
748
|
+
}
|
|
749
|
+
return value
|
|
721
750
|
};
|
|
722
751
|
|
|
723
752
|
currentExtensions[3] = (buffer) => {
|
|
724
753
|
// negative bigint extension
|
|
725
|
-
return BigInt(-1) - (
|
|
754
|
+
return BigInt(-1) - currentExtensions[2](buffer)
|
|
755
|
+
};
|
|
756
|
+
currentExtensions[4] = (fraction) => {
|
|
757
|
+
// best to reparse to maintain accuracy
|
|
758
|
+
return +(fraction[1] + 'e' + fraction[0])
|
|
759
|
+
};
|
|
760
|
+
|
|
761
|
+
currentExtensions[5] = (fraction) => {
|
|
762
|
+
// probably not sufficiently accurate
|
|
763
|
+
return fraction[1] * Math.exp(fraction[0] * Math.log(2))
|
|
726
764
|
};
|
|
727
765
|
|
|
728
766
|
// the registration of the record definition extension (tag 105)
|
|
729
|
-
const recordDefinition = () => {
|
|
730
|
-
let
|
|
731
|
-
let structure = definition[
|
|
732
|
-
|
|
733
|
-
currentStructures[id & 0xff] = structure;
|
|
767
|
+
const recordDefinition = (definition) => {
|
|
768
|
+
let id = definition[0] - 0xe000;
|
|
769
|
+
let structure = definition[1];
|
|
770
|
+
currentStructures[id] = structure;
|
|
734
771
|
structure.read = createStructureReader(structure);
|
|
735
772
|
let object = {};
|
|
736
|
-
for (let i = 2,l = definition.length; i < l; i++) {
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
773
|
+
if (currentDecoder.keyMap) for (let i = 2,l = definition.length; i < l; i++) {
|
|
774
|
+
let key = currentDecoder.decodeKey(structure[i - 2]);
|
|
775
|
+
object[key] = definition[i];
|
|
776
|
+
}
|
|
777
|
+
else for (let i = 2,l = definition.length; i < l; i++) {
|
|
778
|
+
let key = structure[i - 2];
|
|
779
|
+
object[key] = definition[i];
|
|
780
|
+
}
|
|
740
781
|
return object
|
|
741
782
|
};
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
783
|
+
currentExtensions[LEGACY_RECORD_INLINE_ID] = recordDefinition;
|
|
784
|
+
currentExtensions[14] = (value) => {
|
|
785
|
+
if (bundledStrings)
|
|
786
|
+
return bundledStrings[0].slice(bundledStrings.position0, bundledStrings.position0 += value)
|
|
787
|
+
return new Tag(value, 14)
|
|
788
|
+
};
|
|
789
|
+
currentExtensions[15] = (value) => {
|
|
790
|
+
if (bundledStrings)
|
|
791
|
+
return bundledStrings[1].slice(bundledStrings.position1, bundledStrings.position1 += value)
|
|
792
|
+
return new Tag(value, 15)
|
|
793
|
+
};
|
|
745
794
|
|
|
746
795
|
currentExtensions[27] = (data) => { // http://cbor.schmorp.de/generic-object
|
|
747
796
|
return (glbl[data[0]] || Error)(data[1], data[2])
|
|
748
797
|
};
|
|
749
798
|
const packedTable = (read) => {
|
|
750
799
|
if (src[position++] != 0x84)
|
|
751
|
-
throw new Error('Packed values structure must be followed by 4 element array')
|
|
800
|
+
throw new Error('Packed values structure must be followed by a 4 element array')
|
|
752
801
|
let newPackedValues = read(); // packed values
|
|
753
802
|
packedValues = packedValues ? newPackedValues.concat(packedValues.slice(newPackedValues.length)) : newPackedValues;
|
|
754
803
|
packedValues.prefixes = read();
|
|
@@ -759,15 +808,36 @@ packedTable.handlesRead = true;
|
|
|
759
808
|
currentExtensions[51] = packedTable;
|
|
760
809
|
|
|
761
810
|
currentExtensions[PACKED_REFERENCE_TAG_ID] = (data) => { // packed reference
|
|
811
|
+
if (!packedValues) {
|
|
812
|
+
if (currentDecoder.getShared)
|
|
813
|
+
loadShared();
|
|
814
|
+
else
|
|
815
|
+
return new Tag(data, PACKED_REFERENCE_TAG_ID)
|
|
816
|
+
}
|
|
762
817
|
if (typeof data == 'number')
|
|
763
818
|
return packedValues[16 + (data >= 0 ? 2 * data : (-2 * data - 1))]
|
|
764
819
|
throw new Error('No support for non-integer packed references yet')
|
|
765
820
|
};
|
|
821
|
+
currentExtensions[25] = (id) => {
|
|
822
|
+
return stringRefs[id]
|
|
823
|
+
};
|
|
824
|
+
currentExtensions[256] = (read) => {
|
|
825
|
+
stringRefs = [];
|
|
826
|
+
try {
|
|
827
|
+
return read()
|
|
828
|
+
} finally {
|
|
829
|
+
stringRefs = null;
|
|
830
|
+
}
|
|
831
|
+
};
|
|
832
|
+
currentExtensions[256].handlesRead = true;
|
|
766
833
|
|
|
767
|
-
currentExtensions[
|
|
768
|
-
//
|
|
769
|
-
if (!referenceMap)
|
|
834
|
+
currentExtensions[28] = (read) => {
|
|
835
|
+
// shareable http://cbor.schmorp.de/value-sharing (for structured clones)
|
|
836
|
+
if (!referenceMap) {
|
|
770
837
|
referenceMap = new Map();
|
|
838
|
+
referenceMap.id = 0;
|
|
839
|
+
}
|
|
840
|
+
let id = referenceMap.id++;
|
|
771
841
|
let token = src[position];
|
|
772
842
|
let target;
|
|
773
843
|
// TODO: handle Maps, Sets, and other types that can cycle; this is complicated, because you potentially need to read
|
|
@@ -785,9 +855,10 @@ currentExtensions[40009] = (id) => {
|
|
|
785
855
|
refEntry.target = targetProperties; // the placeholder wasn't used, replace with the deserialized one
|
|
786
856
|
return targetProperties // no cycle, can just use the returned read object
|
|
787
857
|
};
|
|
858
|
+
currentExtensions[28].handlesRead = true;
|
|
788
859
|
|
|
789
|
-
currentExtensions[
|
|
790
|
-
//
|
|
860
|
+
currentExtensions[29] = (id) => {
|
|
861
|
+
// sharedref http://cbor.schmorp.de/value-sharing (for structured clones)
|
|
791
862
|
let refEntry = referenceMap.get(id);
|
|
792
863
|
refEntry.used = true;
|
|
793
864
|
return refEntry.target
|
|
@@ -810,19 +881,36 @@ function combine(a, b) {
|
|
|
810
881
|
return a.concat(b)
|
|
811
882
|
return Object.assign({}, a, b)
|
|
812
883
|
}
|
|
884
|
+
function getPackedValues() {
|
|
885
|
+
if (!packedValues) {
|
|
886
|
+
if (currentDecoder.getShared)
|
|
887
|
+
loadShared();
|
|
888
|
+
else
|
|
889
|
+
throw new Error('No packed values available')
|
|
890
|
+
}
|
|
891
|
+
return packedValues
|
|
892
|
+
}
|
|
893
|
+
const SHARED_DATA_TAG_ID = 0x53687264; // ascii 'Shrd'
|
|
813
894
|
currentExtensionRanges.push((tag, input) => {
|
|
814
895
|
if (tag >= 225 && tag <= 255)
|
|
815
|
-
return combine(
|
|
896
|
+
return combine(getPackedValues().prefixes[tag - 224], input)
|
|
816
897
|
if (tag >= 28704 && tag <= 32767)
|
|
817
|
-
return combine(
|
|
898
|
+
return combine(getPackedValues().prefixes[tag - 28672], input)
|
|
818
899
|
if (tag >= 1879052288 && tag <= 2147483647)
|
|
819
|
-
return combine(
|
|
900
|
+
return combine(getPackedValues().prefixes[tag - 1879048192], input)
|
|
820
901
|
if (tag >= 216 && tag <= 223)
|
|
821
|
-
return combine(input,
|
|
902
|
+
return combine(input, getPackedValues().suffixes[tag - 216])
|
|
822
903
|
if (tag >= 27647 && tag <= 28671)
|
|
823
|
-
return combine(input,
|
|
904
|
+
return combine(input, getPackedValues().suffixes[tag - 27639])
|
|
824
905
|
if (tag >= 1811940352 && tag <= 1879048191)
|
|
825
|
-
return combine(input,
|
|
906
|
+
return combine(input, getPackedValues().suffixes[tag - 1811939328])
|
|
907
|
+
if (tag == SHARED_DATA_TAG_ID) {// we do a special check for this so that we can keep the currentExtensions as densely stored array (v8 stores arrays densely under about 3000 elements)
|
|
908
|
+
return {
|
|
909
|
+
packedValues: packedValues,
|
|
910
|
+
structures: currentStructures.slice(0),
|
|
911
|
+
version: input,
|
|
912
|
+
}
|
|
913
|
+
}
|
|
826
914
|
});
|
|
827
915
|
|
|
828
916
|
const typedArrays = ['Uint8', 'Uint8Clamped', 'Uint16', 'Uint32', 'BigUint64','Int8', 'Int16', 'Int32', 'BigInt64', 'Float32', 'Float64'].map(type => type + 'Array');
|
|
@@ -839,6 +927,61 @@ function registerTypedArray(typedArrayName, tag) {
|
|
|
839
927
|
};
|
|
840
928
|
}
|
|
841
929
|
|
|
930
|
+
function readBundleExt() {
|
|
931
|
+
let length = readJustLength();
|
|
932
|
+
let bundlePosition = position + read();
|
|
933
|
+
for (let i = 2; i < length; i++) {
|
|
934
|
+
// skip past bundles that were already read
|
|
935
|
+
let bundleLength = readJustLength(); // this will increment position, so must add to position afterwards
|
|
936
|
+
position += bundleLength;
|
|
937
|
+
}
|
|
938
|
+
let dataPosition = position;
|
|
939
|
+
position = bundlePosition;
|
|
940
|
+
bundledStrings = [readStringJS(readJustLength()), readStringJS(readJustLength())];
|
|
941
|
+
bundledStrings.position0 = 0;
|
|
942
|
+
bundledStrings.position1 = 0;
|
|
943
|
+
bundledStrings.postBundlePosition = position;
|
|
944
|
+
position = dataPosition;
|
|
945
|
+
return read()
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
function readJustLength() {
|
|
949
|
+
let token = src[position++] & 0x1f;
|
|
950
|
+
if (token > 0x17) {
|
|
951
|
+
switch (token) {
|
|
952
|
+
case 0x18:
|
|
953
|
+
token = src[position++];
|
|
954
|
+
break
|
|
955
|
+
case 0x19:
|
|
956
|
+
token = dataView.getUint16(position);
|
|
957
|
+
position += 2;
|
|
958
|
+
break
|
|
959
|
+
case 0x1a:
|
|
960
|
+
token = dataView.getUint32(position);
|
|
961
|
+
position += 4;
|
|
962
|
+
break
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
return token
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
function loadShared() {
|
|
969
|
+
if (currentDecoder.getShared) {
|
|
970
|
+
let sharedData = saveState(() => {
|
|
971
|
+
// save the state in case getShared modifies our buffer
|
|
972
|
+
src = null;
|
|
973
|
+
return currentDecoder.getShared()
|
|
974
|
+
}) || {};
|
|
975
|
+
let updatedStructures = sharedData.structures || [];
|
|
976
|
+
currentDecoder.sharedVersion = sharedData.version;
|
|
977
|
+
packedValues = currentDecoder.sharedValues = sharedData.packedValues;
|
|
978
|
+
if (currentStructures === true)
|
|
979
|
+
currentDecoder.structures = currentStructures = updatedStructures;
|
|
980
|
+
else
|
|
981
|
+
currentStructures.splice.apply(currentStructures, [0, updatedStructures.length].concat(updatedStructures));
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
|
|
842
985
|
function saveState(callback) {
|
|
843
986
|
let savedSrcEnd = srcEnd;
|
|
844
987
|
let savedPosition = position;
|
|
@@ -848,6 +991,8 @@ function saveState(callback) {
|
|
|
848
991
|
let savedSrcString = srcString;
|
|
849
992
|
let savedStrings = strings;
|
|
850
993
|
let savedReferenceMap = referenceMap;
|
|
994
|
+
let savedBundledStrings = bundledStrings;
|
|
995
|
+
|
|
851
996
|
// TODO: We may need to revisit this if we do more external calls to user code (since it could be slow)
|
|
852
997
|
let savedSrc = new Uint8Array(src.slice(0, srcEnd)); // we copy the data in case it changes while external data is processed
|
|
853
998
|
let savedStructures = currentStructures;
|
|
@@ -862,6 +1007,7 @@ function saveState(callback) {
|
|
|
862
1007
|
srcString = savedSrcString;
|
|
863
1008
|
strings = savedStrings;
|
|
864
1009
|
referenceMap = savedReferenceMap;
|
|
1010
|
+
bundledStrings = savedBundledStrings;
|
|
865
1011
|
src = savedSrc;
|
|
866
1012
|
sequentialMode = savedSequentialMode;
|
|
867
1013
|
currentStructures = savedStructures;
|
|
@@ -908,13 +1054,15 @@ let extensions, extensionClasses;
|
|
|
908
1054
|
const hasNodeBuffer = typeof Buffer !== 'undefined';
|
|
909
1055
|
const ByteArrayAllocate = hasNodeBuffer ? Buffer.allocUnsafeSlow : Uint8Array;
|
|
910
1056
|
const ByteArray = hasNodeBuffer ? Buffer : Uint8Array;
|
|
911
|
-
const RECORD_STARTING_ID_PREFIX = 0x69; // tag 105/0x69
|
|
912
1057
|
const MAX_STRUCTURES = 0x100;
|
|
913
1058
|
const MAX_BUFFER_SIZE = hasNodeBuffer ? 0x100000000 : 0x7fd00000;
|
|
914
1059
|
let target;
|
|
915
1060
|
let targetView;
|
|
916
1061
|
let position$1 = 0;
|
|
917
1062
|
let safeEnd;
|
|
1063
|
+
let bundledStrings$1 = null;
|
|
1064
|
+
const MAX_BUNDLE_SIZE = 0xf000;
|
|
1065
|
+
const hasNonLatin = /[\u0080-\uFFFF]/;
|
|
918
1066
|
const RECORD_SYMBOL = Symbol('record-id');
|
|
919
1067
|
class Encoder extends Decoder {
|
|
920
1068
|
constructor(options) {
|
|
@@ -926,7 +1074,6 @@ class Encoder extends Decoder {
|
|
|
926
1074
|
let structures;
|
|
927
1075
|
let referenceMap;
|
|
928
1076
|
options = options || {};
|
|
929
|
-
let lastSharedStructuresLength = 0;
|
|
930
1077
|
let encodeUtf8 = ByteArray.prototype.utf8Write ? function(string, position, maxBytes) {
|
|
931
1078
|
return target.utf8Write(string, position, maxBytes)
|
|
932
1079
|
} : (textEncoder && textEncoder.encodeInto) ?
|
|
@@ -935,12 +1082,14 @@ class Encoder extends Decoder {
|
|
|
935
1082
|
} : false;
|
|
936
1083
|
|
|
937
1084
|
let encoder = this;
|
|
938
|
-
let maxSharedStructures =
|
|
1085
|
+
let maxSharedStructures = options.maxSharedStructures || 128;
|
|
939
1086
|
let isSequential = options.sequential;
|
|
940
1087
|
if (isSequential) {
|
|
941
1088
|
maxSharedStructures = 0;
|
|
942
1089
|
this.structures = [];
|
|
943
1090
|
}
|
|
1091
|
+
if (this.saveStructures)
|
|
1092
|
+
this.saveShared = this.saveStructures;
|
|
944
1093
|
let samplingPackedValues, packedObjectMap, sharedValues = options.sharedValues;
|
|
945
1094
|
let sharedPackedObjectMap;
|
|
946
1095
|
if (sharedValues) {
|
|
@@ -948,13 +1097,29 @@ class Encoder extends Decoder {
|
|
|
948
1097
|
for (let i = 0, l = sharedValues.length; i < l; i++) {
|
|
949
1098
|
sharedPackedObjectMap[sharedValues[i]] = i;
|
|
950
1099
|
}
|
|
951
|
-
|
|
952
1100
|
}
|
|
953
1101
|
let recordIdsToRemove = [];
|
|
954
1102
|
let transitionsCount = 0;
|
|
955
1103
|
let serializationsSinceTransitionRebuild = 0;
|
|
956
|
-
|
|
957
|
-
this.
|
|
1104
|
+
|
|
1105
|
+
this.mapEncode = function(value, encodeOptions) {
|
|
1106
|
+
// Experimental support for premapping keys using _keyMap instad of keyMap - not optiimised yet)
|
|
1107
|
+
if (this._keyMap && !this._mapped) {
|
|
1108
|
+
//console.log('encoding ', value)
|
|
1109
|
+
switch (value.constructor.name) {
|
|
1110
|
+
case 'Array':
|
|
1111
|
+
value = value.map(r => this.encodeKeys(r));
|
|
1112
|
+
break
|
|
1113
|
+
//case 'Map':
|
|
1114
|
+
// value = this.encodeKeys(value)
|
|
1115
|
+
// break
|
|
1116
|
+
}
|
|
1117
|
+
//this._mapped = true
|
|
1118
|
+
}
|
|
1119
|
+
return this.encode(value, encodeOptions)
|
|
1120
|
+
};
|
|
1121
|
+
|
|
1122
|
+
this.encode = function(value, encodeOptions) {
|
|
958
1123
|
if (!target) {
|
|
959
1124
|
target = new ByteArrayAllocate(8192);
|
|
960
1125
|
targetView = new DataView(target.buffer, 0, 8192);
|
|
@@ -971,10 +1136,25 @@ class Encoder extends Decoder {
|
|
|
971
1136
|
position$1 = (position$1 + 7) & 0x7ffffff8; // Word align to make any future copying of this buffer faster
|
|
972
1137
|
start = position$1;
|
|
973
1138
|
referenceMap = encoder.structuredClone ? new Map() : null;
|
|
1139
|
+
if (encoder.bundleStrings && typeof value !== 'string') {
|
|
1140
|
+
bundledStrings$1 = [];
|
|
1141
|
+
bundledStrings$1.size = Infinity; // force a new bundle start on first string
|
|
1142
|
+
} else
|
|
1143
|
+
bundledStrings$1 = null;
|
|
1144
|
+
|
|
974
1145
|
sharedStructures = encoder.structures;
|
|
975
1146
|
if (sharedStructures) {
|
|
976
|
-
if (sharedStructures.uninitialized)
|
|
977
|
-
|
|
1147
|
+
if (sharedStructures.uninitialized) {
|
|
1148
|
+
let sharedData = encoder.getShared() || {};
|
|
1149
|
+
encoder.structures = sharedStructures = sharedData.structures || [];
|
|
1150
|
+
encoder.sharedVersion = sharedData.version;
|
|
1151
|
+
let sharedValues = encoder.sharedValues = sharedData.packedValues;
|
|
1152
|
+
if (sharedValues) {
|
|
1153
|
+
sharedPackedObjectMap = {};
|
|
1154
|
+
for (let i = 0, l = sharedValues.length; i < l; i++)
|
|
1155
|
+
sharedPackedObjectMap[sharedValues[i]] = i;
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
978
1158
|
let sharedStructuresLength = sharedStructures.length;
|
|
979
1159
|
if (sharedStructuresLength > maxSharedStructures && !isSequential)
|
|
980
1160
|
sharedStructuresLength = maxSharedStructures;
|
|
@@ -983,6 +1163,7 @@ class Encoder extends Decoder {
|
|
|
983
1163
|
sharedStructures.transitions = Object.create(null);
|
|
984
1164
|
for (let i = 0; i < sharedStructuresLength; i++) {
|
|
985
1165
|
let keys = sharedStructures[i];
|
|
1166
|
+
//console.log('shared struct keys:', keys)
|
|
986
1167
|
if (!keys)
|
|
987
1168
|
continue
|
|
988
1169
|
let nextTransition, transition = sharedStructures.transitions;
|
|
@@ -996,7 +1177,6 @@ class Encoder extends Decoder {
|
|
|
996
1177
|
}
|
|
997
1178
|
transition[RECORD_SYMBOL] = i;
|
|
998
1179
|
}
|
|
999
|
-
lastSharedStructuresLength = sharedStructures.length;
|
|
1000
1180
|
}
|
|
1001
1181
|
if (!isSequential)
|
|
1002
1182
|
sharedStructures.nextId = sharedStructuresLength;
|
|
@@ -1029,9 +1209,12 @@ class Encoder extends Decoder {
|
|
|
1029
1209
|
}
|
|
1030
1210
|
try {
|
|
1031
1211
|
encode(value);
|
|
1212
|
+
if (bundledStrings$1) {
|
|
1213
|
+
writeBundles(start, encode);
|
|
1214
|
+
}
|
|
1032
1215
|
encoder.offset = position$1; // update the offset so next serialization doesn't write over our buffer, but can continue writing to same buffer sequentially
|
|
1033
1216
|
if (referenceMap && referenceMap.idsToInsert) {
|
|
1034
|
-
position$1 += referenceMap.idsToInsert.length *
|
|
1217
|
+
position$1 += referenceMap.idsToInsert.length * 2;
|
|
1035
1218
|
if (position$1 > safeEnd)
|
|
1036
1219
|
makeRoom(position$1);
|
|
1037
1220
|
encoder.offset = position$1;
|
|
@@ -1039,12 +1222,12 @@ class Encoder extends Decoder {
|
|
|
1039
1222
|
referenceMap = null;
|
|
1040
1223
|
return serialized
|
|
1041
1224
|
}
|
|
1042
|
-
if (encodeOptions
|
|
1225
|
+
if (encodeOptions & REUSE_BUFFER_MODE) {
|
|
1043
1226
|
target.start = start;
|
|
1044
1227
|
target.end = position$1;
|
|
1045
1228
|
return target
|
|
1046
1229
|
}
|
|
1047
|
-
return target.subarray(start, position$1) // position can change if we call pack again in
|
|
1230
|
+
return target.subarray(start, position$1) // position can change if we call pack again in saveShared, so we get the buffer now
|
|
1048
1231
|
} finally {
|
|
1049
1232
|
if (sharedStructures) {
|
|
1050
1233
|
if (serializationsSinceTransitionRebuild < 10)
|
|
@@ -1062,34 +1245,27 @@ class Encoder extends Decoder {
|
|
|
1062
1245
|
}
|
|
1063
1246
|
recordIdsToRemove = [];
|
|
1064
1247
|
}
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
// we can't rely on start/end with REUSE_BUFFER_MODE since they will (probably) change when we save
|
|
1070
|
-
let returnBuffer = target.subarray(start, position$1);
|
|
1071
|
-
let shared = encoder.structures || [];
|
|
1072
|
-
if (sharedValues) {
|
|
1073
|
-
shared = shared.concat(sharedValues);
|
|
1074
|
-
}
|
|
1075
|
-
|
|
1076
|
-
if (encoder.saveStructures(encoder.structures, lastSharedStructuresLength) === false) {
|
|
1077
|
-
// get updated structures and try again if the update failed
|
|
1078
|
-
encoder.structures = encoder.getStructures() || [];
|
|
1079
|
-
return encoder.encode(value)
|
|
1080
|
-
}
|
|
1081
|
-
lastSharedStructuresLength = shared.length;
|
|
1082
|
-
return returnBuffer
|
|
1248
|
+
}
|
|
1249
|
+
if (hasSharedUpdate && encoder.saveShared) {
|
|
1250
|
+
if (encoder.structures.length > maxSharedStructures) {
|
|
1251
|
+
encoder.structures = encoder.structures.slice(0, maxSharedStructures);
|
|
1083
1252
|
}
|
|
1253
|
+
// we can't rely on start/end with REUSE_BUFFER_MODE since they will (probably) change when we save
|
|
1254
|
+
let returnBuffer = target.subarray(start, position$1);
|
|
1255
|
+
if (encoder.updateSharedData() === false)
|
|
1256
|
+
return encoder.encode(value) // re-encode if it fails
|
|
1257
|
+
return returnBuffer
|
|
1084
1258
|
}
|
|
1259
|
+
if (encodeOptions & RESET_BUFFER_MODE)
|
|
1260
|
+
position$1 = start;
|
|
1085
1261
|
}
|
|
1086
1262
|
};
|
|
1087
1263
|
this.findCommonStringsToPack = () => {
|
|
1088
1264
|
samplingPackedValues = new Map();
|
|
1089
1265
|
if (!sharedPackedObjectMap)
|
|
1090
1266
|
sharedPackedObjectMap = Object.create(null);
|
|
1091
|
-
return (
|
|
1092
|
-
threshold = threshold || 4;
|
|
1267
|
+
return (options) => {
|
|
1268
|
+
let threshold = options && options.threshold || 4;
|
|
1093
1269
|
let position = this.pack ? options.maxPrivatePackedValues || 16 : 0;
|
|
1094
1270
|
if (!sharedValues)
|
|
1095
1271
|
sharedValues = this.sharedValues = [];
|
|
@@ -1100,6 +1276,7 @@ class Encoder extends Decoder {
|
|
|
1100
1276
|
hasSharedUpdate = true;
|
|
1101
1277
|
}
|
|
1102
1278
|
}
|
|
1279
|
+
while (this.saveShared && this.updateSharedData() === false) {}
|
|
1103
1280
|
samplingPackedValues = null;
|
|
1104
1281
|
}
|
|
1105
1282
|
};
|
|
@@ -1148,6 +1325,33 @@ class Encoder extends Decoder {
|
|
|
1148
1325
|
}
|
|
1149
1326
|
}
|
|
1150
1327
|
let strLength = value.length;
|
|
1328
|
+
if (bundledStrings$1 && strLength >= 4 && strLength < 0x400) {
|
|
1329
|
+
if ((bundledStrings$1.size += strLength) > MAX_BUNDLE_SIZE) {
|
|
1330
|
+
let extStart;
|
|
1331
|
+
let maxBytes = (bundledStrings$1[0] ? bundledStrings$1[0].length * 3 + bundledStrings$1[1].length : 0) + 10;
|
|
1332
|
+
if (position$1 + maxBytes > safeEnd)
|
|
1333
|
+
target = makeRoom(position$1 + maxBytes);
|
|
1334
|
+
target[position$1++] = 0xd9; // tag 16-bit
|
|
1335
|
+
target[position$1++] = 0xdf; // tag 0xdff9
|
|
1336
|
+
target[position$1++] = 0xf9;
|
|
1337
|
+
// TODO: If we only have one bundle with any string data, only write one string bundle
|
|
1338
|
+
target[position$1++] = bundledStrings$1.position ? 0x84 : 0x82; // array of 4 or 2 elements depending on if we write bundles
|
|
1339
|
+
target[position$1++] = 0x1a; // 32-bit unsigned int
|
|
1340
|
+
extStart = position$1 - start;
|
|
1341
|
+
position$1 += 4; // reserve for writing bundle reference
|
|
1342
|
+
if (bundledStrings$1.position) {
|
|
1343
|
+
writeBundles(start, encode); // write the last bundles
|
|
1344
|
+
}
|
|
1345
|
+
bundledStrings$1 = ['', '']; // create new ones
|
|
1346
|
+
bundledStrings$1.size = 0;
|
|
1347
|
+
bundledStrings$1.position = extStart;
|
|
1348
|
+
}
|
|
1349
|
+
let twoByte = hasNonLatin.test(value);
|
|
1350
|
+
bundledStrings$1[twoByte ? 0 : 1] += value;
|
|
1351
|
+
target[position$1++] = twoByte ? 0xce : 0xcf;
|
|
1352
|
+
encode(strLength);
|
|
1353
|
+
return
|
|
1354
|
+
}
|
|
1151
1355
|
let headerSize;
|
|
1152
1356
|
// first we estimate the header size, so we can write to the correct location
|
|
1153
1357
|
if (strLength < 0x20) {
|
|
@@ -1274,16 +1478,16 @@ class Encoder extends Decoder {
|
|
|
1274
1478
|
if (referenceMap) {
|
|
1275
1479
|
let referee = referenceMap.get(value);
|
|
1276
1480
|
if (referee) {
|
|
1277
|
-
|
|
1481
|
+
target[position$1++] = 0xd8;
|
|
1482
|
+
target[position$1++] = 29; // http://cbor.schmorp.de/value-sharing
|
|
1483
|
+
target[position$1++] = 0x19; // 16-bit uint
|
|
1484
|
+
if (!referee.references) {
|
|
1278
1485
|
let idsToInsert = referenceMap.idsToInsert || (referenceMap.idsToInsert = []);
|
|
1279
|
-
referee.
|
|
1486
|
+
referee.references = [];
|
|
1487
|
+
idsToInsert.push(referee);
|
|
1280
1488
|
}
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
target[position$1++] = 40010 & 0xff;
|
|
1284
|
-
target[position$1++] = 0x1a; // uint32
|
|
1285
|
-
targetView.setUint32(position$1, referee.id);
|
|
1286
|
-
position$1 += 4;
|
|
1489
|
+
referee.references.push(position$1 - start);
|
|
1490
|
+
position$1 += 2; // TODO: also support 32-bit
|
|
1287
1491
|
return
|
|
1288
1492
|
} else
|
|
1289
1493
|
referenceMap.set(value, { offset: position$1 - start });
|
|
@@ -1323,16 +1527,23 @@ class Encoder extends Decoder {
|
|
|
1323
1527
|
targetView.setUint32(position$1, length);
|
|
1324
1528
|
position$1 += 4;
|
|
1325
1529
|
}
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1530
|
+
if (encoder.keyMap) {
|
|
1531
|
+
for (let [ key, entryValue ] of value) {
|
|
1532
|
+
encode(encoder.encodeKey(key));
|
|
1533
|
+
encode(entryValue);
|
|
1534
|
+
}
|
|
1535
|
+
} else {
|
|
1536
|
+
for (let [ key, entryValue ] of value) {
|
|
1537
|
+
encode(key);
|
|
1538
|
+
encode(entryValue);
|
|
1539
|
+
}
|
|
1329
1540
|
}
|
|
1330
|
-
} else {
|
|
1541
|
+
} else {
|
|
1331
1542
|
for (let i = 0, l = extensions.length; i < l; i++) {
|
|
1332
1543
|
let extensionClass = extensionClasses[i];
|
|
1333
1544
|
if (value instanceof extensionClass) {
|
|
1334
1545
|
let extension = extensions[i];
|
|
1335
|
-
let tag = extension.tag;
|
|
1546
|
+
let tag = extension.tag || extension.getTag && extension.getTag(value);
|
|
1336
1547
|
if (tag < 0x18) {
|
|
1337
1548
|
target[position$1++] = 0xc0 | tag;
|
|
1338
1549
|
} else if (tag < 0x100) {
|
|
@@ -1394,6 +1605,7 @@ class Encoder extends Decoder {
|
|
|
1394
1605
|
const writeObject = this.useRecords === false ? this.variableMapSize ? (object) => {
|
|
1395
1606
|
// this method is slightly slower, but generates "preferred serialization" (optimally small for smaller objects)
|
|
1396
1607
|
let keys = Object.keys(object);
|
|
1608
|
+
let vals = Object.values(object);
|
|
1397
1609
|
let length = keys.length;
|
|
1398
1610
|
if (length < 0x18) {
|
|
1399
1611
|
target[position$1++] = 0xa0 | length;
|
|
@@ -1409,10 +1621,16 @@ class Encoder extends Decoder {
|
|
|
1409
1621
|
targetView.setUint32(position$1, length);
|
|
1410
1622
|
position$1 += 4;
|
|
1411
1623
|
}
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1624
|
+
if (encoder.keyMap) {
|
|
1625
|
+
for (let i = 0; i < length; i++) {
|
|
1626
|
+
encode(encodeKey(keys[i]));
|
|
1627
|
+
encode(vals[i]);
|
|
1628
|
+
}
|
|
1629
|
+
} else {
|
|
1630
|
+
for (let i = 0; i < length; i++) {
|
|
1631
|
+
encode(keys[i]);
|
|
1632
|
+
encode(vals[i]);
|
|
1633
|
+
}
|
|
1416
1634
|
}
|
|
1417
1635
|
} :
|
|
1418
1636
|
(object, safePrototype) => {
|
|
@@ -1420,12 +1638,18 @@ class Encoder extends Decoder {
|
|
|
1420
1638
|
let objectOffset = position$1 - start;
|
|
1421
1639
|
position$1 += 2;
|
|
1422
1640
|
let size = 0;
|
|
1423
|
-
|
|
1424
|
-
if (safePrototype || object.hasOwnProperty(key)) {
|
|
1425
|
-
encode(key);
|
|
1641
|
+
if (encoder.keyMap) {
|
|
1642
|
+
for (let key in object) if (safePrototype || object.hasOwnProperty(key)) {
|
|
1643
|
+
encode(encoder.encodeKey(key));
|
|
1426
1644
|
encode(object[key]);
|
|
1427
1645
|
size++;
|
|
1428
1646
|
}
|
|
1647
|
+
} else {
|
|
1648
|
+
for (let key in object) if (safePrototype || object.hasOwnProperty(key)) {
|
|
1649
|
+
encode(key);
|
|
1650
|
+
encode(object[key]);
|
|
1651
|
+
size++;
|
|
1652
|
+
}
|
|
1429
1653
|
}
|
|
1430
1654
|
target[objectOffset++ + start] = size >> 8;
|
|
1431
1655
|
target[objectOffset + start] = size & 0xff;
|
|
@@ -1473,11 +1697,16 @@ class Encoder extends Decoder {
|
|
|
1473
1697
|
}*/
|
|
1474
1698
|
(object) => {
|
|
1475
1699
|
let keys = Object.keys(object);
|
|
1700
|
+
let vals = Object.values(object);
|
|
1701
|
+
if (this.keyMap) keys = keys.map(k => this.encodeKey(k));
|
|
1476
1702
|
let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
|
|
1477
1703
|
let newTransitions = 0;
|
|
1478
1704
|
let length = keys.length;
|
|
1705
|
+
//let parentRecordId
|
|
1479
1706
|
for (let i = 0; i < length; i++) {
|
|
1707
|
+
//if (!parentRecordId)
|
|
1480
1708
|
let key = keys[i];
|
|
1709
|
+
// parentRecordId = transition[RECORD_SYMBOL]
|
|
1481
1710
|
nextTransition = transition[key];
|
|
1482
1711
|
if (!nextTransition) {
|
|
1483
1712
|
nextTransition = transition[key] = Object.create(null);
|
|
@@ -1487,9 +1716,9 @@ class Encoder extends Decoder {
|
|
|
1487
1716
|
}
|
|
1488
1717
|
let recordId = transition[RECORD_SYMBOL];
|
|
1489
1718
|
if (recordId !== undefined) {
|
|
1490
|
-
target[position$1++] = 0xd9;
|
|
1491
|
-
target[position$1++] =
|
|
1492
|
-
target[position$1++] = recordId;
|
|
1719
|
+
target[position$1++] = 0xd9;
|
|
1720
|
+
target[position$1++] = (recordId >> 8) | 0xe0;
|
|
1721
|
+
target[position$1++] = recordId & 0xff;
|
|
1493
1722
|
} else {
|
|
1494
1723
|
recordId = structures.nextId++;
|
|
1495
1724
|
if (!recordId) {
|
|
@@ -1502,13 +1731,13 @@ class Encoder extends Decoder {
|
|
|
1502
1731
|
transition[RECORD_SYMBOL] = recordId;
|
|
1503
1732
|
structures[recordId] = keys;
|
|
1504
1733
|
if (sharedStructures && sharedStructures.length <= maxSharedStructures) {
|
|
1505
|
-
target[position$1++] = 0xd9;
|
|
1506
|
-
target[position$1++] =
|
|
1507
|
-
target[position$1++] = recordId
|
|
1734
|
+
target[position$1++] = 0xd9;
|
|
1735
|
+
target[position$1++] = (recordId >> 8) | 0xe0;
|
|
1736
|
+
target[position$1++] = recordId & 0xff;
|
|
1508
1737
|
hasSharedUpdate = true;
|
|
1509
1738
|
} else {
|
|
1510
|
-
|
|
1511
|
-
|
|
1739
|
+
targetView.setUint32(position$1, 0xd9dfff00); // tag two byte, then record definition id
|
|
1740
|
+
position$1 += 3;
|
|
1512
1741
|
if (newTransitions)
|
|
1513
1742
|
transitionsCount += serializationsSinceTransitionRebuild * newTransitions;
|
|
1514
1743
|
// record the removal of the id, we can maintain our shared structure
|
|
@@ -1516,13 +1745,9 @@ class Encoder extends Decoder {
|
|
|
1516
1745
|
recordIdsToRemove.shift()[RECORD_SYMBOL] = undefined; // we are cycling back through, and have to remove old ones
|
|
1517
1746
|
recordIdsToRemove.push(transition);
|
|
1518
1747
|
writeArrayHeader(length + 2);
|
|
1748
|
+
encode(0xe000 + recordId);
|
|
1519
1749
|
encode(keys);
|
|
1520
|
-
|
|
1521
|
-
target[position$1++] = RECORD_STARTING_ID_PREFIX;
|
|
1522
|
-
target[position$1++] = recordId;
|
|
1523
|
-
// now write the values
|
|
1524
|
-
for (let i =0; i < length; i++)
|
|
1525
|
-
encode(object[keys[i]]);
|
|
1750
|
+
for (let v of Object.values(object)) encode(v);
|
|
1526
1751
|
return
|
|
1527
1752
|
}
|
|
1528
1753
|
}
|
|
@@ -1531,8 +1756,7 @@ class Encoder extends Decoder {
|
|
|
1531
1756
|
} else {
|
|
1532
1757
|
writeArrayHeader(length);
|
|
1533
1758
|
}
|
|
1534
|
-
for (let i =0; i < length; i++)
|
|
1535
|
-
encode(object[keys[i]]);
|
|
1759
|
+
for (let i =0; i < length; i++) encode(vals[i]);
|
|
1536
1760
|
};
|
|
1537
1761
|
const makeRoom = (end) => {
|
|
1538
1762
|
let newSize;
|
|
@@ -1541,7 +1765,7 @@ class Encoder extends Decoder {
|
|
|
1541
1765
|
if ((end - start) > MAX_BUFFER_SIZE)
|
|
1542
1766
|
throw new Error('Encoded buffer would be larger than maximum buffer size')
|
|
1543
1767
|
newSize = Math.min(MAX_BUFFER_SIZE,
|
|
1544
|
-
Math.round(Math.max((end - start) * (end > 0x4000000 ? 1.25 : 2),
|
|
1768
|
+
Math.round(Math.max((end - start) * (end > 0x4000000 ? 1.25 : 2), 0x400000) / 0x1000) * 0x1000);
|
|
1545
1769
|
} else // faster handling for smaller buffers
|
|
1546
1770
|
newSize = ((Math.max((end - start) << 2, target.length - 1) >> 12) + 1) << 12;
|
|
1547
1771
|
let newBuffer = new ByteArrayAllocate(newSize);
|
|
@@ -1562,6 +1786,33 @@ class Encoder extends Decoder {
|
|
|
1562
1786
|
targetView = new DataView(target.buffer, target.byteOffset, target.byteLength);
|
|
1563
1787
|
position$1 = 0;
|
|
1564
1788
|
}
|
|
1789
|
+
clearSharedData() {
|
|
1790
|
+
if (this.structures)
|
|
1791
|
+
this.structures = [];
|
|
1792
|
+
if (this.sharedValues)
|
|
1793
|
+
this.sharedValues = undefined;
|
|
1794
|
+
}
|
|
1795
|
+
updateSharedData() {
|
|
1796
|
+
let lastVersion = this.sharedVersion || 0;
|
|
1797
|
+
this.sharedVersion = lastVersion + 1;
|
|
1798
|
+
let saveResults = this.saveShared(new SharedData(this.structures, this.sharedValues, this.sharedVersion),
|
|
1799
|
+
existingShared => (existingShared && existingShared.version || 0) == lastVersion);
|
|
1800
|
+
if (saveResults === false) {
|
|
1801
|
+
// get updated structures and try again if the update failed
|
|
1802
|
+
let sharedData = this.getShared() || {};
|
|
1803
|
+
this.structures = sharedData.structures || [];
|
|
1804
|
+
this.sharedValues = sharedData.packedValues;
|
|
1805
|
+
this.sharedVersion = sharedData.version;
|
|
1806
|
+
}
|
|
1807
|
+
return saveResults
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1810
|
+
class SharedData {
|
|
1811
|
+
constructor(structures, values, version) {
|
|
1812
|
+
this.structures = structures;
|
|
1813
|
+
this.packedValues = values;
|
|
1814
|
+
this.version = version;
|
|
1815
|
+
}
|
|
1565
1816
|
}
|
|
1566
1817
|
|
|
1567
1818
|
function writeArrayHeader(length) {
|
|
@@ -1631,9 +1882,11 @@ function findRepetitiveStrings(value, packedValues) {
|
|
|
1631
1882
|
}
|
|
1632
1883
|
}
|
|
1633
1884
|
|
|
1634
|
-
extensionClasses = [ Date, Set, Error, RegExp, ArrayBuffer, ByteArray,
|
|
1635
|
-
Uint8Array, Uint8ClampedArray, Uint16Array, Uint32Array,
|
|
1636
|
-
|
|
1885
|
+
extensionClasses = [ Date, Set, Error, RegExp, Tag, ArrayBuffer, ByteArray,
|
|
1886
|
+
Uint8Array, Uint8ClampedArray, Uint16Array, Uint32Array,
|
|
1887
|
+
typeof BigUint64Array == 'undefined' ? function() {} : BigUint64Array, Int8Array, Int16Array, Int32Array,
|
|
1888
|
+
typeof BigInt64Array == 'undefined' ? function() {} : BigInt64Array,
|
|
1889
|
+
Float32Array, Float64Array, SharedData];
|
|
1637
1890
|
|
|
1638
1891
|
//Object.getPrototypeOf(Uint8Array.prototype).constructor /*TypedArray*/
|
|
1639
1892
|
extensions = [{
|
|
@@ -1668,6 +1921,13 @@ extensions = [{
|
|
|
1668
1921
|
encode(regex, encode) {
|
|
1669
1922
|
encode([ 'RegExp', regex.source, regex.flags ]);
|
|
1670
1923
|
}
|
|
1924
|
+
}, {
|
|
1925
|
+
getTag(tag) {
|
|
1926
|
+
return tag.tag
|
|
1927
|
+
},
|
|
1928
|
+
encode(tag, encode) {
|
|
1929
|
+
encode(tag.value);
|
|
1930
|
+
}
|
|
1671
1931
|
}, {
|
|
1672
1932
|
encode(arrayBuffer, encode, makeRoom) {
|
|
1673
1933
|
writeBuffer(arrayBuffer, makeRoom);
|
|
@@ -1686,7 +1946,35 @@ extensions = [{
|
|
|
1686
1946
|
typedArrayEncoder(78),
|
|
1687
1947
|
typedArrayEncoder(79),
|
|
1688
1948
|
typedArrayEncoder(81),
|
|
1689
|
-
typedArrayEncoder(82)
|
|
1949
|
+
typedArrayEncoder(82),
|
|
1950
|
+
{
|
|
1951
|
+
encode(sharedData, encode) { // write SharedData
|
|
1952
|
+
let packedValues = sharedData.packedValues || [];
|
|
1953
|
+
let sharedStructures = sharedData.structures || [];
|
|
1954
|
+
if (packedValues.values.length > 0) {
|
|
1955
|
+
target[position$1++] = 0xd8; // one-byte tag
|
|
1956
|
+
target[position$1++] = 51; // tag 51 for packed shared structures https://www.potaroo.net/ietf/ids/draft-ietf-cbor-packed-03.txt
|
|
1957
|
+
writeArrayHeader(4);
|
|
1958
|
+
let valuesArray = packedValues.values;
|
|
1959
|
+
encode(valuesArray);
|
|
1960
|
+
writeArrayHeader(0); // prefixes
|
|
1961
|
+
writeArrayHeader(0); // suffixes
|
|
1962
|
+
packedObjectMap = Object.create(sharedPackedObjectMap || null);
|
|
1963
|
+
for (let i = 0, l = valuesArray.length; i < l; i++) {
|
|
1964
|
+
packedObjectMap[valuesArray[i]] = i;
|
|
1965
|
+
}
|
|
1966
|
+
}
|
|
1967
|
+
if (sharedStructures) {
|
|
1968
|
+
targetView.setUint32(position$1, 0xd9dffe00);
|
|
1969
|
+
position$1 += 3;
|
|
1970
|
+
let definitions = sharedStructures.slice(0);
|
|
1971
|
+
definitions.unshift(0xe000);
|
|
1972
|
+
definitions.push(new Tag(sharedData.version, 0x53687264));
|
|
1973
|
+
encode(definitions);
|
|
1974
|
+
} else
|
|
1975
|
+
encode(new Tag(sharedData.version, 0x53687264));
|
|
1976
|
+
}
|
|
1977
|
+
}];
|
|
1690
1978
|
|
|
1691
1979
|
function typedArrayEncoder(tag) {
|
|
1692
1980
|
return {
|
|
@@ -1726,27 +2014,35 @@ function writeBuffer(buffer, makeRoom) {
|
|
|
1726
2014
|
function insertIds(serialized, idsToInsert) {
|
|
1727
2015
|
// insert the ids that need to be referenced for structured clones
|
|
1728
2016
|
let nextId;
|
|
1729
|
-
let distanceToMove = idsToInsert.length *
|
|
2017
|
+
let distanceToMove = idsToInsert.length * 2;
|
|
1730
2018
|
let lastEnd = serialized.length - distanceToMove;
|
|
1731
2019
|
idsToInsert.sort((a, b) => a.offset > b.offset ? 1 : -1);
|
|
2020
|
+
for (let id = 0; id < idsToInsert.length; id++) {
|
|
2021
|
+
let referee = idsToInsert[id];
|
|
2022
|
+
referee.id = id;
|
|
2023
|
+
for (let position of referee.references) {
|
|
2024
|
+
serialized[position++] = id >> 8;
|
|
2025
|
+
serialized[position] = id & 0xff;
|
|
2026
|
+
}
|
|
2027
|
+
}
|
|
1732
2028
|
while (nextId = idsToInsert.pop()) {
|
|
1733
2029
|
let offset = nextId.offset;
|
|
1734
|
-
let id = nextId.id;
|
|
1735
2030
|
serialized.copyWithin(offset + distanceToMove, offset, lastEnd);
|
|
1736
|
-
distanceToMove -=
|
|
2031
|
+
distanceToMove -= 2;
|
|
1737
2032
|
let position = offset + distanceToMove;
|
|
1738
|
-
serialized[position++] =
|
|
1739
|
-
serialized[position++] =
|
|
1740
|
-
serialized[position++] = 40009 & 0xff;
|
|
1741
|
-
serialized[position++] = 0x1a; // uint32
|
|
1742
|
-
serialized[position++] = id >> 24;
|
|
1743
|
-
serialized[position++] = (id >> 16) & 0xff;
|
|
1744
|
-
serialized[position++] = (id >> 8) & 0xff;
|
|
1745
|
-
serialized[position++] = id & 0xff;
|
|
2033
|
+
serialized[position++] = 0xd8;
|
|
2034
|
+
serialized[position++] = 28; // http://cbor.schmorp.de/value-sharing
|
|
1746
2035
|
lastEnd = offset;
|
|
1747
2036
|
}
|
|
1748
2037
|
return serialized
|
|
1749
2038
|
}
|
|
2039
|
+
function writeBundles(start, encode) {
|
|
2040
|
+
targetView.setUint32(bundledStrings$1.position + start, position$1 - bundledStrings$1.position - start + 1); // the offset to bundle
|
|
2041
|
+
let writeStrings = bundledStrings$1;
|
|
2042
|
+
bundledStrings$1 = null;
|
|
2043
|
+
encode(writeStrings[0]);
|
|
2044
|
+
encode(writeStrings[1]);
|
|
2045
|
+
}
|
|
1750
2046
|
|
|
1751
2047
|
function addExtension$1(extension) {
|
|
1752
2048
|
if (extension.Class) {
|
|
@@ -1760,7 +2056,8 @@ function addExtension$1(extension) {
|
|
|
1760
2056
|
let defaultEncoder = new Encoder({ useRecords: false });
|
|
1761
2057
|
const encode = defaultEncoder.encode;
|
|
1762
2058
|
const { NEVER, ALWAYS, DECIMAL_ROUND, DECIMAL_FIT } = FLOAT32_OPTIONS;
|
|
1763
|
-
const REUSE_BUFFER_MODE =
|
|
2059
|
+
const REUSE_BUFFER_MODE = 512;
|
|
2060
|
+
const RESET_BUFFER_MODE = 1024;
|
|
1764
2061
|
|
|
1765
2062
|
class EncoderStream extends stream.Transform {
|
|
1766
2063
|
constructor(options) {
|
|
@@ -1910,9 +2207,7 @@ function tryRequire(moduleId) {
|
|
|
1910
2207
|
let require$1 = module$1.createRequire((typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('node.cjs', document.baseURI).href)));
|
|
1911
2208
|
return require$1(moduleId)
|
|
1912
2209
|
} catch (error) {
|
|
1913
|
-
if (typeof window
|
|
1914
|
-
console.warn('Native extraction module not loaded, cbor-x will still run, but with decreased performance. ' + error.message.split('\n')[0]);
|
|
1915
|
-
else
|
|
2210
|
+
if (typeof window != 'undefined')
|
|
1916
2211
|
console.warn('For browser usage, directly use cbor-x/decode or cbor-x/encode modules. ' + error.message.split('\n')[0]);
|
|
1917
2212
|
}
|
|
1918
2213
|
}
|