cbor-x 1.3.1 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -4,2149 +4,2166 @@
4
4
  (global = global || self, factory(global.CBOR = {}));
5
5
  }(this, (function (exports) { 'use strict';
6
6
 
7
- let decoder;
8
- try {
9
- decoder = new TextDecoder();
10
- } catch(error) {}
11
- let src;
12
- let srcEnd;
13
- let position = 0;
14
- const LEGACY_RECORD_INLINE_ID = 105;
15
- const RECORD_DEFINITIONS_ID = 0xdffe;
16
- const RECORD_INLINE_ID = 0xdfff; // temporary first-come first-serve tag // proposed tag: 0x7265 // 're'
17
- const BUNDLED_STRINGS_ID = 0xdff9;
18
- const PACKED_REFERENCE_TAG_ID = 6;
19
- const STOP_CODE = {};
20
- let currentDecoder = {};
21
- let currentStructures;
22
- let srcString;
23
- let srcStringStart = 0;
24
- let srcStringEnd = 0;
25
- let bundledStrings;
26
- let referenceMap;
27
- let currentExtensions = [];
28
- let currentExtensionRanges = [];
29
- let packedValues;
30
- let dataView;
31
- let restoreMapsAsObject;
32
- let defaultOptions = {
33
- useRecords: false,
34
- mapsAsObjects: true
35
- };
36
- let sequentialMode = false;
37
-
38
- class Decoder {
39
- constructor(options) {
40
- if (options) {
41
- if ((options.keyMap || options._keyMap) && !options.useRecords) {
42
- options.useRecords = false;
43
- options.mapsAsObjects = true;
44
- }
45
- if (options.useRecords === false && options.mapsAsObjects === undefined)
46
- options.mapsAsObjects = true;
47
- if (options.getStructures)
48
- options.getShared = options.getStructures;
49
- if (options.getShared && !options.structures)
50
- (options.structures = []).uninitialized = true; // this is what we use to denote an uninitialized structures
51
- if (options.keyMap) {
52
- this.mapKey = new Map();
53
- for (let [k,v] of Object.entries(options.keyMap)) this.mapKey.set(v,k);
54
- }
55
- }
56
- Object.assign(this, options);
57
- }
58
- /*
59
- decodeKey(key) {
60
- return this.keyMap
61
- ? Object.keys(this.keyMap)[Object.values(this.keyMap).indexOf(key)] || key
62
- : key
63
- }
64
- */
65
- decodeKey(key) {
66
- return this.keyMap ? this.mapKey.get(key) || key : key
67
- }
68
-
69
- encodeKey(key) {
70
- return this.keyMap && this.keyMap.hasOwnProperty(key) ? this.keyMap[key] : key
71
- }
72
-
73
- encodeKeys(rec) {
74
- if (!this._keyMap) return rec
75
- let map = new Map();
76
- for (let [k,v] of Object.entries(rec)) map.set((this._keyMap.hasOwnProperty(k) ? this._keyMap[k] : k), v);
77
- return map
78
- }
79
-
80
- decodeKeys(map) {
81
- if (!this._keyMap || map.constructor.name != 'Map') return map
82
- if (!this._mapKey) {
83
- this._mapKey = new Map();
84
- for (let [k,v] of Object.entries(this._keyMap)) this._mapKey.set(v,k);
85
- }
86
- let res = {};
87
- //map.forEach((v,k) => res[Object.keys(this._keyMap)[Object.values(this._keyMap).indexOf(k)] || k] = v)
88
- map.forEach((v,k) => res[this._mapKey.has(k) ? this._mapKey.get(k) : k] = v);
89
- return res
90
- }
91
-
92
- mapDecode(source, end) {
93
-
94
- let res = this.decode(source);
95
- if (this._keyMap) {
96
- //Experiemntal support for Optimised KeyMap decoding
97
- switch (res.constructor.name) {
98
- case 'Array': return res.map(r => this.decodeKeys(r))
99
- //case 'Map': return this.decodeKeys(res)
100
- }
101
- }
102
- return res
103
- }
104
-
105
- decode(source, end) {
106
- if (src) {
107
- // re-entrant execution, save the state and restore it after we do this decode
108
- return saveState(() => {
109
- clearSource();
110
- return this ? this.decode(source, end) : Decoder.prototype.decode.call(defaultOptions, source, end)
111
- })
112
- }
113
- srcEnd = end > -1 ? end : source.length;
114
- position = 0;
115
- srcStringEnd = 0;
116
- srcString = null;
117
- bundledStrings = null;
118
- src = source;
119
- // this provides cached access to the data view for a buffer if it is getting reused, which is a recommend
120
- // technique for getting data from a database where it can be copied into an existing buffer instead of creating
121
- // new ones
122
- try {
123
- dataView = source.dataView || (source.dataView = new DataView(source.buffer, source.byteOffset, source.byteLength));
124
- } catch(error) {
125
- // if it doesn't have a buffer, maybe it is the wrong type of object
126
- src = null;
127
- if (source instanceof Uint8Array)
128
- throw error
129
- throw new Error('Source must be a Uint8Array or Buffer but was a ' + ((source && typeof source == 'object') ? source.constructor.name : typeof source))
130
- }
131
- if (this instanceof Decoder) {
132
- currentDecoder = this;
133
- packedValues = this.sharedValues &&
134
- (this.pack ? new Array(this.maxPrivatePackedValues || 16).concat(this.sharedValues) :
135
- this.sharedValues);
136
- if (this.structures) {
137
- currentStructures = this.structures;
138
- return checkedRead()
139
- } else if (!currentStructures || currentStructures.length > 0) {
140
- currentStructures = [];
141
- }
142
- } else {
143
- currentDecoder = defaultOptions;
144
- if (!currentStructures || currentStructures.length > 0)
145
- currentStructures = [];
146
- packedValues = null;
147
- }
148
- return checkedRead()
149
- }
150
- decodeMultiple(source, forEach) {
151
- let values, lastPosition = 0;
152
- try {
153
- let size = source.length;
154
- sequentialMode = true;
155
- let value = this ? this.decode(source, size) : defaultDecoder.decode(source, size);
156
- if (forEach) {
157
- if (forEach(value) === false) {
158
- return
159
- }
160
- while(position < size) {
161
- lastPosition = position;
162
- if (forEach(checkedRead()) === false) {
163
- return
164
- }
165
- }
166
- }
167
- else {
168
- values = [ value ];
169
- while(position < size) {
170
- lastPosition = position;
171
- values.push(checkedRead());
172
- }
173
- return values
174
- }
175
- } catch(error) {
176
- error.lastPosition = lastPosition;
177
- error.values = values;
178
- throw error
179
- } finally {
180
- sequentialMode = false;
181
- clearSource();
182
- }
183
- }
184
- }
185
- function checkedRead() {
186
- try {
187
- let result = read();
188
- if (bundledStrings) // bundled strings to skip past
189
- position = bundledStrings.postBundlePosition;
190
-
191
- if (position == srcEnd) {
192
- // finished reading this source, cleanup references
193
- currentStructures = null;
194
- src = null;
195
- if (referenceMap)
196
- referenceMap = null;
197
- } else if (position > srcEnd) {
198
- // over read
199
- let error = new Error('Unexpected end of CBOR data');
200
- error.incomplete = true;
201
- throw error
202
- } else if (!sequentialMode) {
203
- throw new Error('Data read, but end of buffer not reached')
204
- }
205
- // else more to read, but we are reading sequentially, so don't clear source yet
206
- return result
207
- } catch(error) {
208
- clearSource();
209
- if (error instanceof RangeError || error.message.startsWith('Unexpected end of buffer')) {
210
- error.incomplete = true;
211
- }
212
- throw error
213
- }
214
- }
215
-
216
- function read() {
217
- let token = src[position++];
218
- let majorType = token >> 5;
219
- token = token & 0x1f;
220
- if (token > 0x17) {
221
- switch (token) {
222
- case 0x18:
223
- token = src[position++];
224
- break
225
- case 0x19:
226
- if (majorType == 7) {
227
- return getFloat16()
228
- }
229
- token = dataView.getUint16(position);
230
- position += 2;
231
- break
232
- case 0x1a:
233
- if (majorType == 7) {
234
- let value = dataView.getFloat32(position);
235
- if (currentDecoder.useFloat32 > 2) {
236
- // this does rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
237
- let multiplier = mult10[((src[position] & 0x7f) << 1) | (src[position + 1] >> 7)];
238
- position += 4;
239
- return ((multiplier * value + (value > 0 ? 0.5 : -0.5)) >> 0) / multiplier
240
- }
241
- position += 4;
242
- return value
243
- }
244
- token = dataView.getUint32(position);
245
- position += 4;
246
- break
247
- case 0x1b:
248
- if (majorType == 7) {
249
- let value = dataView.getFloat64(position);
250
- position += 8;
251
- return value
252
- }
253
- if (majorType > 1) {
254
- if (dataView.getUint32(position) > 0)
255
- throw new Error('JavaScript does not support arrays, maps, or strings with length over 4294967295')
256
- token = dataView.getUint32(position + 4);
257
- } else if (currentDecoder.int64AsNumber) {
258
- token = dataView.getUint32(position) * 0x100000000;
259
- token += dataView.getUint32(position + 4);
260
- } else
261
- token = dataView.getBigUint64(position);
262
- position += 8;
263
- break
264
- case 0x1f:
265
- // indefinite length
266
- switch(majorType) {
267
- case 2: // byte string
268
- case 3: // text string
269
- throw new Error('Indefinite length not supported for byte or text strings')
270
- case 4: // array
271
- let array = [];
272
- let value, i = 0;
273
- while ((value = read()) != STOP_CODE) {
274
- array[i++] = value;
275
- }
276
- return majorType == 4 ? array : majorType == 3 ? array.join('') : Buffer.concat(array)
277
- case 5: // map
278
- let key;
279
- if (currentDecoder.mapsAsObjects) {
280
- let object = {};
281
- if (currentDecoder.keyMap) while((key = read()) != STOP_CODE) object[currentDecoder.decodeKey(key)] = read();
282
- else while ((key = read()) != STOP_CODE) object[key] = read();
283
- return object
284
- } else {
285
- if (restoreMapsAsObject) {
286
- currentDecoder.mapsAsObjects = true;
287
- restoreMapsAsObject = false;
288
- }
289
- let map = new Map();
290
- if (currentDecoder.keyMap) while((key = read()) != STOP_CODE) map.set(currentDecoder.decodeKey(key), read());
291
- else while ((key = read()) != STOP_CODE) map.set(key, read());
292
- return map
293
- }
294
- case 7:
295
- return STOP_CODE
296
- default:
297
- throw new Error('Invalid major type for indefinite length ' + majorType)
298
- }
299
- default:
300
- throw new Error('Unknown token ' + token)
301
- }
302
- }
303
- switch (majorType) {
304
- case 0: // positive int
305
- return token
306
- case 1: // negative int
307
- return ~token
308
- case 2: // buffer
309
- return readBin(token)
310
- case 3: // string
311
- if (srcStringEnd >= position) {
312
- return srcString.slice(position - srcStringStart, (position += token) - srcStringStart)
313
- }
314
- if (srcStringEnd == 0 && srcEnd < 140 && token < 32) {
315
- // for small blocks, avoiding the overhead of the extract call is helpful
316
- let string = token < 16 ? shortStringInJS(token) : longStringInJS(token);
317
- if (string != null)
318
- return string
319
- }
320
- return readFixedString(token)
321
- case 4: // array
322
- let array = new Array(token);
323
- //if (currentDecoder.keyMap) for (let i = 0; i < token; i++) array[i] = currentDecoder.decodeKey(read())
324
- //else
325
- for (let i = 0; i < token; i++) array[i] = read();
326
- return array
327
- case 5: // map
328
- if (currentDecoder.mapsAsObjects) {
329
- let object = {};
330
- if (currentDecoder.keyMap) for (let i = 0; i < token; i++) object[currentDecoder.decodeKey(read())] = read();
331
- else for (let i = 0; i < token; i++) object[read()] = read();
332
- return object
333
- } else {
334
- if (restoreMapsAsObject) {
335
- currentDecoder.mapsAsObjects = true;
336
- restoreMapsAsObject = false;
337
- }
338
- let map = new Map();
339
- if (currentDecoder.keyMap) for (let i = 0; i < token; i++) map.set(currentDecoder.decodeKey(read()),read());
340
- else for (let i = 0; i < token; i++) map.set(read(), read());
341
- return map
342
- }
343
- case 6: // extension
344
- if (token >= BUNDLED_STRINGS_ID) {
345
- let structure = currentStructures[token & 0x1fff]; // check record structures first
346
- // 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))
347
- if (structure) {
348
- if (!structure.read) structure.read = createStructureReader(structure);
349
- return structure.read()
350
- }
351
- if (token < 0x10000) {
352
- 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)
353
- return recordDefinition(read())
354
- else if (token == RECORD_DEFINITIONS_ID) {
355
- let length = readJustLength();
356
- let id = read();
357
- for (let i = 2; i < length; i++) {
358
- recordDefinition([id++, read()]);
359
- }
360
- return read()
361
- } else if (token == BUNDLED_STRINGS_ID) {
362
- return readBundleExt()
363
- }
364
- if (currentDecoder.getShared) {
365
- loadShared();
366
- structure = currentStructures[token & 0x1fff];
367
- if (structure) {
368
- if (!structure.read)
369
- structure.read = createStructureReader(structure);
370
- return structure.read()
371
- }
372
- }
373
- }
374
- }
375
- let extension = currentExtensions[token];
376
- if (extension) {
377
- if (extension.handlesRead)
378
- return extension(read)
379
- else
380
- return extension(read())
381
- } else {
382
- let input = read();
383
- for (let i = 0; i < currentExtensionRanges.length; i++) {
384
- let value = currentExtensionRanges[i](token, input);
385
- if (value !== undefined)
386
- return value
387
- }
388
- return new Tag(input, token)
389
- }
390
- case 7: // fixed value
391
- switch (token) {
392
- case 0x14: return false
393
- case 0x15: return true
394
- case 0x16: return null
395
- case 0x17: return; // undefined
396
- case 0x1f:
397
- default:
398
- let packedValue = (packedValues || getPackedValues())[token];
399
- if (packedValue !== undefined)
400
- return packedValue
401
- throw new Error('Unknown token ' + token)
402
- }
403
- default: // negative int
404
- if (isNaN(token)) {
405
- let error = new Error('Unexpected end of CBOR data');
406
- error.incomplete = true;
407
- throw error
408
- }
409
- throw new Error('Unknown CBOR token ' + token)
410
- }
411
- }
412
- const validName = /^[a-zA-Z_$][a-zA-Z\d_$]*$/;
413
- function createStructureReader(structure) {
414
- function readObject() {
415
- // get the array size from the header
416
- let length = src[position++];
417
- //let majorType = token >> 5
418
- length = length & 0x1f;
419
- if (length > 0x17) {
420
- switch (length) {
421
- case 0x18:
422
- length = src[position++];
423
- break
424
- case 0x19:
425
- length = dataView.getUint16(position);
426
- position += 2;
427
- break
428
- case 0x1a:
429
- length = dataView.getUint32(position);
430
- position += 4;
431
- break
432
- default:
433
- throw new Error('Expected array header, but got ' + src[position - 1])
434
- }
435
- }
436
- // This initial function is quick to instantiate, but runs slower. After several iterations pay the cost to build the faster function
437
- let compiledReader = this.compiledReader; // first look to see if we have the fast compiled function
438
- while(compiledReader) {
439
- // we have a fast compiled object literal reader
440
- if (compiledReader.propertyCount === length)
441
- return compiledReader(read) // with the right length, so we use it
442
- compiledReader = compiledReader.next; // see if there is another reader with the right length
443
- }
444
- if (this.slowReads++ >= 3) { // create a fast compiled reader
445
- let array = this.length == length ? this : this.slice(0, length);
446
- compiledReader = currentDecoder.keyMap
447
- ? new Function('r', 'return {' + array.map(k => currentDecoder.decodeKey(k)).map(k => validName.test(k) ? k + ':r()' : ('[' + JSON.stringify(k) + ']:r()')).join(',') + '}')
448
- : new Function('r', 'return {' + array.map(key => validName.test(key) ? key + ':r()' : ('[' + JSON.stringify(key) + ']:r()')).join(',') + '}');
449
- if (this.compiledReader)
450
- compiledReader.next = this.compiledReader; // if there is an existing one, we store multiple readers as a linked list because it is usually pretty rare to have multiple readers (of different length) for the same structure
451
- compiledReader.propertyCount = length;
452
- this.compiledReader = compiledReader;
453
- return compiledReader(read)
454
- }
455
- let object = {};
456
- if (currentDecoder.keyMap) for (let i = 0; i < length; i++) object[currentDecoder.decodeKey(this[i])] = read();
457
- else for (let i = 0; i < length; i++) object[this[i]] = read();
458
- return object
459
- }
460
- structure.slowReads = 0;
461
- return readObject
462
- }
463
-
464
- let readFixedString = readStringJS;
465
-
466
- let isNativeAccelerationEnabled = false;
467
- function readStringJS(length) {
468
- let result;
469
- if (length < 16) {
470
- if (result = shortStringInJS(length))
471
- return result
472
- }
473
- if (length > 64 && decoder)
474
- return decoder.decode(src.subarray(position, position += length))
475
- const end = position + length;
476
- const units = [];
477
- result = '';
478
- while (position < end) {
479
- const byte1 = src[position++];
480
- if ((byte1 & 0x80) === 0) {
481
- // 1 byte
482
- units.push(byte1);
483
- } else if ((byte1 & 0xe0) === 0xc0) {
484
- // 2 bytes
485
- const byte2 = src[position++] & 0x3f;
486
- units.push(((byte1 & 0x1f) << 6) | byte2);
487
- } else if ((byte1 & 0xf0) === 0xe0) {
488
- // 3 bytes
489
- const byte2 = src[position++] & 0x3f;
490
- const byte3 = src[position++] & 0x3f;
491
- units.push(((byte1 & 0x1f) << 12) | (byte2 << 6) | byte3);
492
- } else if ((byte1 & 0xf8) === 0xf0) {
493
- // 4 bytes
494
- const byte2 = src[position++] & 0x3f;
495
- const byte3 = src[position++] & 0x3f;
496
- const byte4 = src[position++] & 0x3f;
497
- let unit = ((byte1 & 0x07) << 0x12) | (byte2 << 0x0c) | (byte3 << 0x06) | byte4;
498
- if (unit > 0xffff) {
499
- unit -= 0x10000;
500
- units.push(((unit >>> 10) & 0x3ff) | 0xd800);
501
- unit = 0xdc00 | (unit & 0x3ff);
502
- }
503
- units.push(unit);
504
- } else {
505
- units.push(byte1);
506
- }
507
-
508
- if (units.length >= 0x1000) {
509
- result += fromCharCode.apply(String, units);
510
- units.length = 0;
511
- }
512
- }
513
-
514
- if (units.length > 0) {
515
- result += fromCharCode.apply(String, units);
516
- }
517
-
518
- return result
519
- }
520
- let fromCharCode = String.fromCharCode;
521
- function longStringInJS(length) {
522
- let start = position;
523
- let bytes = new Array(length);
524
- for (let i = 0; i < length; i++) {
525
- const byte = src[position++];
526
- if ((byte & 0x80) > 0) {
527
- position = start;
528
- return
529
- }
530
- bytes[i] = byte;
531
- }
532
- return fromCharCode.apply(String, bytes)
533
- }
534
- function shortStringInJS(length) {
535
- if (length < 4) {
536
- if (length < 2) {
537
- if (length === 0)
538
- return ''
539
- else {
540
- let a = src[position++];
541
- if ((a & 0x80) > 1) {
542
- position -= 1;
543
- return
544
- }
545
- return fromCharCode(a)
546
- }
547
- } else {
548
- let a = src[position++];
549
- let b = src[position++];
550
- if ((a & 0x80) > 0 || (b & 0x80) > 0) {
551
- position -= 2;
552
- return
553
- }
554
- if (length < 3)
555
- return fromCharCode(a, b)
556
- let c = src[position++];
557
- if ((c & 0x80) > 0) {
558
- position -= 3;
559
- return
560
- }
561
- return fromCharCode(a, b, c)
562
- }
563
- } else {
564
- let a = src[position++];
565
- let b = src[position++];
566
- let c = src[position++];
567
- let d = src[position++];
568
- if ((a & 0x80) > 0 || (b & 0x80) > 0 || (c & 0x80) > 0 || (d & 0x80) > 0) {
569
- position -= 4;
570
- return
571
- }
572
- if (length < 6) {
573
- if (length === 4)
574
- return fromCharCode(a, b, c, d)
575
- else {
576
- let e = src[position++];
577
- if ((e & 0x80) > 0) {
578
- position -= 5;
579
- return
580
- }
581
- return fromCharCode(a, b, c, d, e)
582
- }
583
- } else if (length < 8) {
584
- let e = src[position++];
585
- let f = src[position++];
586
- if ((e & 0x80) > 0 || (f & 0x80) > 0) {
587
- position -= 6;
588
- return
589
- }
590
- if (length < 7)
591
- return fromCharCode(a, b, c, d, e, f)
592
- let g = src[position++];
593
- if ((g & 0x80) > 0) {
594
- position -= 7;
595
- return
596
- }
597
- return fromCharCode(a, b, c, d, e, f, g)
598
- } else {
599
- let e = src[position++];
600
- let f = src[position++];
601
- let g = src[position++];
602
- let h = src[position++];
603
- if ((e & 0x80) > 0 || (f & 0x80) > 0 || (g & 0x80) > 0 || (h & 0x80) > 0) {
604
- position -= 8;
605
- return
606
- }
607
- if (length < 10) {
608
- if (length === 8)
609
- return fromCharCode(a, b, c, d, e, f, g, h)
610
- else {
611
- let i = src[position++];
612
- if ((i & 0x80) > 0) {
613
- position -= 9;
614
- return
615
- }
616
- return fromCharCode(a, b, c, d, e, f, g, h, i)
617
- }
618
- } else if (length < 12) {
619
- let i = src[position++];
620
- let j = src[position++];
621
- if ((i & 0x80) > 0 || (j & 0x80) > 0) {
622
- position -= 10;
623
- return
624
- }
625
- if (length < 11)
626
- return fromCharCode(a, b, c, d, e, f, g, h, i, j)
627
- let k = src[position++];
628
- if ((k & 0x80) > 0) {
629
- position -= 11;
630
- return
631
- }
632
- return fromCharCode(a, b, c, d, e, f, g, h, i, j, k)
633
- } else {
634
- let i = src[position++];
635
- let j = src[position++];
636
- let k = src[position++];
637
- let l = src[position++];
638
- if ((i & 0x80) > 0 || (j & 0x80) > 0 || (k & 0x80) > 0 || (l & 0x80) > 0) {
639
- position -= 12;
640
- return
641
- }
642
- if (length < 14) {
643
- if (length === 12)
644
- return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l)
645
- else {
646
- let m = src[position++];
647
- if ((m & 0x80) > 0) {
648
- position -= 13;
649
- return
650
- }
651
- return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m)
652
- }
653
- } else {
654
- let m = src[position++];
655
- let n = src[position++];
656
- if ((m & 0x80) > 0 || (n & 0x80) > 0) {
657
- position -= 14;
658
- return
659
- }
660
- if (length < 15)
661
- return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m, n)
662
- let o = src[position++];
663
- if ((o & 0x80) > 0) {
664
- position -= 15;
665
- return
666
- }
667
- return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
668
- }
669
- }
670
- }
671
- }
672
- }
673
-
674
- function readBin(length) {
675
- return currentDecoder.copyBuffers ?
676
- // specifically use the copying slice (not the node one)
677
- Uint8Array.prototype.slice.call(src, position, position += length) :
678
- src.subarray(position, position += length)
679
- }
680
-
681
- function getFloat16() {
682
- let byte0 = src[position++];
683
- let byte1 = src[position++];
684
- let half = (byte0 << 8) + byte1;
685
- let exp = (half >> 10) & 0x1f;
686
- let mant = half & 0x3ff;
687
- let val;
688
- if (exp == 0) val = Math.exp(mant, -24);
689
- else if (exp != 31) val = Math.exp(mant + 1024, exp - 25);
690
- else val = mant == 0 ? Infinity : NaN;
691
- return half & 0x8000 ? -val : val
692
- }
693
-
694
- let keyCache = new Array(4096);
695
-
696
- class Tag {
697
- constructor(value, tag) {
698
- this.value = value;
699
- this.tag = tag;
700
- }
701
- }
702
-
703
- let glbl = typeof self == 'object' ? self : global;
704
-
705
- currentExtensions[0] = (dateString) => {
706
- // string date extension
707
- return new Date(dateString)
708
- };
709
-
710
- currentExtensions[1] = (epochSec) => {
711
- // numeric date extension
712
- return new Date(Math.round(epochSec * 1000))
713
- };
714
-
715
- currentExtensions[2] = (buffer) => {
716
- // bigint extension
717
- let value = BigInt(0);
718
- for (let i = 0, l = buffer.byteLength; i < l; i++) {
719
- value = BigInt(buffer[i]) + value << BigInt(8);
720
- }
721
- return value
722
- };
723
-
724
- currentExtensions[3] = (buffer) => {
725
- // negative bigint extension
726
- return BigInt(-1) - currentExtensions[2](buffer)
727
- };
728
- currentExtensions[4] = (fraction) => {
729
- // best to reparse to maintain accuracy
730
- return +(fraction[1] + 'e' + fraction[0])
731
- };
732
-
733
- currentExtensions[5] = (fraction) => {
734
- // probably not sufficiently accurate
735
- return fraction[1] * Math.exp(fraction[0] * Math.log(2))
736
- };
737
-
738
- // the registration of the record definition extension
739
- const recordDefinition = (definition) => {
740
- let id = definition[0] - 0xe000;
741
- let structure = definition[1];
742
- let existingStructure = currentStructures[id];
743
- if (existingStructure && existingStructure.isShared) {
744
- (currentStructures.restoreStructures || (currentStructures.restoreStructures = []))[id] = existingStructure;
745
- }
746
- currentStructures[id] = structure;
747
-
748
- structure.read = createStructureReader(structure);
749
- let object = {};
750
- if (currentDecoder.keyMap) for (let i = 2,l = definition.length; i < l; i++) {
751
- let key = currentDecoder.decodeKey(structure[i - 2]);
752
- object[key] = definition[i];
753
- }
754
- else for (let i = 2,l = definition.length; i < l; i++) {
755
- let key = structure[i - 2];
756
- object[key] = definition[i];
757
- }
758
- return object
759
- };
760
- currentExtensions[LEGACY_RECORD_INLINE_ID] = recordDefinition;
761
- currentExtensions[14] = (value) => {
762
- if (bundledStrings)
763
- return bundledStrings[0].slice(bundledStrings.position0, bundledStrings.position0 += value)
764
- return new Tag(value, 14)
765
- };
766
- currentExtensions[15] = (value) => {
767
- if (bundledStrings)
768
- return bundledStrings[1].slice(bundledStrings.position1, bundledStrings.position1 += value)
769
- return new Tag(value, 15)
770
- };
771
-
772
- currentExtensions[27] = (data) => { // http://cbor.schmorp.de/generic-object
773
- return (glbl[data[0]] || Error)(data[1], data[2])
774
- };
775
- const packedTable = (read) => {
776
- if (src[position++] != 0x84)
777
- throw new Error('Packed values structure must be followed by a 4 element array')
778
- let newPackedValues = read(); // packed values
779
- packedValues = packedValues ? newPackedValues.concat(packedValues.slice(newPackedValues.length)) : newPackedValues;
780
- packedValues.prefixes = read();
781
- packedValues.suffixes = read();
782
- return read() // read the rump
783
- };
784
- packedTable.handlesRead = true;
785
- currentExtensions[51] = packedTable;
786
-
787
- currentExtensions[PACKED_REFERENCE_TAG_ID] = (data) => { // packed reference
788
- if (!packedValues) {
789
- if (currentDecoder.getShared)
790
- loadShared();
791
- else
792
- return new Tag(data, PACKED_REFERENCE_TAG_ID)
793
- }
794
- if (typeof data == 'number')
795
- return packedValues[16 + (data >= 0 ? 2 * data : (-2 * data - 1))]
796
- throw new Error('No support for non-integer packed references yet')
797
- };
798
- currentExtensions[25] = (id) => {
799
- return stringRefs[id]
800
- };
801
- currentExtensions[256] = (read) => {
802
- stringRefs = [];
803
- try {
804
- return read()
805
- } finally {
806
- stringRefs = null;
807
- }
808
- };
809
- currentExtensions[256].handlesRead = true;
810
-
811
- currentExtensions[28] = (read) => {
812
- // shareable http://cbor.schmorp.de/value-sharing (for structured clones)
813
- if (!referenceMap) {
814
- referenceMap = new Map();
815
- referenceMap.id = 0;
816
- }
817
- let id = referenceMap.id++;
818
- let token = src[position];
819
- let target;
820
- // TODO: handle Maps, Sets, and other types that can cycle; this is complicated, because you potentially need to read
821
- // ahead past references to record structure definitions
822
- if ((token >> 5) == 4)
823
- target = [];
824
- else
825
- target = {};
826
-
827
- let refEntry = { target }; // a placeholder object
828
- referenceMap.set(id, refEntry);
829
- let targetProperties = read(); // read the next value as the target object to id
830
- if (refEntry.used) // there is a cycle, so we have to assign properties to original target
831
- return Object.assign(target, targetProperties)
832
- refEntry.target = targetProperties; // the placeholder wasn't used, replace with the deserialized one
833
- return targetProperties // no cycle, can just use the returned read object
834
- };
835
- currentExtensions[28].handlesRead = true;
836
-
837
- currentExtensions[29] = (id) => {
838
- // sharedref http://cbor.schmorp.de/value-sharing (for structured clones)
839
- let refEntry = referenceMap.get(id);
840
- refEntry.used = true;
841
- return refEntry.target
842
- };
843
-
844
- currentExtensions[258] = (array) => new Set(array); // https://github.com/input-output-hk/cbor-sets-spec/blob/master/CBOR_SETS.md
845
- (currentExtensions[259] = (read) => {
846
- // https://github.com/shanewholloway/js-cbor-codec/blob/master/docs/CBOR-259-spec
847
- // for decoding as a standard Map
848
- if (currentDecoder.mapsAsObjects) {
849
- currentDecoder.mapsAsObjects = false;
850
- restoreMapsAsObject = true;
851
- }
852
- return read()
853
- }).handlesRead = true;
854
- function combine(a, b) {
855
- if (typeof a === 'string')
856
- return a + b
857
- if (a instanceof Array)
858
- return a.concat(b)
859
- return Object.assign({}, a, b)
860
- }
861
- function getPackedValues() {
862
- if (!packedValues) {
863
- if (currentDecoder.getShared)
864
- loadShared();
865
- else
866
- throw new Error('No packed values available')
867
- }
868
- return packedValues
869
- }
870
- const SHARED_DATA_TAG_ID = 0x53687264; // ascii 'Shrd'
871
- currentExtensionRanges.push((tag, input) => {
872
- if (tag >= 225 && tag <= 255)
873
- return combine(getPackedValues().prefixes[tag - 224], input)
874
- if (tag >= 28704 && tag <= 32767)
875
- return combine(getPackedValues().prefixes[tag - 28672], input)
876
- if (tag >= 1879052288 && tag <= 2147483647)
877
- return combine(getPackedValues().prefixes[tag - 1879048192], input)
878
- if (tag >= 216 && tag <= 223)
879
- return combine(input, getPackedValues().suffixes[tag - 216])
880
- if (tag >= 27647 && tag <= 28671)
881
- return combine(input, getPackedValues().suffixes[tag - 27639])
882
- if (tag >= 1811940352 && tag <= 1879048191)
883
- return combine(input, getPackedValues().suffixes[tag - 1811939328])
884
- 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)
885
- return {
886
- packedValues: packedValues,
887
- structures: currentStructures.slice(0),
888
- version: input,
889
- }
890
- }
891
- if (tag == 55799) // self-descriptive CBOR tag, just return input value
892
- return input
893
- });
894
-
895
- const isLittleEndianMachine = new Uint8Array(new Uint16Array([1]).buffer)[0] == 1;
896
- const typedArrays = ['Uint8', 'Uint8Clamped', 'Uint16', 'Uint32', 'BigUint64','Int8', 'Int16', 'Int32', 'BigInt64', 'Float32', 'Float64'];
897
- const typedArrayTags = [64, 68, 69, 70, 71, 72, 77, 78, 79, 85, 86];
898
- for (let i = 0; i < typedArrays.length; i++) {
899
- registerTypedArray(typedArrays[i], typedArrayTags[i]);
900
- }
901
- function registerTypedArray(typedArrayId, tag, littleEndian) {
902
- let TypedArray = glbl[typedArrayId + 'Array'];
903
- let bytesPerElement = TypedArray.BYTES_PER_ELEMENT;
904
- for (let littleEndian = 0; littleEndian < 2; littleEndian++) {
905
- if (!littleEndian && bytesPerElement == 1)
906
- continue
907
- let sizeShift = bytesPerElement == 2 ? 1 : bytesPerElement == 4 ? 2 : 3;
908
- currentExtensions[littleEndian ? tag : (tag - 4)] = (bytesPerElement == 1 || littleEndian == isLittleEndianMachine) ? (buffer) => {
909
- if (!TypedArray)
910
- throw new Error('Could not find typed array for code ' + tag)
911
- // we have to always slice/copy here to get a new ArrayBuffer that is word/byte aligned
912
- return new TypedArray(Uint8Array.prototype.slice.call(buffer, 0).buffer)
913
- } : buffer => {
914
- if (!TypedArray)
915
- throw new Error('Could not find typed array for code ' + tag)
916
- let dv = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
917
- let elements = buffer.length >> sizeShift;
918
- let ta = new TypedArray(elements);
919
- let method = dv['get' + typedArrayId];
920
- for (let i = 0; i < elements; i++) {
921
- ta[i] = method.call(dv, i << sizeShift, littleEndian);
922
- }
923
- return ta
924
- };
925
- }
926
- }
927
-
928
- function readBundleExt() {
929
- let length = readJustLength();
930
- let bundlePosition = position + read();
931
- for (let i = 2; i < length; i++) {
932
- // skip past bundles that were already read
933
- let bundleLength = readJustLength(); // this will increment position, so must add to position afterwards
934
- position += bundleLength;
935
- }
936
- let dataPosition = position;
937
- position = bundlePosition;
938
- bundledStrings = [readStringJS(readJustLength()), readStringJS(readJustLength())];
939
- bundledStrings.position0 = 0;
940
- bundledStrings.position1 = 0;
941
- bundledStrings.postBundlePosition = position;
942
- position = dataPosition;
943
- return read()
944
- }
945
-
946
- function readJustLength() {
947
- let token = src[position++] & 0x1f;
948
- if (token > 0x17) {
949
- switch (token) {
950
- case 0x18:
951
- token = src[position++];
952
- break
953
- case 0x19:
954
- token = dataView.getUint16(position);
955
- position += 2;
956
- break
957
- case 0x1a:
958
- token = dataView.getUint32(position);
959
- position += 4;
960
- break
961
- }
962
- }
963
- return token
964
- }
965
-
966
- function loadShared() {
967
- if (currentDecoder.getShared) {
968
- let sharedData = saveState(() => {
969
- // save the state in case getShared modifies our buffer
970
- src = null;
971
- return currentDecoder.getShared()
972
- }) || {};
973
- let updatedStructures = sharedData.structures || [];
974
- currentDecoder.sharedVersion = sharedData.version;
975
- packedValues = currentDecoder.sharedValues = sharedData.packedValues;
976
- if (currentStructures === true)
977
- currentDecoder.structures = currentStructures = updatedStructures;
978
- else
979
- currentStructures.splice.apply(currentStructures, [0, updatedStructures.length].concat(updatedStructures));
980
- }
981
- }
982
-
983
- function saveState(callback) {
984
- let savedSrcEnd = srcEnd;
985
- let savedPosition = position;
986
- let savedSrcStringStart = srcStringStart;
987
- let savedSrcStringEnd = srcStringEnd;
988
- let savedSrcString = srcString;
989
- let savedReferenceMap = referenceMap;
990
- let savedBundledStrings = bundledStrings;
991
-
992
- // TODO: We may need to revisit this if we do more external calls to user code (since it could be slow)
993
- let savedSrc = new Uint8Array(src.slice(0, srcEnd)); // we copy the data in case it changes while external data is processed
994
- let savedStructures = currentStructures;
995
- let savedDecoder = currentDecoder;
996
- let savedSequentialMode = sequentialMode;
997
- let value = callback();
998
- srcEnd = savedSrcEnd;
999
- position = savedPosition;
1000
- srcStringStart = savedSrcStringStart;
1001
- srcStringEnd = savedSrcStringEnd;
1002
- srcString = savedSrcString;
1003
- referenceMap = savedReferenceMap;
1004
- bundledStrings = savedBundledStrings;
1005
- src = savedSrc;
1006
- sequentialMode = savedSequentialMode;
1007
- currentStructures = savedStructures;
1008
- currentDecoder = savedDecoder;
1009
- dataView = new DataView(src.buffer, src.byteOffset, src.byteLength);
1010
- return value
1011
- }
1012
- function clearSource() {
1013
- src = null;
1014
- referenceMap = null;
1015
- currentStructures = null;
1016
- }
1017
-
1018
- function addExtension(extension) {
1019
- currentExtensions[extension.tag] = extension.decode;
1020
- }
1021
-
1022
- const mult10 = new Array(147); // this is a table matching binary exponents to the multiplier to determine significant digit rounding
1023
- for (let i = 0; i < 256; i++) {
1024
- mult10[i] = +('1e' + Math.floor(45.15 - i * 0.30103));
1025
- }
1026
- let defaultDecoder = new Decoder({ useRecords: false });
1027
- const decode = defaultDecoder.decode;
1028
- const decodeMultiple = defaultDecoder.decodeMultiple;
1029
- const FLOAT32_OPTIONS = {
1030
- NEVER: 0,
1031
- ALWAYS: 1,
1032
- DECIMAL_ROUND: 3,
1033
- DECIMAL_FIT: 4
1034
- };
1035
- let f32Array = new Float32Array(1);
1036
- let u8Array = new Uint8Array(f32Array.buffer, 0, 4);
1037
- function roundFloat32(float32Number) {
1038
- f32Array[0] = float32Number;
1039
- let multiplier = mult10[((u8Array[3] & 0x7f) << 1) | (u8Array[2] >> 7)];
1040
- return ((multiplier * float32Number + (float32Number > 0 ? 0.5 : -0.5)) >> 0) / multiplier
7
+ let decoder;
8
+ try {
9
+ decoder = new TextDecoder();
10
+ } catch(error) {}
11
+ let src;
12
+ let srcEnd;
13
+ let position = 0;
14
+ const LEGACY_RECORD_INLINE_ID = 105;
15
+ const RECORD_DEFINITIONS_ID = 0xdffe;
16
+ const RECORD_INLINE_ID = 0xdfff; // temporary first-come first-serve tag // proposed tag: 0x7265 // 're'
17
+ const BUNDLED_STRINGS_ID = 0xdff9;
18
+ const PACKED_REFERENCE_TAG_ID = 6;
19
+ const STOP_CODE = {};
20
+ let currentDecoder = {};
21
+ let currentStructures;
22
+ let srcString;
23
+ let srcStringStart = 0;
24
+ let srcStringEnd = 0;
25
+ let bundledStrings;
26
+ let referenceMap;
27
+ let currentExtensions = [];
28
+ let currentExtensionRanges = [];
29
+ let packedValues;
30
+ let dataView;
31
+ let restoreMapsAsObject;
32
+ let defaultOptions = {
33
+ useRecords: false,
34
+ mapsAsObjects: true
35
+ };
36
+ let sequentialMode = false;
37
+
38
+ class Decoder {
39
+ constructor(options) {
40
+ if (options) {
41
+ if ((options.keyMap || options._keyMap) && !options.useRecords) {
42
+ options.useRecords = false;
43
+ options.mapsAsObjects = true;
44
+ }
45
+ if (options.useRecords === false && options.mapsAsObjects === undefined)
46
+ options.mapsAsObjects = true;
47
+ if (options.getStructures)
48
+ options.getShared = options.getStructures;
49
+ if (options.getShared && !options.structures)
50
+ (options.structures = []).uninitialized = true; // this is what we use to denote an uninitialized structures
51
+ if (options.keyMap) {
52
+ this.mapKey = new Map();
53
+ for (let [k,v] of Object.entries(options.keyMap)) this.mapKey.set(v,k);
54
+ }
55
+ }
56
+ Object.assign(this, options);
57
+ }
58
+ /*
59
+ decodeKey(key) {
60
+ return this.keyMap
61
+ ? Object.keys(this.keyMap)[Object.values(this.keyMap).indexOf(key)] || key
62
+ : key
63
+ }
64
+ */
65
+ decodeKey(key) {
66
+ return this.keyMap ? this.mapKey.get(key) || key : key
67
+ }
68
+
69
+ encodeKey(key) {
70
+ return this.keyMap && this.keyMap.hasOwnProperty(key) ? this.keyMap[key] : key
71
+ }
72
+
73
+ encodeKeys(rec) {
74
+ if (!this._keyMap) return rec
75
+ let map = new Map();
76
+ for (let [k,v] of Object.entries(rec)) map.set((this._keyMap.hasOwnProperty(k) ? this._keyMap[k] : k), v);
77
+ return map
78
+ }
79
+
80
+ decodeKeys(map) {
81
+ if (!this._keyMap || map.constructor.name != 'Map') return map
82
+ if (!this._mapKey) {
83
+ this._mapKey = new Map();
84
+ for (let [k,v] of Object.entries(this._keyMap)) this._mapKey.set(v,k);
85
+ }
86
+ let res = {};
87
+ //map.forEach((v,k) => res[Object.keys(this._keyMap)[Object.values(this._keyMap).indexOf(k)] || k] = v)
88
+ map.forEach((v,k) => res[this._mapKey.has(k) ? this._mapKey.get(k) : k] = v);
89
+ return res
90
+ }
91
+
92
+ mapDecode(source, end) {
93
+
94
+ let res = this.decode(source);
95
+ if (this._keyMap) {
96
+ //Experiemntal support for Optimised KeyMap decoding
97
+ switch (res.constructor.name) {
98
+ case 'Array': return res.map(r => this.decodeKeys(r))
99
+ //case 'Map': return this.decodeKeys(res)
100
+ }
101
+ }
102
+ return res
103
+ }
104
+
105
+ decode(source, end) {
106
+ if (src) {
107
+ // re-entrant execution, save the state and restore it after we do this decode
108
+ return saveState(() => {
109
+ clearSource();
110
+ return this ? this.decode(source, end) : Decoder.prototype.decode.call(defaultOptions, source, end)
111
+ })
112
+ }
113
+ srcEnd = end > -1 ? end : source.length;
114
+ position = 0;
115
+ srcStringEnd = 0;
116
+ srcString = null;
117
+ bundledStrings = null;
118
+ src = source;
119
+ // this provides cached access to the data view for a buffer if it is getting reused, which is a recommend
120
+ // technique for getting data from a database where it can be copied into an existing buffer instead of creating
121
+ // new ones
122
+ try {
123
+ dataView = source.dataView || (source.dataView = new DataView(source.buffer, source.byteOffset, source.byteLength));
124
+ } catch(error) {
125
+ // if it doesn't have a buffer, maybe it is the wrong type of object
126
+ src = null;
127
+ if (source instanceof Uint8Array)
128
+ throw error
129
+ throw new Error('Source must be a Uint8Array or Buffer but was a ' + ((source && typeof source == 'object') ? source.constructor.name : typeof source))
130
+ }
131
+ if (this instanceof Decoder) {
132
+ currentDecoder = this;
133
+ packedValues = this.sharedValues &&
134
+ (this.pack ? new Array(this.maxPrivatePackedValues || 16).concat(this.sharedValues) :
135
+ this.sharedValues);
136
+ if (this.structures) {
137
+ currentStructures = this.structures;
138
+ return checkedRead()
139
+ } else if (!currentStructures || currentStructures.length > 0) {
140
+ currentStructures = [];
141
+ }
142
+ } else {
143
+ currentDecoder = defaultOptions;
144
+ if (!currentStructures || currentStructures.length > 0)
145
+ currentStructures = [];
146
+ packedValues = null;
147
+ }
148
+ return checkedRead()
149
+ }
150
+ decodeMultiple(source, forEach) {
151
+ let values, lastPosition = 0;
152
+ try {
153
+ let size = source.length;
154
+ sequentialMode = true;
155
+ let value = this ? this.decode(source, size) : defaultDecoder.decode(source, size);
156
+ if (forEach) {
157
+ if (forEach(value) === false) {
158
+ return
159
+ }
160
+ while(position < size) {
161
+ lastPosition = position;
162
+ if (forEach(checkedRead()) === false) {
163
+ return
164
+ }
165
+ }
166
+ }
167
+ else {
168
+ values = [ value ];
169
+ while(position < size) {
170
+ lastPosition = position;
171
+ values.push(checkedRead());
172
+ }
173
+ return values
174
+ }
175
+ } catch(error) {
176
+ error.lastPosition = lastPosition;
177
+ error.values = values;
178
+ throw error
179
+ } finally {
180
+ sequentialMode = false;
181
+ clearSource();
182
+ }
183
+ }
184
+ }
185
+ function checkedRead() {
186
+ try {
187
+ let result = read();
188
+ if (bundledStrings) {
189
+ if (position >= bundledStrings.postBundlePosition) {
190
+ let error = new Error('Unexpected bundle position');
191
+ error.incomplete = true;
192
+ throw error
193
+ }
194
+ // bundled strings to skip past
195
+ position = bundledStrings.postBundlePosition;
196
+ }
197
+
198
+ if (position == srcEnd) {
199
+ // finished reading this source, cleanup references
200
+ currentStructures = null;
201
+ src = null;
202
+ if (referenceMap)
203
+ referenceMap = null;
204
+ } else if (position > srcEnd) {
205
+ // over read
206
+ let error = new Error('Unexpected end of CBOR data');
207
+ error.incomplete = true;
208
+ throw error
209
+ } else if (!sequentialMode) {
210
+ throw new Error('Data read, but end of buffer not reached')
211
+ }
212
+ // else more to read, but we are reading sequentially, so don't clear source yet
213
+ return result
214
+ } catch(error) {
215
+ clearSource();
216
+ if (error instanceof RangeError || error.message.startsWith('Unexpected end of buffer')) {
217
+ error.incomplete = true;
218
+ }
219
+ throw error
220
+ }
221
+ }
222
+
223
+ function read() {
224
+ let token = src[position++];
225
+ let majorType = token >> 5;
226
+ token = token & 0x1f;
227
+ if (token > 0x17) {
228
+ switch (token) {
229
+ case 0x18:
230
+ token = src[position++];
231
+ break
232
+ case 0x19:
233
+ if (majorType == 7) {
234
+ return getFloat16()
235
+ }
236
+ token = dataView.getUint16(position);
237
+ position += 2;
238
+ break
239
+ case 0x1a:
240
+ if (majorType == 7) {
241
+ let value = dataView.getFloat32(position);
242
+ if (currentDecoder.useFloat32 > 2) {
243
+ // this does rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
244
+ let multiplier = mult10[((src[position] & 0x7f) << 1) | (src[position + 1] >> 7)];
245
+ position += 4;
246
+ return ((multiplier * value + (value > 0 ? 0.5 : -0.5)) >> 0) / multiplier
247
+ }
248
+ position += 4;
249
+ return value
250
+ }
251
+ token = dataView.getUint32(position);
252
+ position += 4;
253
+ break
254
+ case 0x1b:
255
+ if (majorType == 7) {
256
+ let value = dataView.getFloat64(position);
257
+ position += 8;
258
+ return value
259
+ }
260
+ if (majorType > 1) {
261
+ if (dataView.getUint32(position) > 0)
262
+ throw new Error('JavaScript does not support arrays, maps, or strings with length over 4294967295')
263
+ token = dataView.getUint32(position + 4);
264
+ } else if (currentDecoder.int64AsNumber) {
265
+ token = dataView.getUint32(position) * 0x100000000;
266
+ token += dataView.getUint32(position + 4);
267
+ } else
268
+ token = dataView.getBigUint64(position);
269
+ position += 8;
270
+ break
271
+ case 0x1f:
272
+ // indefinite length
273
+ switch(majorType) {
274
+ case 2: // byte string
275
+ case 3: // text string
276
+ throw new Error('Indefinite length not supported for byte or text strings')
277
+ case 4: // array
278
+ let array = [];
279
+ let value, i = 0;
280
+ while ((value = read()) != STOP_CODE) {
281
+ array[i++] = value;
282
+ }
283
+ return majorType == 4 ? array : majorType == 3 ? array.join('') : Buffer.concat(array)
284
+ case 5: // map
285
+ let key;
286
+ if (currentDecoder.mapsAsObjects) {
287
+ let object = {};
288
+ if (currentDecoder.keyMap) while((key = read()) != STOP_CODE) object[currentDecoder.decodeKey(key)] = read();
289
+ else while ((key = read()) != STOP_CODE) object[key] = read();
290
+ return object
291
+ } else {
292
+ if (restoreMapsAsObject) {
293
+ currentDecoder.mapsAsObjects = true;
294
+ restoreMapsAsObject = false;
295
+ }
296
+ let map = new Map();
297
+ if (currentDecoder.keyMap) while((key = read()) != STOP_CODE) map.set(currentDecoder.decodeKey(key), read());
298
+ else while ((key = read()) != STOP_CODE) map.set(key, read());
299
+ return map
300
+ }
301
+ case 7:
302
+ return STOP_CODE
303
+ default:
304
+ throw new Error('Invalid major type for indefinite length ' + majorType)
305
+ }
306
+ default:
307
+ throw new Error('Unknown token ' + token)
308
+ }
309
+ }
310
+ switch (majorType) {
311
+ case 0: // positive int
312
+ return token
313
+ case 1: // negative int
314
+ return ~token
315
+ case 2: // buffer
316
+ return readBin(token)
317
+ case 3: // string
318
+ if (srcStringEnd >= position) {
319
+ return srcString.slice(position - srcStringStart, (position += token) - srcStringStart)
320
+ }
321
+ if (srcStringEnd == 0 && srcEnd < 140 && token < 32) {
322
+ // for small blocks, avoiding the overhead of the extract call is helpful
323
+ let string = token < 16 ? shortStringInJS(token) : longStringInJS(token);
324
+ if (string != null)
325
+ return string
326
+ }
327
+ return readFixedString(token)
328
+ case 4: // array
329
+ let array = new Array(token);
330
+ //if (currentDecoder.keyMap) for (let i = 0; i < token; i++) array[i] = currentDecoder.decodeKey(read())
331
+ //else
332
+ for (let i = 0; i < token; i++) array[i] = read();
333
+ return array
334
+ case 5: // map
335
+ if (currentDecoder.mapsAsObjects) {
336
+ let object = {};
337
+ if (currentDecoder.keyMap) for (let i = 0; i < token; i++) object[currentDecoder.decodeKey(read())] = read();
338
+ else for (let i = 0; i < token; i++) object[read()] = read();
339
+ return object
340
+ } else {
341
+ if (restoreMapsAsObject) {
342
+ currentDecoder.mapsAsObjects = true;
343
+ restoreMapsAsObject = false;
344
+ }
345
+ let map = new Map();
346
+ if (currentDecoder.keyMap) for (let i = 0; i < token; i++) map.set(currentDecoder.decodeKey(read()),read());
347
+ else for (let i = 0; i < token; i++) map.set(read(), read());
348
+ return map
349
+ }
350
+ case 6: // extension
351
+ if (token >= BUNDLED_STRINGS_ID) {
352
+ let structure = currentStructures[token & 0x1fff]; // check record structures first
353
+ // 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))
354
+ if (structure) {
355
+ if (!structure.read) structure.read = createStructureReader(structure);
356
+ return structure.read()
357
+ }
358
+ if (token < 0x10000) {
359
+ 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)
360
+ return recordDefinition(read())
361
+ else if (token == RECORD_DEFINITIONS_ID) {
362
+ let length = readJustLength();
363
+ let id = read();
364
+ for (let i = 2; i < length; i++) {
365
+ recordDefinition([id++, read()]);
366
+ }
367
+ return read()
368
+ } else if (token == BUNDLED_STRINGS_ID) {
369
+ return readBundleExt()
370
+ }
371
+ if (currentDecoder.getShared) {
372
+ loadShared();
373
+ structure = currentStructures[token & 0x1fff];
374
+ if (structure) {
375
+ if (!structure.read)
376
+ structure.read = createStructureReader(structure);
377
+ return structure.read()
378
+ }
379
+ }
380
+ }
381
+ }
382
+ let extension = currentExtensions[token];
383
+ if (extension) {
384
+ if (extension.handlesRead)
385
+ return extension(read)
386
+ else
387
+ return extension(read())
388
+ } else {
389
+ let input = read();
390
+ for (let i = 0; i < currentExtensionRanges.length; i++) {
391
+ let value = currentExtensionRanges[i](token, input);
392
+ if (value !== undefined)
393
+ return value
394
+ }
395
+ return new Tag(input, token)
396
+ }
397
+ case 7: // fixed value
398
+ switch (token) {
399
+ case 0x14: return false
400
+ case 0x15: return true
401
+ case 0x16: return null
402
+ case 0x17: return; // undefined
403
+ case 0x1f:
404
+ default:
405
+ let packedValue = (packedValues || getPackedValues())[token];
406
+ if (packedValue !== undefined)
407
+ return packedValue
408
+ throw new Error('Unknown token ' + token)
409
+ }
410
+ default: // negative int
411
+ if (isNaN(token)) {
412
+ let error = new Error('Unexpected end of CBOR data');
413
+ error.incomplete = true;
414
+ throw error
415
+ }
416
+ throw new Error('Unknown CBOR token ' + token)
417
+ }
418
+ }
419
+ const validName = /^[a-zA-Z_$][a-zA-Z\d_$]*$/;
420
+ function createStructureReader(structure) {
421
+ function readObject() {
422
+ // get the array size from the header
423
+ let length = src[position++];
424
+ //let majorType = token >> 5
425
+ length = length & 0x1f;
426
+ if (length > 0x17) {
427
+ switch (length) {
428
+ case 0x18:
429
+ length = src[position++];
430
+ break
431
+ case 0x19:
432
+ length = dataView.getUint16(position);
433
+ position += 2;
434
+ break
435
+ case 0x1a:
436
+ length = dataView.getUint32(position);
437
+ position += 4;
438
+ break
439
+ default:
440
+ throw new Error('Expected array header, but got ' + src[position - 1])
441
+ }
442
+ }
443
+ // This initial function is quick to instantiate, but runs slower. After several iterations pay the cost to build the faster function
444
+ let compiledReader = this.compiledReader; // first look to see if we have the fast compiled function
445
+ while(compiledReader) {
446
+ // we have a fast compiled object literal reader
447
+ if (compiledReader.propertyCount === length)
448
+ return compiledReader(read) // with the right length, so we use it
449
+ compiledReader = compiledReader.next; // see if there is another reader with the right length
450
+ }
451
+ if (this.slowReads++ >= 3) { // create a fast compiled reader
452
+ let array = this.length == length ? this : this.slice(0, length);
453
+ compiledReader = currentDecoder.keyMap
454
+ ? new Function('r', 'return {' + array.map(k => currentDecoder.decodeKey(k)).map(k => validName.test(k) ? k + ':r()' : ('[' + JSON.stringify(k) + ']:r()')).join(',') + '}')
455
+ : new Function('r', 'return {' + array.map(key => validName.test(key) ? key + ':r()' : ('[' + JSON.stringify(key) + ']:r()')).join(',') + '}');
456
+ if (this.compiledReader)
457
+ compiledReader.next = this.compiledReader; // if there is an existing one, we store multiple readers as a linked list because it is usually pretty rare to have multiple readers (of different length) for the same structure
458
+ compiledReader.propertyCount = length;
459
+ this.compiledReader = compiledReader;
460
+ return compiledReader(read)
461
+ }
462
+ let object = {};
463
+ if (currentDecoder.keyMap) for (let i = 0; i < length; i++) object[currentDecoder.decodeKey(this[i])] = read();
464
+ else for (let i = 0; i < length; i++) object[this[i]] = read();
465
+ return object
466
+ }
467
+ structure.slowReads = 0;
468
+ return readObject
469
+ }
470
+
471
+ let readFixedString = readStringJS;
472
+
473
+ let isNativeAccelerationEnabled = false;
474
+ function readStringJS(length) {
475
+ let result;
476
+ if (length < 16) {
477
+ if (result = shortStringInJS(length))
478
+ return result
479
+ }
480
+ if (length > 64 && decoder)
481
+ return decoder.decode(src.subarray(position, position += length))
482
+ const end = position + length;
483
+ const units = [];
484
+ result = '';
485
+ while (position < end) {
486
+ const byte1 = src[position++];
487
+ if ((byte1 & 0x80) === 0) {
488
+ // 1 byte
489
+ units.push(byte1);
490
+ } else if ((byte1 & 0xe0) === 0xc0) {
491
+ // 2 bytes
492
+ const byte2 = src[position++] & 0x3f;
493
+ units.push(((byte1 & 0x1f) << 6) | byte2);
494
+ } else if ((byte1 & 0xf0) === 0xe0) {
495
+ // 3 bytes
496
+ const byte2 = src[position++] & 0x3f;
497
+ const byte3 = src[position++] & 0x3f;
498
+ units.push(((byte1 & 0x1f) << 12) | (byte2 << 6) | byte3);
499
+ } else if ((byte1 & 0xf8) === 0xf0) {
500
+ // 4 bytes
501
+ const byte2 = src[position++] & 0x3f;
502
+ const byte3 = src[position++] & 0x3f;
503
+ const byte4 = src[position++] & 0x3f;
504
+ let unit = ((byte1 & 0x07) << 0x12) | (byte2 << 0x0c) | (byte3 << 0x06) | byte4;
505
+ if (unit > 0xffff) {
506
+ unit -= 0x10000;
507
+ units.push(((unit >>> 10) & 0x3ff) | 0xd800);
508
+ unit = 0xdc00 | (unit & 0x3ff);
509
+ }
510
+ units.push(unit);
511
+ } else {
512
+ units.push(byte1);
513
+ }
514
+
515
+ if (units.length >= 0x1000) {
516
+ result += fromCharCode.apply(String, units);
517
+ units.length = 0;
518
+ }
519
+ }
520
+
521
+ if (units.length > 0) {
522
+ result += fromCharCode.apply(String, units);
523
+ }
524
+
525
+ return result
526
+ }
527
+ let fromCharCode = String.fromCharCode;
528
+ function longStringInJS(length) {
529
+ let start = position;
530
+ let bytes = new Array(length);
531
+ for (let i = 0; i < length; i++) {
532
+ const byte = src[position++];
533
+ if ((byte & 0x80) > 0) {
534
+ position = start;
535
+ return
536
+ }
537
+ bytes[i] = byte;
538
+ }
539
+ return fromCharCode.apply(String, bytes)
540
+ }
541
+ function shortStringInJS(length) {
542
+ if (length < 4) {
543
+ if (length < 2) {
544
+ if (length === 0)
545
+ return ''
546
+ else {
547
+ let a = src[position++];
548
+ if ((a & 0x80) > 1) {
549
+ position -= 1;
550
+ return
551
+ }
552
+ return fromCharCode(a)
553
+ }
554
+ } else {
555
+ let a = src[position++];
556
+ let b = src[position++];
557
+ if ((a & 0x80) > 0 || (b & 0x80) > 0) {
558
+ position -= 2;
559
+ return
560
+ }
561
+ if (length < 3)
562
+ return fromCharCode(a, b)
563
+ let c = src[position++];
564
+ if ((c & 0x80) > 0) {
565
+ position -= 3;
566
+ return
567
+ }
568
+ return fromCharCode(a, b, c)
569
+ }
570
+ } else {
571
+ let a = src[position++];
572
+ let b = src[position++];
573
+ let c = src[position++];
574
+ let d = src[position++];
575
+ if ((a & 0x80) > 0 || (b & 0x80) > 0 || (c & 0x80) > 0 || (d & 0x80) > 0) {
576
+ position -= 4;
577
+ return
578
+ }
579
+ if (length < 6) {
580
+ if (length === 4)
581
+ return fromCharCode(a, b, c, d)
582
+ else {
583
+ let e = src[position++];
584
+ if ((e & 0x80) > 0) {
585
+ position -= 5;
586
+ return
587
+ }
588
+ return fromCharCode(a, b, c, d, e)
589
+ }
590
+ } else if (length < 8) {
591
+ let e = src[position++];
592
+ let f = src[position++];
593
+ if ((e & 0x80) > 0 || (f & 0x80) > 0) {
594
+ position -= 6;
595
+ return
596
+ }
597
+ if (length < 7)
598
+ return fromCharCode(a, b, c, d, e, f)
599
+ let g = src[position++];
600
+ if ((g & 0x80) > 0) {
601
+ position -= 7;
602
+ return
603
+ }
604
+ return fromCharCode(a, b, c, d, e, f, g)
605
+ } else {
606
+ let e = src[position++];
607
+ let f = src[position++];
608
+ let g = src[position++];
609
+ let h = src[position++];
610
+ if ((e & 0x80) > 0 || (f & 0x80) > 0 || (g & 0x80) > 0 || (h & 0x80) > 0) {
611
+ position -= 8;
612
+ return
613
+ }
614
+ if (length < 10) {
615
+ if (length === 8)
616
+ return fromCharCode(a, b, c, d, e, f, g, h)
617
+ else {
618
+ let i = src[position++];
619
+ if ((i & 0x80) > 0) {
620
+ position -= 9;
621
+ return
622
+ }
623
+ return fromCharCode(a, b, c, d, e, f, g, h, i)
624
+ }
625
+ } else if (length < 12) {
626
+ let i = src[position++];
627
+ let j = src[position++];
628
+ if ((i & 0x80) > 0 || (j & 0x80) > 0) {
629
+ position -= 10;
630
+ return
631
+ }
632
+ if (length < 11)
633
+ return fromCharCode(a, b, c, d, e, f, g, h, i, j)
634
+ let k = src[position++];
635
+ if ((k & 0x80) > 0) {
636
+ position -= 11;
637
+ return
638
+ }
639
+ return fromCharCode(a, b, c, d, e, f, g, h, i, j, k)
640
+ } else {
641
+ let i = src[position++];
642
+ let j = src[position++];
643
+ let k = src[position++];
644
+ let l = src[position++];
645
+ if ((i & 0x80) > 0 || (j & 0x80) > 0 || (k & 0x80) > 0 || (l & 0x80) > 0) {
646
+ position -= 12;
647
+ return
648
+ }
649
+ if (length < 14) {
650
+ if (length === 12)
651
+ return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l)
652
+ else {
653
+ let m = src[position++];
654
+ if ((m & 0x80) > 0) {
655
+ position -= 13;
656
+ return
657
+ }
658
+ return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m)
659
+ }
660
+ } else {
661
+ let m = src[position++];
662
+ let n = src[position++];
663
+ if ((m & 0x80) > 0 || (n & 0x80) > 0) {
664
+ position -= 14;
665
+ return
666
+ }
667
+ if (length < 15)
668
+ return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m, n)
669
+ let o = src[position++];
670
+ if ((o & 0x80) > 0) {
671
+ position -= 15;
672
+ return
673
+ }
674
+ return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
675
+ }
676
+ }
677
+ }
678
+ }
679
+ }
680
+
681
+ function readBin(length) {
682
+ return currentDecoder.copyBuffers ?
683
+ // specifically use the copying slice (not the node one)
684
+ Uint8Array.prototype.slice.call(src, position, position += length) :
685
+ src.subarray(position, position += length)
686
+ }
687
+
688
+ function getFloat16() {
689
+ let byte0 = src[position++];
690
+ let byte1 = src[position++];
691
+ let half = (byte0 << 8) + byte1;
692
+ let exp = (half >> 10) & 0x1f;
693
+ let mant = half & 0x3ff;
694
+ let val;
695
+ if (exp == 0) val = Math.exp(mant, -24);
696
+ else if (exp != 31) val = Math.exp(mant + 1024, exp - 25);
697
+ else val = mant == 0 ? Infinity : NaN;
698
+ return half & 0x8000 ? -val : val
699
+ }
700
+
701
+ let keyCache = new Array(4096);
702
+
703
+ class Tag {
704
+ constructor(value, tag) {
705
+ this.value = value;
706
+ this.tag = tag;
707
+ }
708
+ }
709
+
710
+ currentExtensions[0] = (dateString) => {
711
+ // string date extension
712
+ return new Date(dateString)
713
+ };
714
+
715
+ currentExtensions[1] = (epochSec) => {
716
+ // numeric date extension
717
+ return new Date(Math.round(epochSec * 1000))
718
+ };
719
+
720
+ currentExtensions[2] = (buffer) => {
721
+ // bigint extension
722
+ let value = BigInt(0);
723
+ for (let i = 0, l = buffer.byteLength; i < l; i++) {
724
+ value = BigInt(buffer[i]) + value << BigInt(8);
725
+ }
726
+ return value
727
+ };
728
+
729
+ currentExtensions[3] = (buffer) => {
730
+ // negative bigint extension
731
+ return BigInt(-1) - currentExtensions[2](buffer)
732
+ };
733
+ currentExtensions[4] = (fraction) => {
734
+ // best to reparse to maintain accuracy
735
+ return +(fraction[1] + 'e' + fraction[0])
736
+ };
737
+
738
+ currentExtensions[5] = (fraction) => {
739
+ // probably not sufficiently accurate
740
+ return fraction[1] * Math.exp(fraction[0] * Math.log(2))
741
+ };
742
+
743
+ // the registration of the record definition extension
744
+ const recordDefinition = (definition) => {
745
+ let id = definition[0] - 0xe000;
746
+ let structure = definition[1];
747
+ let existingStructure = currentStructures[id];
748
+ if (existingStructure && existingStructure.isShared) {
749
+ (currentStructures.restoreStructures || (currentStructures.restoreStructures = []))[id] = existingStructure;
750
+ }
751
+ currentStructures[id] = structure;
752
+
753
+ structure.read = createStructureReader(structure);
754
+ let object = {};
755
+ if (currentDecoder.keyMap) for (let i = 2,l = definition.length; i < l; i++) {
756
+ let key = currentDecoder.decodeKey(structure[i - 2]);
757
+ object[key] = definition[i];
758
+ }
759
+ else for (let i = 2,l = definition.length; i < l; i++) {
760
+ let key = structure[i - 2];
761
+ object[key] = definition[i];
762
+ }
763
+ return object
764
+ };
765
+ currentExtensions[LEGACY_RECORD_INLINE_ID] = recordDefinition;
766
+ currentExtensions[14] = (value) => {
767
+ if (bundledStrings)
768
+ return bundledStrings[0].slice(bundledStrings.position0, bundledStrings.position0 += value)
769
+ return new Tag(value, 14)
770
+ };
771
+ currentExtensions[15] = (value) => {
772
+ if (bundledStrings)
773
+ return bundledStrings[1].slice(bundledStrings.position1, bundledStrings.position1 += value)
774
+ return new Tag(value, 15)
775
+ };
776
+ let glbl = { Error, RegExp };
777
+ currentExtensions[27] = (data) => { // http://cbor.schmorp.de/generic-object
778
+ return (glbl[data[0]] || Error)(data[1], data[2])
779
+ };
780
+ const packedTable = (read) => {
781
+ if (src[position++] != 0x84)
782
+ throw new Error('Packed values structure must be followed by a 4 element array')
783
+ let newPackedValues = read(); // packed values
784
+ packedValues = packedValues ? newPackedValues.concat(packedValues.slice(newPackedValues.length)) : newPackedValues;
785
+ packedValues.prefixes = read();
786
+ packedValues.suffixes = read();
787
+ return read() // read the rump
788
+ };
789
+ packedTable.handlesRead = true;
790
+ currentExtensions[51] = packedTable;
791
+
792
+ currentExtensions[PACKED_REFERENCE_TAG_ID] = (data) => { // packed reference
793
+ if (!packedValues) {
794
+ if (currentDecoder.getShared)
795
+ loadShared();
796
+ else
797
+ return new Tag(data, PACKED_REFERENCE_TAG_ID)
798
+ }
799
+ if (typeof data == 'number')
800
+ return packedValues[16 + (data >= 0 ? 2 * data : (-2 * data - 1))]
801
+ throw new Error('No support for non-integer packed references yet')
802
+ };
803
+ currentExtensions[25] = (id) => {
804
+ return stringRefs[id]
805
+ };
806
+ currentExtensions[256] = (read) => {
807
+ stringRefs = [];
808
+ try {
809
+ return read()
810
+ } finally {
811
+ stringRefs = null;
812
+ }
813
+ };
814
+ currentExtensions[256].handlesRead = true;
815
+
816
+ currentExtensions[28] = (read) => {
817
+ // shareable http://cbor.schmorp.de/value-sharing (for structured clones)
818
+ if (!referenceMap) {
819
+ referenceMap = new Map();
820
+ referenceMap.id = 0;
821
+ }
822
+ let id = referenceMap.id++;
823
+ let token = src[position];
824
+ let target;
825
+ // TODO: handle Maps, Sets, and other types that can cycle; this is complicated, because you potentially need to read
826
+ // ahead past references to record structure definitions
827
+ if ((token >> 5) == 4)
828
+ target = [];
829
+ else
830
+ target = {};
831
+
832
+ let refEntry = { target }; // a placeholder object
833
+ referenceMap.set(id, refEntry);
834
+ let targetProperties = read(); // read the next value as the target object to id
835
+ if (refEntry.used) // there is a cycle, so we have to assign properties to original target
836
+ return Object.assign(target, targetProperties)
837
+ refEntry.target = targetProperties; // the placeholder wasn't used, replace with the deserialized one
838
+ return targetProperties // no cycle, can just use the returned read object
839
+ };
840
+ currentExtensions[28].handlesRead = true;
841
+
842
+ currentExtensions[29] = (id) => {
843
+ // sharedref http://cbor.schmorp.de/value-sharing (for structured clones)
844
+ let refEntry = referenceMap.get(id);
845
+ refEntry.used = true;
846
+ return refEntry.target
847
+ };
848
+
849
+ currentExtensions[258] = (array) => new Set(array); // https://github.com/input-output-hk/cbor-sets-spec/blob/master/CBOR_SETS.md
850
+ (currentExtensions[259] = (read) => {
851
+ // https://github.com/shanewholloway/js-cbor-codec/blob/master/docs/CBOR-259-spec
852
+ // for decoding as a standard Map
853
+ if (currentDecoder.mapsAsObjects) {
854
+ currentDecoder.mapsAsObjects = false;
855
+ restoreMapsAsObject = true;
856
+ }
857
+ return read()
858
+ }).handlesRead = true;
859
+ function combine(a, b) {
860
+ if (typeof a === 'string')
861
+ return a + b
862
+ if (a instanceof Array)
863
+ return a.concat(b)
864
+ return Object.assign({}, a, b)
865
+ }
866
+ function getPackedValues() {
867
+ if (!packedValues) {
868
+ if (currentDecoder.getShared)
869
+ loadShared();
870
+ else
871
+ throw new Error('No packed values available')
872
+ }
873
+ return packedValues
1041
874
  }
875
+ const SHARED_DATA_TAG_ID = 0x53687264; // ascii 'Shrd'
876
+ currentExtensionRanges.push((tag, input) => {
877
+ if (tag >= 225 && tag <= 255)
878
+ return combine(getPackedValues().prefixes[tag - 224], input)
879
+ if (tag >= 28704 && tag <= 32767)
880
+ return combine(getPackedValues().prefixes[tag - 28672], input)
881
+ if (tag >= 1879052288 && tag <= 2147483647)
882
+ return combine(getPackedValues().prefixes[tag - 1879048192], input)
883
+ if (tag >= 216 && tag <= 223)
884
+ return combine(input, getPackedValues().suffixes[tag - 216])
885
+ if (tag >= 27647 && tag <= 28671)
886
+ return combine(input, getPackedValues().suffixes[tag - 27639])
887
+ if (tag >= 1811940352 && tag <= 1879048191)
888
+ return combine(input, getPackedValues().suffixes[tag - 1811939328])
889
+ 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)
890
+ return {
891
+ packedValues: packedValues,
892
+ structures: currentStructures.slice(0),
893
+ version: input,
894
+ }
895
+ }
896
+ if (tag == 55799) // self-descriptive CBOR tag, just return input value
897
+ return input
898
+ });
1042
899
 
1043
- let textEncoder;
1044
- try {
1045
- textEncoder = new TextEncoder();
1046
- } catch (error) {}
1047
- let extensions, extensionClasses;
1048
- const hasNodeBuffer = typeof Buffer !== 'undefined';
1049
- const ByteArrayAllocate = hasNodeBuffer ? Buffer.allocUnsafeSlow : Uint8Array;
1050
- const ByteArray = hasNodeBuffer ? Buffer : Uint8Array;
1051
- const MAX_STRUCTURES = 0x100;
1052
- const MAX_BUFFER_SIZE = hasNodeBuffer ? 0x100000000 : 0x7fd00000;
1053
- let target;
1054
- let targetView;
1055
- let position$1 = 0;
1056
- let safeEnd;
1057
- let bundledStrings$1 = null;
1058
- const MAX_BUNDLE_SIZE = 0xf000;
1059
- const hasNonLatin = /[\u0080-\uFFFF]/;
1060
- const RECORD_SYMBOL = Symbol('record-id');
1061
- class Encoder extends Decoder {
1062
- constructor(options) {
1063
- super(options);
1064
- this.offset = 0;
1065
- let start;
1066
- let sharedStructures;
1067
- let hasSharedUpdate;
1068
- let structures;
1069
- let referenceMap;
1070
- options = options || {};
1071
- let encodeUtf8 = ByteArray.prototype.utf8Write ? function(string, position, maxBytes) {
1072
- return target.utf8Write(string, position, maxBytes)
1073
- } : (textEncoder && textEncoder.encodeInto) ?
1074
- function(string, position) {
1075
- return textEncoder.encodeInto(string, target.subarray(position)).written
1076
- } : false;
1077
-
1078
- let encoder = this;
1079
- let hasSharedStructures = options.structures || options.saveStructures;
1080
- let maxSharedStructures = options.maxSharedStructures;
1081
- if (maxSharedStructures == null)
1082
- maxSharedStructures = hasSharedStructures ? 128 : 0;
1083
- if (maxSharedStructures > 8190)
1084
- throw new Error('Maximum maxSharedStructure is 8190')
1085
- let isSequential = options.sequential;
1086
- if (isSequential) {
1087
- maxSharedStructures = 0;
1088
- }
1089
- if (!this.structures)
1090
- this.structures = [];
1091
- if (this.saveStructures)
1092
- this.saveShared = this.saveStructures;
1093
- let samplingPackedValues, packedObjectMap, sharedValues = options.sharedValues;
1094
- let sharedPackedObjectMap;
1095
- if (sharedValues) {
1096
- sharedPackedObjectMap = Object.create(null);
1097
- for (let i = 0, l = sharedValues.length; i < l; i++) {
1098
- sharedPackedObjectMap[sharedValues[i]] = i;
1099
- }
1100
- }
1101
- let recordIdsToRemove = [];
1102
- let transitionsCount = 0;
1103
- let serializationsSinceTransitionRebuild = 0;
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) {
1123
- if (!target) {
1124
- target = new ByteArrayAllocate(8192);
1125
- targetView = new DataView(target.buffer, 0, 8192);
1126
- position$1 = 0;
1127
- }
1128
- safeEnd = target.length - 10;
1129
- if (safeEnd - position$1 < 0x800) {
1130
- // don't start too close to the end,
1131
- target = new ByteArrayAllocate(target.length);
1132
- targetView = new DataView(target.buffer, 0, target.length);
1133
- safeEnd = target.length - 10;
1134
- position$1 = 0;
1135
- } else if (encodeOptions === REUSE_BUFFER_MODE)
1136
- position$1 = (position$1 + 7) & 0x7ffffff8; // Word align to make any future copying of this buffer faster
1137
- start = position$1;
1138
- if (encoder.useSelfDescribedHeader) {
1139
- targetView.setUint32(position$1, 0xd9d9f700); // tag two byte, then self-descriptive tag
1140
- position$1 += 3;
1141
- }
1142
- referenceMap = encoder.structuredClone ? new Map() : null;
1143
- if (encoder.bundleStrings && typeof value !== 'string') {
1144
- bundledStrings$1 = [];
1145
- bundledStrings$1.size = Infinity; // force a new bundle start on first string
1146
- } else
1147
- bundledStrings$1 = null;
1148
-
1149
- sharedStructures = encoder.structures;
1150
- if (sharedStructures) {
1151
- if (sharedStructures.uninitialized) {
1152
- let sharedData = encoder.getShared() || {};
1153
- encoder.structures = sharedStructures = sharedData.structures || [];
1154
- encoder.sharedVersion = sharedData.version;
1155
- let sharedValues = encoder.sharedValues = sharedData.packedValues;
1156
- if (sharedValues) {
1157
- sharedPackedObjectMap = {};
1158
- for (let i = 0, l = sharedValues.length; i < l; i++)
1159
- sharedPackedObjectMap[sharedValues[i]] = i;
1160
- }
1161
- }
1162
- let sharedStructuresLength = sharedStructures.length;
1163
- if (sharedStructuresLength > maxSharedStructures && !isSequential)
1164
- sharedStructuresLength = maxSharedStructures;
1165
- if (!sharedStructures.transitions) {
1166
- // rebuild our structure transitions
1167
- sharedStructures.transitions = Object.create(null);
1168
- for (let i = 0; i < sharedStructuresLength; i++) {
1169
- let keys = sharedStructures[i];
1170
- //console.log('shared struct keys:', keys)
1171
- if (!keys)
1172
- continue
1173
- let nextTransition, transition = sharedStructures.transitions;
1174
- for (let j = 0, l = keys.length; j < l; j++) {
1175
- if (transition[RECORD_SYMBOL] === undefined)
1176
- transition[RECORD_SYMBOL] = i;
1177
- let key = keys[j];
1178
- nextTransition = transition[key];
1179
- if (!nextTransition) {
1180
- nextTransition = transition[key] = Object.create(null);
1181
- }
1182
- transition = nextTransition;
1183
- }
1184
- transition[RECORD_SYMBOL] = i | 0x100000;
1185
- }
1186
- }
1187
- if (!isSequential)
1188
- sharedStructures.nextId = sharedStructuresLength;
1189
- }
1190
- if (hasSharedUpdate)
1191
- hasSharedUpdate = false;
1192
- structures = sharedStructures || [];
1193
- packedObjectMap = sharedPackedObjectMap;
1194
- if (options.pack) {
1195
- let packedValues = new Map();
1196
- packedValues.values = [];
1197
- packedValues.encoder = encoder;
1198
- packedValues.maxValues = options.maxPrivatePackedValues || (sharedPackedObjectMap ? 16 : Infinity);
1199
- packedValues.objectMap = sharedPackedObjectMap || false;
1200
- packedValues.samplingPackedValues = samplingPackedValues;
1201
- findRepetitiveStrings(value, packedValues);
1202
- if (packedValues.values.length > 0) {
1203
- target[position$1++] = 0xd8; // one-byte tag
1204
- target[position$1++] = 51; // tag 51 for packed shared structures https://www.potaroo.net/ietf/ids/draft-ietf-cbor-packed-03.txt
1205
- writeArrayHeader(4);
1206
- let valuesArray = packedValues.values;
1207
- encode(valuesArray);
1208
- writeArrayHeader(0); // prefixes
1209
- writeArrayHeader(0); // suffixes
1210
- packedObjectMap = Object.create(sharedPackedObjectMap || null);
1211
- for (let i = 0, l = valuesArray.length; i < l; i++) {
1212
- packedObjectMap[valuesArray[i]] = i;
1213
- }
1214
- }
1215
- }
1216
- try {
1217
- encode(value);
1218
- if (bundledStrings$1) {
1219
- writeBundles(start, encode);
1220
- }
1221
- encoder.offset = position$1; // update the offset so next serialization doesn't write over our buffer, but can continue writing to same buffer sequentially
1222
- if (referenceMap && referenceMap.idsToInsert) {
1223
- position$1 += referenceMap.idsToInsert.length * 2;
1224
- if (position$1 > safeEnd)
1225
- makeRoom(position$1);
1226
- encoder.offset = position$1;
1227
- let serialized = insertIds(target.subarray(start, position$1), referenceMap.idsToInsert);
1228
- referenceMap = null;
1229
- return serialized
1230
- }
1231
- if (encodeOptions & REUSE_BUFFER_MODE) {
1232
- target.start = start;
1233
- target.end = position$1;
1234
- return target
1235
- }
1236
- return target.subarray(start, position$1) // position can change if we call encode again in saveShared, so we get the buffer now
1237
- } finally {
1238
- if (sharedStructures) {
1239
- if (serializationsSinceTransitionRebuild < 10)
1240
- serializationsSinceTransitionRebuild++;
1241
- if (sharedStructures.length > maxSharedStructures)
1242
- sharedStructures.length = maxSharedStructures;
1243
- if (transitionsCount > 10000) {
1244
- // force a rebuild occasionally after a lot of transitions so it can get cleaned up
1245
- sharedStructures.transitions = null;
1246
- serializationsSinceTransitionRebuild = 0;
1247
- transitionsCount = 0;
1248
- if (recordIdsToRemove.length > 0)
1249
- recordIdsToRemove = [];
1250
- } else if (recordIdsToRemove.length > 0 && !isSequential) {
1251
- for (let i = 0, l = recordIdsToRemove.length; i < l; i++) {
1252
- recordIdsToRemove[i][RECORD_SYMBOL] = undefined;
1253
- }
1254
- recordIdsToRemove = [];
1255
- //sharedStructures.nextId = maxSharedStructures
1256
- }
1257
- }
1258
- if (hasSharedUpdate && encoder.saveShared) {
1259
- if (encoder.structures.length > maxSharedStructures) {
1260
- encoder.structures = encoder.structures.slice(0, maxSharedStructures);
1261
- }
1262
- // we can't rely on start/end with REUSE_BUFFER_MODE since they will (probably) change when we save
1263
- let returnBuffer = target.subarray(start, position$1);
1264
- if (encoder.updateSharedData() === false)
1265
- return encoder.encode(value) // re-encode if it fails
1266
- return returnBuffer
1267
- }
1268
- if (encodeOptions & RESET_BUFFER_MODE)
1269
- position$1 = start;
1270
- }
1271
- };
1272
- this.findCommonStringsToPack = () => {
1273
- samplingPackedValues = new Map();
1274
- if (!sharedPackedObjectMap)
1275
- sharedPackedObjectMap = Object.create(null);
1276
- return (options) => {
1277
- let threshold = options && options.threshold || 4;
1278
- let position = this.pack ? options.maxPrivatePackedValues || 16 : 0;
1279
- if (!sharedValues)
1280
- sharedValues = this.sharedValues = [];
1281
- for (let [ key, status ] of samplingPackedValues) {
1282
- if (status.count > threshold) {
1283
- sharedPackedObjectMap[key] = position++;
1284
- sharedValues.push(key);
1285
- hasSharedUpdate = true;
1286
- }
1287
- }
1288
- while (this.saveShared && this.updateSharedData() === false) {}
1289
- samplingPackedValues = null;
1290
- }
1291
- };
1292
- const encode = (value) => {
1293
- if (position$1 > safeEnd)
1294
- target = makeRoom(position$1);
1295
-
1296
- var type = typeof value;
1297
- var length;
1298
- if (type === 'string') {
1299
- if (packedObjectMap) {
1300
- let packedPosition = packedObjectMap[value];
1301
- if (packedPosition >= 0) {
1302
- if (packedPosition < 16)
1303
- target[position$1++] = packedPosition + 0xe0; // simple values, defined in https://www.potaroo.net/ietf/ids/draft-ietf-cbor-packed-03.txt
1304
- else {
1305
- target[position$1++] = 0xc6; // tag 6 defined in https://www.potaroo.net/ietf/ids/draft-ietf-cbor-packed-03.txt
1306
- if (packedPosition & 1)
1307
- encode((15 - packedPosition) >> 1);
1308
- else
1309
- encode((packedPosition - 16) >> 1);
1310
- }
1311
- return
1312
- /* } else if (packedStatus.serializationId != serializationId) {
1313
- packedStatus.serializationId = serializationId
1314
- packedStatus.count = 1
1315
- if (options.sharedPack) {
1316
- let sharedCount = packedStatus.sharedCount = (packedStatus.sharedCount || 0) + 1
1317
- if (shareCount > (options.sharedPack.threshold || 5)) {
1318
- let sharedPosition = packedStatus.position = packedStatus.nextSharedPosition
1319
- hasSharedUpdate = true
1320
- if (sharedPosition < 16)
1321
- target[position++] = sharedPosition + 0xc0
1322
-
1323
- }
1324
- }
1325
- } // else any in-doc incrementation?*/
1326
- } else if (samplingPackedValues && !options.pack) {
1327
- let status = samplingPackedValues.get(value);
1328
- if (status)
1329
- status.count++;
1330
- else
1331
- samplingPackedValues.set(value, {
1332
- count: 1,
1333
- });
1334
- }
1335
- }
1336
- let strLength = value.length;
1337
- if (bundledStrings$1 && strLength >= 4 && strLength < 0x400) {
1338
- if ((bundledStrings$1.size += strLength) > MAX_BUNDLE_SIZE) {
1339
- let extStart;
1340
- let maxBytes = (bundledStrings$1[0] ? bundledStrings$1[0].length * 3 + bundledStrings$1[1].length : 0) + 10;
1341
- if (position$1 + maxBytes > safeEnd)
1342
- target = makeRoom(position$1 + maxBytes);
1343
- target[position$1++] = 0xd9; // tag 16-bit
1344
- target[position$1++] = 0xdf; // tag 0xdff9
1345
- target[position$1++] = 0xf9;
1346
- // TODO: If we only have one bundle with any string data, only write one string bundle
1347
- target[position$1++] = bundledStrings$1.position ? 0x84 : 0x82; // array of 4 or 2 elements depending on if we write bundles
1348
- target[position$1++] = 0x1a; // 32-bit unsigned int
1349
- extStart = position$1 - start;
1350
- position$1 += 4; // reserve for writing bundle reference
1351
- if (bundledStrings$1.position) {
1352
- writeBundles(start, encode); // write the last bundles
1353
- }
1354
- bundledStrings$1 = ['', '']; // create new ones
1355
- bundledStrings$1.size = 0;
1356
- bundledStrings$1.position = extStart;
1357
- }
1358
- let twoByte = hasNonLatin.test(value);
1359
- bundledStrings$1[twoByte ? 0 : 1] += value;
1360
- target[position$1++] = twoByte ? 0xce : 0xcf;
1361
- encode(strLength);
1362
- return
1363
- }
1364
- let headerSize;
1365
- // first we estimate the header size, so we can write to the correct location
1366
- if (strLength < 0x20) {
1367
- headerSize = 1;
1368
- } else if (strLength < 0x100) {
1369
- headerSize = 2;
1370
- } else if (strLength < 0x10000) {
1371
- headerSize = 3;
1372
- } else {
1373
- headerSize = 5;
1374
- }
1375
- let maxBytes = strLength * 3;
1376
- if (position$1 + maxBytes > safeEnd)
1377
- target = makeRoom(position$1 + maxBytes);
1378
-
1379
- if (strLength < 0x40 || !encodeUtf8) {
1380
- let i, c1, c2, strPosition = position$1 + headerSize;
1381
- for (i = 0; i < strLength; i++) {
1382
- c1 = value.charCodeAt(i);
1383
- if (c1 < 0x80) {
1384
- target[strPosition++] = c1;
1385
- } else if (c1 < 0x800) {
1386
- target[strPosition++] = c1 >> 6 | 0xc0;
1387
- target[strPosition++] = c1 & 0x3f | 0x80;
1388
- } else if (
1389
- (c1 & 0xfc00) === 0xd800 &&
1390
- ((c2 = value.charCodeAt(i + 1)) & 0xfc00) === 0xdc00
1391
- ) {
1392
- c1 = 0x10000 + ((c1 & 0x03ff) << 10) + (c2 & 0x03ff);
1393
- i++;
1394
- target[strPosition++] = c1 >> 18 | 0xf0;
1395
- target[strPosition++] = c1 >> 12 & 0x3f | 0x80;
1396
- target[strPosition++] = c1 >> 6 & 0x3f | 0x80;
1397
- target[strPosition++] = c1 & 0x3f | 0x80;
1398
- } else {
1399
- target[strPosition++] = c1 >> 12 | 0xe0;
1400
- target[strPosition++] = c1 >> 6 & 0x3f | 0x80;
1401
- target[strPosition++] = c1 & 0x3f | 0x80;
1402
- }
1403
- }
1404
- length = strPosition - position$1 - headerSize;
1405
- } else {
1406
- length = encodeUtf8(value, position$1 + headerSize, maxBytes);
1407
- }
1408
-
1409
- if (length < 0x18) {
1410
- target[position$1++] = 0x60 | length;
1411
- } else if (length < 0x100) {
1412
- if (headerSize < 2) {
1413
- target.copyWithin(position$1 + 2, position$1 + 1, position$1 + 1 + length);
1414
- }
1415
- target[position$1++] = 0x78;
1416
- target[position$1++] = length;
1417
- } else if (length < 0x10000) {
1418
- if (headerSize < 3) {
1419
- target.copyWithin(position$1 + 3, position$1 + 2, position$1 + 2 + length);
1420
- }
1421
- target[position$1++] = 0x79;
1422
- target[position$1++] = length >> 8;
1423
- target[position$1++] = length & 0xff;
1424
- } else {
1425
- if (headerSize < 5) {
1426
- target.copyWithin(position$1 + 5, position$1 + 3, position$1 + 3 + length);
1427
- }
1428
- target[position$1++] = 0x7a;
1429
- targetView.setUint32(position$1, length);
1430
- position$1 += 4;
1431
- }
1432
- position$1 += length;
1433
- } else if (type === 'number') {
1434
- if (value >>> 0 === value) {// positive integer, 32-bit or less
1435
- // positive uint
1436
- if (value < 0x18) {
1437
- target[position$1++] = value;
1438
- } else if (value < 0x100) {
1439
- target[position$1++] = 0x18;
1440
- target[position$1++] = value;
1441
- } else if (value < 0x10000) {
1442
- target[position$1++] = 0x19;
1443
- target[position$1++] = value >> 8;
1444
- target[position$1++] = value & 0xff;
1445
- } else {
1446
- target[position$1++] = 0x1a;
1447
- targetView.setUint32(position$1, value);
1448
- position$1 += 4;
1449
- }
1450
- } else if (value >> 0 === value) { // negative integer
1451
- if (value >= -0x18) {
1452
- target[position$1++] = 0x1f - value;
1453
- } else if (value >= -0x100) {
1454
- target[position$1++] = 0x38;
1455
- target[position$1++] = ~value;
1456
- } else if (value >= -0x10000) {
1457
- target[position$1++] = 0x39;
1458
- targetView.setUint16(position$1, ~value);
1459
- position$1 += 2;
1460
- } else {
1461
- target[position$1++] = 0x3a;
1462
- targetView.setUint32(position$1, ~value);
1463
- position$1 += 4;
1464
- }
1465
- } else {
1466
- let useFloat32;
1467
- if ((useFloat32 = this.useFloat32) > 0 && value < 0x100000000 && value >= -0x80000000) {
1468
- target[position$1++] = 0xfa;
1469
- targetView.setFloat32(position$1, value);
1470
- let xShifted;
1471
- if (useFloat32 < 4 ||
1472
- // this checks for rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
1473
- ((xShifted = value * mult10[((target[position$1] & 0x7f) << 1) | (target[position$1 + 1] >> 7)]) >> 0) === xShifted) {
1474
- position$1 += 4;
1475
- return
1476
- } else
1477
- position$1--; // move back into position for writing a double
1478
- }
1479
- target[position$1++] = 0xfb;
1480
- targetView.setFloat64(position$1, value);
1481
- position$1 += 8;
1482
- }
1483
- } else if (type === 'object') {
1484
- if (!value)
1485
- target[position$1++] = 0xf6;
1486
- else {
1487
- if (referenceMap) {
1488
- let referee = referenceMap.get(value);
1489
- if (referee) {
1490
- target[position$1++] = 0xd8;
1491
- target[position$1++] = 29; // http://cbor.schmorp.de/value-sharing
1492
- target[position$1++] = 0x19; // 16-bit uint
1493
- if (!referee.references) {
1494
- let idsToInsert = referenceMap.idsToInsert || (referenceMap.idsToInsert = []);
1495
- referee.references = [];
1496
- idsToInsert.push(referee);
1497
- }
1498
- referee.references.push(position$1 - start);
1499
- position$1 += 2; // TODO: also support 32-bit
1500
- return
1501
- } else
1502
- referenceMap.set(value, { offset: position$1 - start });
1503
- }
1504
- let constructor = value.constructor;
1505
- if (constructor === Object) {
1506
- writeObject(value, true);
1507
- } else if (constructor === Array) {
1508
- length = value.length;
1509
- if (length < 0x18) {
1510
- target[position$1++] = 0x80 | length;
1511
- } else {
1512
- writeArrayHeader(length);
1513
- }
1514
- for (let i = 0; i < length; i++) {
1515
- encode(value[i]);
1516
- }
1517
- } else if (constructor === Map) {
1518
- if (this.mapsAsObjects ? this.useTag259ForMaps !== false : this.useTag259ForMaps) {
1519
- // use Tag 259 (https://github.com/shanewholloway/js-cbor-codec/blob/master/docs/CBOR-259-spec--explicit-maps.md) for maps if the user wants it that way
1520
- target[position$1++] = 0xd9;
1521
- target[position$1++] = 1;
1522
- target[position$1++] = 3;
1523
- }
1524
- length = value.size;
1525
- if (length < 0x18) {
1526
- target[position$1++] = 0xa0 | length;
1527
- } else if (length < 0x100) {
1528
- target[position$1++] = 0xb8;
1529
- target[position$1++] = length;
1530
- } else if (length < 0x10000) {
1531
- target[position$1++] = 0xb9;
1532
- target[position$1++] = length >> 8;
1533
- target[position$1++] = length & 0xff;
1534
- } else {
1535
- target[position$1++] = 0xba;
1536
- targetView.setUint32(position$1, length);
1537
- position$1 += 4;
1538
- }
1539
- if (encoder.keyMap) {
1540
- for (let [ key, entryValue ] of value) {
1541
- encode(encoder.encodeKey(key));
1542
- encode(entryValue);
1543
- }
1544
- } else {
1545
- for (let [ key, entryValue ] of value) {
1546
- encode(key);
1547
- encode(entryValue);
1548
- }
1549
- }
1550
- } else {
1551
- for (let i = 0, l = extensions.length; i < l; i++) {
1552
- let extensionClass = extensionClasses[i];
1553
- if (value instanceof extensionClass) {
1554
- let extension = extensions[i];
1555
- let tag = extension.tag;
1556
- if (tag == undefined)
1557
- tag = extension.getTag && extension.getTag(value);
1558
- if (tag < 0x18) {
1559
- target[position$1++] = 0xc0 | tag;
1560
- } else if (tag < 0x100) {
1561
- target[position$1++] = 0xd8;
1562
- target[position$1++] = tag;
1563
- } else if (tag < 0x10000) {
1564
- target[position$1++] = 0xd9;
1565
- target[position$1++] = tag >> 8;
1566
- target[position$1++] = tag & 0xff;
1567
- } else if (tag > -1) {
1568
- target[position$1++] = 0xda;
1569
- targetView.setUint32(position$1, tag);
1570
- position$1 += 4;
1571
- } // else undefined, don't write tag
1572
- extension.encode.call(this, value, encode, makeRoom);
1573
- return
1574
- }
1575
- }
1576
- if (value[Symbol.iterator]) {
1577
- target[position$1++] = 0x9f; // indefinite length array
1578
- for (let entry of value) {
1579
- encode(entry);
1580
- }
1581
- target[position$1++] = 0xff; // stop-code
1582
- return
1583
- }
1584
- // no extension found, write as object
1585
- writeObject(value, !value.hasOwnProperty); // if it doesn't have hasOwnProperty, don't do hasOwnProperty checks
1586
- }
1587
- }
1588
- } else if (type === 'boolean') {
1589
- target[position$1++] = value ? 0xf5 : 0xf4;
1590
- } else if (type === 'bigint') {
1591
- if (value < (BigInt(1)<<BigInt(64)) && value >= 0) {
1592
- // use an unsigned int as long as it fits
1593
- target[position$1++] = 0x1b;
1594
- targetView.setBigUint64(position$1, value);
1595
- } else if (value > -(BigInt(1)<<BigInt(64)) && value < 0) {
1596
- // if we can fit an unsigned int, use that
1597
- target[position$1++] = 0x3b;
1598
- targetView.setBigUint64(position$1, -value - BigInt(1));
1599
- } else {
1600
- // overflow
1601
- if (this.largeBigIntToFloat) {
1602
- target[position$1++] = 0xfb;
1603
- targetView.setFloat64(position$1, Number(value));
1604
- } else {
1605
- throw new RangeError(value + ' was too large to fit in CBOR 64-bit integer format, set largeBigIntToFloat to convert to float-64')
1606
- }
1607
- }
1608
- position$1 += 8;
1609
- } else if (type === 'undefined') {
1610
- target[position$1++] = 0xf7;
1611
- } else {
1612
- throw new Error('Unknown type: ' + type)
1613
- }
1614
- };
1615
-
1616
- const writeObject = this.useRecords === false ? this.variableMapSize ? (object) => {
1617
- // this method is slightly slower, but generates "preferred serialization" (optimally small for smaller objects)
1618
- let keys = Object.keys(object);
1619
- let vals = Object.values(object);
1620
- let length = keys.length;
1621
- if (length < 0x18) {
1622
- target[position$1++] = 0xa0 | length;
1623
- } else if (length < 0x100) {
1624
- target[position$1++] = 0xb8;
1625
- target[position$1++] = length;
1626
- } else if (length < 0x10000) {
1627
- target[position$1++] = 0xb9;
1628
- target[position$1++] = length >> 8;
1629
- target[position$1++] = length & 0xff;
1630
- } else {
1631
- target[position$1++] = 0xba;
1632
- targetView.setUint32(position$1, length);
1633
- position$1 += 4;
1634
- }
1635
- if (encoder.keyMap) {
1636
- for (let i = 0; i < length; i++) {
1637
- encode(encodeKey(keys[i]));
1638
- encode(vals[i]);
1639
- }
1640
- } else {
1641
- for (let i = 0; i < length; i++) {
1642
- encode(keys[i]);
1643
- encode(vals[i]);
1644
- }
1645
- }
1646
- } :
1647
- (object, safePrototype) => {
1648
- target[position$1++] = 0xb9; // always use map 16, so we can preallocate and set the length afterwards
1649
- let objectOffset = position$1 - start;
1650
- position$1 += 2;
1651
- let size = 0;
1652
- if (encoder.keyMap) {
1653
- for (let key in object) if (safePrototype || object.hasOwnProperty(key)) {
1654
- encode(encoder.encodeKey(key));
1655
- encode(object[key]);
1656
- size++;
1657
- }
1658
- } else {
1659
- for (let key in object) if (safePrototype || object.hasOwnProperty(key)) {
1660
- encode(key);
1661
- encode(object[key]);
1662
- size++;
1663
- }
1664
- }
1665
- target[objectOffset++ + start] = size >> 8;
1666
- target[objectOffset + start] = size & 0xff;
1667
- } :
1668
- (object, safePrototype) => {
1669
- let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
1670
- let newTransitions = 0;
1671
- let length = 0;
1672
- let parentRecordId;
1673
- let keys;
1674
- if (this.keyMap) {
1675
- keys = Object.keys(object).map(k => this.encodeKey(k));
1676
- length = keys.length;
1677
- for (let i = 0; i < length; i++) {
1678
- let key = keys[i];
1679
- nextTransition = transition[key];
1680
- if (!nextTransition) {
1681
- nextTransition = transition[key] = Object.create(null);
1682
- newTransitions++;
1683
- }
1684
- transition = nextTransition;
1685
- }
1686
- } else {
1687
- for (let key in object) if (safePrototype || object.hasOwnProperty(key)) {
1688
- nextTransition = transition[key];
1689
- if (!nextTransition) {
1690
- if (transition[RECORD_SYMBOL] & 0x100000) {// this indicates it is a brancheable/extendable terminal node, so we will use this record id and extend it
1691
- parentRecordId = transition[RECORD_SYMBOL] & 0xffff;
1692
- }
1693
- nextTransition = transition[key] = Object.create(null);
1694
- newTransitions++;
1695
- }
1696
- transition = nextTransition;
1697
- length++;
1698
- }
1699
- }
1700
- let recordId = transition[RECORD_SYMBOL];
1701
- if (recordId !== undefined) {
1702
- recordId &= 0xffff;
1703
- target[position$1++] = 0xd9;
1704
- target[position$1++] = (recordId >> 8) | 0xe0;
1705
- target[position$1++] = recordId & 0xff;
1706
- } else {
1707
- if (!keys)
1708
- keys = transition.__keys__ || (transition.__keys__ = Object.keys(object));
1709
- if (parentRecordId === undefined) {
1710
- recordId = structures.nextId++;
1711
- if (!recordId) {
1712
- recordId = 0;
1713
- structures.nextId = 1;
1714
- }
1715
- if (recordId >= MAX_STRUCTURES) {// cycle back around
1716
- structures.nextId = (recordId = maxSharedStructures) + 1;
1717
- }
1718
- } else {
1719
- recordId = parentRecordId;
1720
- }
1721
- structures[recordId] = keys;
1722
- if (recordId < maxSharedStructures) {
1723
- target[position$1++] = 0xd9;
1724
- target[position$1++] = (recordId >> 8) | 0xe0;
1725
- target[position$1++] = recordId & 0xff;
1726
- transition = structures.transitions;
1727
- for (let i = 0; i < length; i++) {
1728
- if (transition[RECORD_SYMBOL] === undefined || (transition[RECORD_SYMBOL] & 0x100000))
1729
- transition[RECORD_SYMBOL] = recordId;
1730
- transition = transition[keys[i]];
1731
- }
1732
- transition[RECORD_SYMBOL] = recordId | 0x100000; // indicates it is a extendable terminal
1733
- hasSharedUpdate = true;
1734
- } else {
1735
- transition[RECORD_SYMBOL] = recordId;
1736
- targetView.setUint32(position$1, 0xd9dfff00); // tag two byte, then record definition id
1737
- position$1 += 3;
1738
- if (newTransitions)
1739
- transitionsCount += serializationsSinceTransitionRebuild * newTransitions;
1740
- // record the removal of the id, we can maintain our shared structure
1741
- if (recordIdsToRemove.length >= MAX_STRUCTURES - maxSharedStructures)
1742
- recordIdsToRemove.shift()[RECORD_SYMBOL] = undefined; // we are cycling back through, and have to remove old ones
1743
- recordIdsToRemove.push(transition);
1744
- writeArrayHeader(length + 2);
1745
- encode(0xe000 + recordId);
1746
- encode(keys);
1747
- for (let v of Object.values(object)) encode(v);
1748
- return
1749
- }
1750
- }
1751
- if (length < 0x18) { // write the array header
1752
- target[position$1++] = 0x80 | length;
1753
- } else {
1754
- writeArrayHeader(length);
1755
- }
1756
- for (let key in object)
1757
- if (safePrototype || object.hasOwnProperty(key))
1758
- encode(object[key]);
1759
- };
1760
- const makeRoom = (end) => {
1761
- let newSize;
1762
- if (end > 0x1000000) {
1763
- // special handling for really large buffers
1764
- if ((end - start) > MAX_BUFFER_SIZE)
1765
- throw new Error('Encoded buffer would be larger than maximum buffer size')
1766
- newSize = Math.min(MAX_BUFFER_SIZE,
1767
- Math.round(Math.max((end - start) * (end > 0x4000000 ? 1.25 : 2), 0x400000) / 0x1000) * 0x1000);
1768
- } else // faster handling for smaller buffers
1769
- newSize = ((Math.max((end - start) << 2, target.length - 1) >> 12) + 1) << 12;
1770
- let newBuffer = new ByteArrayAllocate(newSize);
1771
- targetView = new DataView(newBuffer.buffer, 0, newSize);
1772
- if (target.copy)
1773
- target.copy(newBuffer, 0, start, end);
1774
- else
1775
- newBuffer.set(target.slice(start, end));
1776
- position$1 -= start;
1777
- start = 0;
1778
- safeEnd = newBuffer.length - 10;
1779
- return target = newBuffer
1780
- };
1781
- }
1782
- useBuffer(buffer) {
1783
- // this means we are finished using our own buffer and we can write over it safely
1784
- target = buffer;
1785
- targetView = new DataView(target.buffer, target.byteOffset, target.byteLength);
1786
- position$1 = 0;
1787
- }
1788
- clearSharedData() {
1789
- if (this.structures)
1790
- this.structures = [];
1791
- if (this.sharedValues)
1792
- this.sharedValues = undefined;
1793
- }
1794
- updateSharedData() {
1795
- let lastVersion = this.sharedVersion || 0;
1796
- this.sharedVersion = lastVersion + 1;
1797
- let structuresCopy = this.structures.slice(0);
1798
- let sharedData = new SharedData(structuresCopy, this.sharedValues, this.sharedVersion);
1799
- let saveResults = this.saveShared(sharedData,
1800
- existingShared => (existingShared && existingShared.version || 0) == lastVersion);
1801
- if (saveResults === false) {
1802
- // get updated structures and try again if the update failed
1803
- sharedData = this.getShared() || {};
1804
- this.structures = sharedData.structures || [];
1805
- this.sharedValues = sharedData.packedValues;
1806
- this.sharedVersion = sharedData.version;
1807
- this.structures.nextId = this.structures.length;
1808
- } else {
1809
- // restore structures
1810
- structuresCopy.forEach((structure, i) => this.structures[i] = structure);
1811
- }
1812
- // saveShared may fail to write and reload, or may have reloaded to check compatibility and overwrite saved data, either way load the correct shared data
1813
- return saveResults
1814
- }
1815
- }
1816
- class SharedData {
1817
- constructor(structures, values, version) {
1818
- this.structures = structures;
1819
- this.packedValues = values;
1820
- this.version = version;
1821
- }
1822
- }
1823
-
1824
- function writeArrayHeader(length) {
1825
- if (length < 0x18)
1826
- target[position$1++] = 0x80 | length;
1827
- else if (length < 0x100) {
1828
- target[position$1++] = 0x98;
1829
- target[position$1++] = length;
1830
- } else if (length < 0x10000) {
1831
- target[position$1++] = 0x99;
1832
- target[position$1++] = length >> 8;
1833
- target[position$1++] = length & 0xff;
1834
- } else {
1835
- target[position$1++] = 0x9a;
1836
- targetView.setUint32(position$1, length);
1837
- position$1 += 4;
1838
- }
1839
- }
1840
-
1841
- function findRepetitiveStrings(value, packedValues) {
1842
- switch(typeof value) {
1843
- case 'string':
1844
- if (value.length > 3) {
1845
- if (packedValues.objectMap[value] > -1 || packedValues.values.length >= packedValues.maxValues)
1846
- return
1847
- let packedStatus = packedValues.get(value);
1848
- if (packedStatus) {
1849
- if (++packedStatus.count == 2) {
1850
- packedValues.values.push(value);
1851
- }
1852
- } else {
1853
- packedValues.set(value, {
1854
- count: 1,
1855
- });
1856
- if (packedValues.samplingPackedValues) {
1857
- let status = packedValues.samplingPackedValues.get(value);
1858
- if (status)
1859
- status.count++;
1860
- else
1861
- packedValues.samplingPackedValues.set(value, {
1862
- count: 1,
1863
- });
1864
- }
1865
- }
1866
- }
1867
- break
1868
- case 'object':
1869
- if (value) {
1870
- if (value instanceof Array) {
1871
- for (let i = 0, l = value.length; i < l; i++) {
1872
- findRepetitiveStrings(value[i], packedValues);
1873
- }
1874
-
1875
- } else {
1876
- let includeKeys = !packedValues.encoder.useRecords;
1877
- for (var key in value) {
1878
- if (value.hasOwnProperty(key)) {
1879
- if (includeKeys)
1880
- findRepetitiveStrings(key, packedValues);
1881
- findRepetitiveStrings(value[key], packedValues);
1882
- }
1883
- }
1884
- }
1885
- }
1886
- break
1887
- case 'function': console.log(value);
1888
- }
1889
- }
1890
- const isLittleEndianMachine$1 = new Uint8Array(new Uint16Array([1]).buffer)[0] == 1;
1891
- extensionClasses = [ Date, Set, Error, RegExp, Tag, ArrayBuffer, ByteArray,
1892
- Uint8Array, Uint8ClampedArray, Uint16Array, Uint32Array,
1893
- typeof BigUint64Array == 'undefined' ? function() {} : BigUint64Array, Int8Array, Int16Array, Int32Array,
1894
- typeof BigInt64Array == 'undefined' ? function() {} : BigInt64Array,
1895
- Float32Array, Float64Array, SharedData];
1896
-
1897
- //Object.getPrototypeOf(Uint8Array.prototype).constructor /*TypedArray*/
1898
- extensions = [{
1899
- tag: 1,
1900
- encode(date, encode) {
1901
- let seconds = date.getTime() / 1000;
1902
- if ((this.useTimestamp32 || date.getMilliseconds() === 0) && seconds >= 0 && seconds < 0x100000000) {
1903
- // Timestamp 32
1904
- target[position$1++] = 0x1a;
1905
- targetView.setUint32(position$1, seconds);
1906
- position$1 += 4;
1907
- } else {
1908
- // Timestamp float64
1909
- target[position$1++] = 0xfb;
1910
- targetView.setFloat64(position$1, seconds);
1911
- position$1 += 8;
1912
- }
1913
- }
1914
- }, {
1915
- tag: 258, // https://github.com/input-output-hk/cbor-sets-spec/blob/master/CBOR_SETS.md
1916
- encode(set, encode) {
1917
- let array = Array.from(set);
1918
- encode(array);
1919
- }
1920
- }, {
1921
- tag: 27, // http://cbor.schmorp.de/generic-object
1922
- encode(error, encode) {
1923
- encode([ error.name, error.message ]);
1924
- }
1925
- }, {
1926
- tag: 27, // http://cbor.schmorp.de/generic-object
1927
- encode(regex, encode) {
1928
- encode([ 'RegExp', regex.source, regex.flags ]);
1929
- }
1930
- }, {
1931
- getTag(tag) {
1932
- return tag.tag
1933
- },
1934
- encode(tag, encode) {
1935
- encode(tag.value);
1936
- }
1937
- }, {
1938
- encode(arrayBuffer, encode, makeRoom) {
1939
- writeBuffer(arrayBuffer, makeRoom);
1940
- }
1941
- }, {
1942
- encode(arrayBuffer, encode, makeRoom) {
1943
- writeBuffer(arrayBuffer, makeRoom);
1944
- }
1945
- }, typedArrayEncoder(64, 1),
1946
- typedArrayEncoder(68, 1),
1947
- typedArrayEncoder(69, 2),
1948
- typedArrayEncoder(70, 4),
1949
- typedArrayEncoder(71, 8),
1950
- typedArrayEncoder(72, 1),
1951
- typedArrayEncoder(77, 2),
1952
- typedArrayEncoder(78, 4),
1953
- typedArrayEncoder(79, 8),
1954
- typedArrayEncoder(85, 4),
1955
- typedArrayEncoder(86, 8),
1956
- {
1957
- encode(sharedData, encode) { // write SharedData
1958
- let packedValues = sharedData.packedValues || [];
1959
- let sharedStructures = sharedData.structures || [];
1960
- if (packedValues.values.length > 0) {
1961
- target[position$1++] = 0xd8; // one-byte tag
1962
- target[position$1++] = 51; // tag 51 for packed shared structures https://www.potaroo.net/ietf/ids/draft-ietf-cbor-packed-03.txt
1963
- writeArrayHeader(4);
1964
- let valuesArray = packedValues.values;
1965
- encode(valuesArray);
1966
- writeArrayHeader(0); // prefixes
1967
- writeArrayHeader(0); // suffixes
1968
- packedObjectMap = Object.create(sharedPackedObjectMap || null);
1969
- for (let i = 0, l = valuesArray.length; i < l; i++) {
1970
- packedObjectMap[valuesArray[i]] = i;
1971
- }
1972
- }
1973
- if (sharedStructures) {
1974
- targetView.setUint32(position$1, 0xd9dffe00);
1975
- position$1 += 3;
1976
- let definitions = sharedStructures.slice(0);
1977
- definitions.unshift(0xe000);
1978
- definitions.push(new Tag(sharedData.version, 0x53687264));
1979
- encode(definitions);
1980
- } else
1981
- encode(new Tag(sharedData.version, 0x53687264));
1982
- }
1983
- }];
1984
- function typedArrayEncoder(tag, size) {
1985
- if (!isLittleEndianMachine$1 && size > 1)
1986
- tag -= 4; // the big endian equivalents are 4 less
1987
- return {
1988
- tag: tag,
1989
- encode: function writeExtBuffer(typedArray, encode) {
1990
- let length = typedArray.byteLength;
1991
- let offset = typedArray.byteOffset || 0;
1992
- let buffer = typedArray.buffer || typedArray;
1993
- encode(hasNodeBuffer ? Buffer.from(buffer, offset, length) :
1994
- new Uint8Array(buffer, offset, length));
1995
- }
1996
- }
1997
- }
1998
- function writeBuffer(buffer, makeRoom) {
1999
- let length = buffer.byteLength;
2000
- if (length < 0x18) {
2001
- target[position$1++] = 0x40 + length;
2002
- } else if (length < 0x100) {
2003
- target[position$1++] = 0x58;
2004
- target[position$1++] = length;
2005
- } else if (length < 0x10000) {
2006
- target[position$1++] = 0x59;
2007
- target[position$1++] = length >> 8;
2008
- target[position$1++] = length & 0xff;
2009
- } else {
2010
- target[position$1++] = 0x5a;
2011
- targetView.setUint32(position$1, length);
2012
- position$1 += 4;
2013
- }
2014
- if (position$1 + length >= target.length) {
2015
- makeRoom(position$1 + length);
2016
- }
2017
- target.set(buffer, position$1);
2018
- position$1 += length;
2019
- }
2020
-
2021
- function insertIds(serialized, idsToInsert) {
2022
- // insert the ids that need to be referenced for structured clones
2023
- let nextId;
2024
- let distanceToMove = idsToInsert.length * 2;
2025
- let lastEnd = serialized.length - distanceToMove;
2026
- idsToInsert.sort((a, b) => a.offset > b.offset ? 1 : -1);
2027
- for (let id = 0; id < idsToInsert.length; id++) {
2028
- let referee = idsToInsert[id];
2029
- referee.id = id;
2030
- for (let position of referee.references) {
2031
- serialized[position++] = id >> 8;
2032
- serialized[position] = id & 0xff;
2033
- }
2034
- }
2035
- while (nextId = idsToInsert.pop()) {
2036
- let offset = nextId.offset;
2037
- serialized.copyWithin(offset + distanceToMove, offset, lastEnd);
2038
- distanceToMove -= 2;
2039
- let position = offset + distanceToMove;
2040
- serialized[position++] = 0xd8;
2041
- serialized[position++] = 28; // http://cbor.schmorp.de/value-sharing
2042
- lastEnd = offset;
2043
- }
2044
- return serialized
2045
- }
2046
- function writeBundles(start, encode) {
2047
- targetView.setUint32(bundledStrings$1.position + start, position$1 - bundledStrings$1.position - start + 1); // the offset to bundle
2048
- let writeStrings = bundledStrings$1;
2049
- bundledStrings$1 = null;
2050
- encode(writeStrings[0]);
2051
- encode(writeStrings[1]);
2052
- }
2053
-
2054
- function addExtension$1(extension) {
2055
- if (extension.Class) {
2056
- if (!extension.encode)
2057
- throw new Error('Extension has no encode function')
2058
- extensionClasses.unshift(extension.Class);
2059
- extensions.unshift(extension);
2060
- }
2061
- addExtension(extension);
2062
- }
2063
- let defaultEncoder = new Encoder({ useRecords: false });
2064
- const encode = defaultEncoder.encode;
2065
- const { NEVER, ALWAYS, DECIMAL_ROUND, DECIMAL_FIT } = FLOAT32_OPTIONS;
2066
- const REUSE_BUFFER_MODE = 512;
900
+ const isLittleEndianMachine = new Uint8Array(new Uint16Array([1]).buffer)[0] == 1;
901
+ const typedArrays = [Uint8Array, Uint8ClampedArray, Uint16Array, Uint32Array,
902
+ typeof BigUint64Array == 'undefined' ? { name:'BigUint64Array' } : BigUint64Array, Int8Array, Int16Array, Int32Array,
903
+ typeof BigInt64Array == 'undefined' ? { name:'BigInt64Array' } : BigInt64Array, Float32Array, Float64Array];
904
+ const typedArrayTags = [64, 68, 69, 70, 71, 72, 77, 78, 79, 85, 86];
905
+ for (let i = 0; i < typedArrays.length; i++) {
906
+ registerTypedArray(typedArrays[i], typedArrayTags[i]);
907
+ }
908
+ function registerTypedArray(TypedArray, tag) {
909
+ let dvMethod = 'get' + TypedArray.name.slice(0, -5);
910
+ if (typeof TypedArray !== 'function')
911
+ TypedArray = null;
912
+ let bytesPerElement = TypedArray.BYTES_PER_ELEMENT;
913
+ for (let littleEndian = 0; littleEndian < 2; littleEndian++) {
914
+ if (!littleEndian && bytesPerElement == 1)
915
+ continue
916
+ let sizeShift = bytesPerElement == 2 ? 1 : bytesPerElement == 4 ? 2 : 3;
917
+ currentExtensions[littleEndian ? tag : (tag - 4)] = (bytesPerElement == 1 || littleEndian == isLittleEndianMachine) ? (buffer) => {
918
+ if (!TypedArray)
919
+ throw new Error('Could not find typed array for code ' + tag)
920
+ // we have to always slice/copy here to get a new ArrayBuffer that is word/byte aligned
921
+ return new TypedArray(Uint8Array.prototype.slice.call(buffer, 0).buffer)
922
+ } : buffer => {
923
+ if (!TypedArray)
924
+ throw new Error('Could not find typed array for code ' + tag)
925
+ let dv = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
926
+ let elements = buffer.length >> sizeShift;
927
+ let ta = new TypedArray(elements);
928
+ let method = dv[dvMethod];
929
+ for (let i = 0; i < elements; i++) {
930
+ ta[i] = method.call(dv, i << sizeShift, littleEndian);
931
+ }
932
+ return ta
933
+ };
934
+ }
935
+ }
936
+
937
+ function readBundleExt() {
938
+ let length = readJustLength();
939
+ let bundlePosition = position + read();
940
+ for (let i = 2; i < length; i++) {
941
+ // skip past bundles that were already read
942
+ let bundleLength = readJustLength(); // this will increment position, so must add to position afterwards
943
+ position += bundleLength;
944
+ }
945
+ let dataPosition = position;
946
+ position = bundlePosition;
947
+ bundledStrings = [readStringJS(readJustLength()), readStringJS(readJustLength())];
948
+ bundledStrings.position0 = 0;
949
+ bundledStrings.position1 = 0;
950
+ bundledStrings.postBundlePosition = position;
951
+ position = dataPosition;
952
+ return read()
953
+ }
954
+
955
+ function readJustLength() {
956
+ let token = src[position++] & 0x1f;
957
+ if (token > 0x17) {
958
+ switch (token) {
959
+ case 0x18:
960
+ token = src[position++];
961
+ break
962
+ case 0x19:
963
+ token = dataView.getUint16(position);
964
+ position += 2;
965
+ break
966
+ case 0x1a:
967
+ token = dataView.getUint32(position);
968
+ position += 4;
969
+ break
970
+ }
971
+ }
972
+ return token
973
+ }
974
+
975
+ function loadShared() {
976
+ if (currentDecoder.getShared) {
977
+ let sharedData = saveState(() => {
978
+ // save the state in case getShared modifies our buffer
979
+ src = null;
980
+ return currentDecoder.getShared()
981
+ }) || {};
982
+ let updatedStructures = sharedData.structures || [];
983
+ currentDecoder.sharedVersion = sharedData.version;
984
+ packedValues = currentDecoder.sharedValues = sharedData.packedValues;
985
+ if (currentStructures === true)
986
+ currentDecoder.structures = currentStructures = updatedStructures;
987
+ else
988
+ currentStructures.splice.apply(currentStructures, [0, updatedStructures.length].concat(updatedStructures));
989
+ }
990
+ }
991
+
992
+ function saveState(callback) {
993
+ let savedSrcEnd = srcEnd;
994
+ let savedPosition = position;
995
+ let savedSrcStringStart = srcStringStart;
996
+ let savedSrcStringEnd = srcStringEnd;
997
+ let savedSrcString = srcString;
998
+ let savedReferenceMap = referenceMap;
999
+ let savedBundledStrings = bundledStrings;
1000
+
1001
+ // TODO: We may need to revisit this if we do more external calls to user code (since it could be slow)
1002
+ let savedSrc = new Uint8Array(src.slice(0, srcEnd)); // we copy the data in case it changes while external data is processed
1003
+ let savedStructures = currentStructures;
1004
+ let savedDecoder = currentDecoder;
1005
+ let savedSequentialMode = sequentialMode;
1006
+ let value = callback();
1007
+ srcEnd = savedSrcEnd;
1008
+ position = savedPosition;
1009
+ srcStringStart = savedSrcStringStart;
1010
+ srcStringEnd = savedSrcStringEnd;
1011
+ srcString = savedSrcString;
1012
+ referenceMap = savedReferenceMap;
1013
+ bundledStrings = savedBundledStrings;
1014
+ src = savedSrc;
1015
+ sequentialMode = savedSequentialMode;
1016
+ currentStructures = savedStructures;
1017
+ currentDecoder = savedDecoder;
1018
+ dataView = new DataView(src.buffer, src.byteOffset, src.byteLength);
1019
+ return value
1020
+ }
1021
+ function clearSource() {
1022
+ src = null;
1023
+ referenceMap = null;
1024
+ currentStructures = null;
1025
+ }
1026
+
1027
+ function addExtension(extension) {
1028
+ currentExtensions[extension.tag] = extension.decode;
1029
+ }
1030
+
1031
+ const mult10 = new Array(147); // this is a table matching binary exponents to the multiplier to determine significant digit rounding
1032
+ for (let i = 0; i < 256; i++) {
1033
+ mult10[i] = +('1e' + Math.floor(45.15 - i * 0.30103));
1034
+ }
1035
+ let defaultDecoder = new Decoder({ useRecords: false });
1036
+ const decode = defaultDecoder.decode;
1037
+ const decodeMultiple = defaultDecoder.decodeMultiple;
1038
+ const FLOAT32_OPTIONS = {
1039
+ NEVER: 0,
1040
+ ALWAYS: 1,
1041
+ DECIMAL_ROUND: 3,
1042
+ DECIMAL_FIT: 4
1043
+ };
1044
+ let f32Array = new Float32Array(1);
1045
+ let u8Array = new Uint8Array(f32Array.buffer, 0, 4);
1046
+ function roundFloat32(float32Number) {
1047
+ f32Array[0] = float32Number;
1048
+ let multiplier = mult10[((u8Array[3] & 0x7f) << 1) | (u8Array[2] >> 7)];
1049
+ return ((multiplier * float32Number + (float32Number > 0 ? 0.5 : -0.5)) >> 0) / multiplier
1050
+ }
1051
+
1052
+ let textEncoder;
1053
+ try {
1054
+ textEncoder = new TextEncoder();
1055
+ } catch (error) {}
1056
+ let extensions, extensionClasses;
1057
+ const hasNodeBuffer = typeof Buffer !== 'undefined';
1058
+ const ByteArrayAllocate = hasNodeBuffer ? Buffer.allocUnsafeSlow : Uint8Array;
1059
+ const ByteArray = hasNodeBuffer ? Buffer : Uint8Array;
1060
+ const MAX_STRUCTURES = 0x100;
1061
+ const MAX_BUFFER_SIZE = hasNodeBuffer ? 0x100000000 : 0x7fd00000;
1062
+ let target;
1063
+ let targetView;
1064
+ let position$1 = 0;
1065
+ let safeEnd;
1066
+ let bundledStrings$1 = null;
1067
+ const MAX_BUNDLE_SIZE = 0xf000;
1068
+ const hasNonLatin = /[\u0080-\uFFFF]/;
1069
+ const RECORD_SYMBOL = Symbol('record-id');
1070
+ class Encoder extends Decoder {
1071
+ constructor(options) {
1072
+ super(options);
1073
+ this.offset = 0;
1074
+ let start;
1075
+ let sharedStructures;
1076
+ let hasSharedUpdate;
1077
+ let structures;
1078
+ let referenceMap;
1079
+ options = options || {};
1080
+ let encodeUtf8 = ByteArray.prototype.utf8Write ? function(string, position, maxBytes) {
1081
+ return target.utf8Write(string, position, maxBytes)
1082
+ } : (textEncoder && textEncoder.encodeInto) ?
1083
+ function(string, position) {
1084
+ return textEncoder.encodeInto(string, target.subarray(position)).written
1085
+ } : false;
1086
+
1087
+ let encoder = this;
1088
+ let hasSharedStructures = options.structures || options.saveStructures;
1089
+ let maxSharedStructures = options.maxSharedStructures;
1090
+ if (maxSharedStructures == null)
1091
+ maxSharedStructures = hasSharedStructures ? 128 : 0;
1092
+ if (maxSharedStructures > 8190)
1093
+ throw new Error('Maximum maxSharedStructure is 8190')
1094
+ let isSequential = options.sequential;
1095
+ if (isSequential) {
1096
+ maxSharedStructures = 0;
1097
+ }
1098
+ if (!this.structures)
1099
+ this.structures = [];
1100
+ if (this.saveStructures)
1101
+ this.saveShared = this.saveStructures;
1102
+ let samplingPackedValues, packedObjectMap, sharedValues = options.sharedValues;
1103
+ let sharedPackedObjectMap;
1104
+ if (sharedValues) {
1105
+ sharedPackedObjectMap = Object.create(null);
1106
+ for (let i = 0, l = sharedValues.length; i < l; i++) {
1107
+ sharedPackedObjectMap[sharedValues[i]] = i;
1108
+ }
1109
+ }
1110
+ let recordIdsToRemove = [];
1111
+ let transitionsCount = 0;
1112
+ let serializationsSinceTransitionRebuild = 0;
1113
+
1114
+ this.mapEncode = function(value, encodeOptions) {
1115
+ // Experimental support for premapping keys using _keyMap instad of keyMap - not optiimised yet)
1116
+ if (this._keyMap && !this._mapped) {
1117
+ //console.log('encoding ', value)
1118
+ switch (value.constructor.name) {
1119
+ case 'Array':
1120
+ value = value.map(r => this.encodeKeys(r));
1121
+ break
1122
+ //case 'Map':
1123
+ // value = this.encodeKeys(value)
1124
+ // break
1125
+ }
1126
+ //this._mapped = true
1127
+ }
1128
+ return this.encode(value, encodeOptions)
1129
+ };
1130
+
1131
+ this.encode = function(value, encodeOptions) {
1132
+ if (!target) {
1133
+ target = new ByteArrayAllocate(8192);
1134
+ targetView = new DataView(target.buffer, 0, 8192);
1135
+ position$1 = 0;
1136
+ }
1137
+ safeEnd = target.length - 10;
1138
+ if (safeEnd - position$1 < 0x800) {
1139
+ // don't start too close to the end,
1140
+ target = new ByteArrayAllocate(target.length);
1141
+ targetView = new DataView(target.buffer, 0, target.length);
1142
+ safeEnd = target.length - 10;
1143
+ position$1 = 0;
1144
+ } else if (encodeOptions === REUSE_BUFFER_MODE)
1145
+ position$1 = (position$1 + 7) & 0x7ffffff8; // Word align to make any future copying of this buffer faster
1146
+ start = position$1;
1147
+ if (encoder.useSelfDescribedHeader) {
1148
+ targetView.setUint32(position$1, 0xd9d9f700); // tag two byte, then self-descriptive tag
1149
+ position$1 += 3;
1150
+ }
1151
+ referenceMap = encoder.structuredClone ? new Map() : null;
1152
+ if (encoder.bundleStrings && typeof value !== 'string') {
1153
+ bundledStrings$1 = [];
1154
+ bundledStrings$1.size = Infinity; // force a new bundle start on first string
1155
+ } else
1156
+ bundledStrings$1 = null;
1157
+
1158
+ sharedStructures = encoder.structures;
1159
+ if (sharedStructures) {
1160
+ if (sharedStructures.uninitialized) {
1161
+ let sharedData = encoder.getShared() || {};
1162
+ encoder.structures = sharedStructures = sharedData.structures || [];
1163
+ encoder.sharedVersion = sharedData.version;
1164
+ let sharedValues = encoder.sharedValues = sharedData.packedValues;
1165
+ if (sharedValues) {
1166
+ sharedPackedObjectMap = {};
1167
+ for (let i = 0, l = sharedValues.length; i < l; i++)
1168
+ sharedPackedObjectMap[sharedValues[i]] = i;
1169
+ }
1170
+ }
1171
+ let sharedStructuresLength = sharedStructures.length;
1172
+ if (sharedStructuresLength > maxSharedStructures && !isSequential)
1173
+ sharedStructuresLength = maxSharedStructures;
1174
+ if (!sharedStructures.transitions) {
1175
+ // rebuild our structure transitions
1176
+ sharedStructures.transitions = Object.create(null);
1177
+ for (let i = 0; i < sharedStructuresLength; i++) {
1178
+ let keys = sharedStructures[i];
1179
+ //console.log('shared struct keys:', keys)
1180
+ if (!keys)
1181
+ continue
1182
+ let nextTransition, transition = sharedStructures.transitions;
1183
+ for (let j = 0, l = keys.length; j < l; j++) {
1184
+ if (transition[RECORD_SYMBOL] === undefined)
1185
+ transition[RECORD_SYMBOL] = i;
1186
+ let key = keys[j];
1187
+ nextTransition = transition[key];
1188
+ if (!nextTransition) {
1189
+ nextTransition = transition[key] = Object.create(null);
1190
+ }
1191
+ transition = nextTransition;
1192
+ }
1193
+ transition[RECORD_SYMBOL] = i | 0x100000;
1194
+ }
1195
+ }
1196
+ if (!isSequential)
1197
+ sharedStructures.nextId = sharedStructuresLength;
1198
+ }
1199
+ if (hasSharedUpdate)
1200
+ hasSharedUpdate = false;
1201
+ structures = sharedStructures || [];
1202
+ packedObjectMap = sharedPackedObjectMap;
1203
+ if (options.pack) {
1204
+ let packedValues = new Map();
1205
+ packedValues.values = [];
1206
+ packedValues.encoder = encoder;
1207
+ packedValues.maxValues = options.maxPrivatePackedValues || (sharedPackedObjectMap ? 16 : Infinity);
1208
+ packedValues.objectMap = sharedPackedObjectMap || false;
1209
+ packedValues.samplingPackedValues = samplingPackedValues;
1210
+ findRepetitiveStrings(value, packedValues);
1211
+ if (packedValues.values.length > 0) {
1212
+ target[position$1++] = 0xd8; // one-byte tag
1213
+ target[position$1++] = 51; // tag 51 for packed shared structures https://www.potaroo.net/ietf/ids/draft-ietf-cbor-packed-03.txt
1214
+ writeArrayHeader(4);
1215
+ let valuesArray = packedValues.values;
1216
+ encode(valuesArray);
1217
+ writeArrayHeader(0); // prefixes
1218
+ writeArrayHeader(0); // suffixes
1219
+ packedObjectMap = Object.create(sharedPackedObjectMap || null);
1220
+ for (let i = 0, l = valuesArray.length; i < l; i++) {
1221
+ packedObjectMap[valuesArray[i]] = i;
1222
+ }
1223
+ }
1224
+ }
1225
+ try {
1226
+ encode(value);
1227
+ if (bundledStrings$1) {
1228
+ writeBundles(start, encode);
1229
+ }
1230
+ encoder.offset = position$1; // update the offset so next serialization doesn't write over our buffer, but can continue writing to same buffer sequentially
1231
+ if (referenceMap && referenceMap.idsToInsert) {
1232
+ position$1 += referenceMap.idsToInsert.length * 2;
1233
+ if (position$1 > safeEnd)
1234
+ makeRoom(position$1);
1235
+ encoder.offset = position$1;
1236
+ let serialized = insertIds(target.subarray(start, position$1), referenceMap.idsToInsert);
1237
+ referenceMap = null;
1238
+ return serialized
1239
+ }
1240
+ if (encodeOptions & REUSE_BUFFER_MODE) {
1241
+ target.start = start;
1242
+ target.end = position$1;
1243
+ return target
1244
+ }
1245
+ return target.subarray(start, position$1) // position can change if we call encode again in saveShared, so we get the buffer now
1246
+ } finally {
1247
+ if (sharedStructures) {
1248
+ if (serializationsSinceTransitionRebuild < 10)
1249
+ serializationsSinceTransitionRebuild++;
1250
+ if (sharedStructures.length > maxSharedStructures)
1251
+ sharedStructures.length = maxSharedStructures;
1252
+ if (transitionsCount > 10000) {
1253
+ // force a rebuild occasionally after a lot of transitions so it can get cleaned up
1254
+ sharedStructures.transitions = null;
1255
+ serializationsSinceTransitionRebuild = 0;
1256
+ transitionsCount = 0;
1257
+ if (recordIdsToRemove.length > 0)
1258
+ recordIdsToRemove = [];
1259
+ } else if (recordIdsToRemove.length > 0 && !isSequential) {
1260
+ for (let i = 0, l = recordIdsToRemove.length; i < l; i++) {
1261
+ recordIdsToRemove[i][RECORD_SYMBOL] = undefined;
1262
+ }
1263
+ recordIdsToRemove = [];
1264
+ //sharedStructures.nextId = maxSharedStructures
1265
+ }
1266
+ }
1267
+ if (hasSharedUpdate && encoder.saveShared) {
1268
+ if (encoder.structures.length > maxSharedStructures) {
1269
+ encoder.structures = encoder.structures.slice(0, maxSharedStructures);
1270
+ }
1271
+ // we can't rely on start/end with REUSE_BUFFER_MODE since they will (probably) change when we save
1272
+ let returnBuffer = target.subarray(start, position$1);
1273
+ if (encoder.updateSharedData() === false)
1274
+ return encoder.encode(value) // re-encode if it fails
1275
+ return returnBuffer
1276
+ }
1277
+ if (encodeOptions & RESET_BUFFER_MODE)
1278
+ position$1 = start;
1279
+ }
1280
+ };
1281
+ this.findCommonStringsToPack = () => {
1282
+ samplingPackedValues = new Map();
1283
+ if (!sharedPackedObjectMap)
1284
+ sharedPackedObjectMap = Object.create(null);
1285
+ return (options) => {
1286
+ let threshold = options && options.threshold || 4;
1287
+ let position = this.pack ? options.maxPrivatePackedValues || 16 : 0;
1288
+ if (!sharedValues)
1289
+ sharedValues = this.sharedValues = [];
1290
+ for (let [ key, status ] of samplingPackedValues) {
1291
+ if (status.count > threshold) {
1292
+ sharedPackedObjectMap[key] = position++;
1293
+ sharedValues.push(key);
1294
+ hasSharedUpdate = true;
1295
+ }
1296
+ }
1297
+ while (this.saveShared && this.updateSharedData() === false) {}
1298
+ samplingPackedValues = null;
1299
+ }
1300
+ };
1301
+ const encode = (value) => {
1302
+ if (position$1 > safeEnd)
1303
+ target = makeRoom(position$1);
1304
+
1305
+ var type = typeof value;
1306
+ var length;
1307
+ if (type === 'string') {
1308
+ if (packedObjectMap) {
1309
+ let packedPosition = packedObjectMap[value];
1310
+ if (packedPosition >= 0) {
1311
+ if (packedPosition < 16)
1312
+ target[position$1++] = packedPosition + 0xe0; // simple values, defined in https://www.potaroo.net/ietf/ids/draft-ietf-cbor-packed-03.txt
1313
+ else {
1314
+ target[position$1++] = 0xc6; // tag 6 defined in https://www.potaroo.net/ietf/ids/draft-ietf-cbor-packed-03.txt
1315
+ if (packedPosition & 1)
1316
+ encode((15 - packedPosition) >> 1);
1317
+ else
1318
+ encode((packedPosition - 16) >> 1);
1319
+ }
1320
+ return
1321
+ /* } else if (packedStatus.serializationId != serializationId) {
1322
+ packedStatus.serializationId = serializationId
1323
+ packedStatus.count = 1
1324
+ if (options.sharedPack) {
1325
+ let sharedCount = packedStatus.sharedCount = (packedStatus.sharedCount || 0) + 1
1326
+ if (shareCount > (options.sharedPack.threshold || 5)) {
1327
+ let sharedPosition = packedStatus.position = packedStatus.nextSharedPosition
1328
+ hasSharedUpdate = true
1329
+ if (sharedPosition < 16)
1330
+ target[position++] = sharedPosition + 0xc0
1331
+
1332
+ }
1333
+ }
1334
+ } // else any in-doc incrementation?*/
1335
+ } else if (samplingPackedValues && !options.pack) {
1336
+ let status = samplingPackedValues.get(value);
1337
+ if (status)
1338
+ status.count++;
1339
+ else
1340
+ samplingPackedValues.set(value, {
1341
+ count: 1,
1342
+ });
1343
+ }
1344
+ }
1345
+ let strLength = value.length;
1346
+ if (bundledStrings$1 && strLength >= 4 && strLength < 0x400) {
1347
+ if ((bundledStrings$1.size += strLength) > MAX_BUNDLE_SIZE) {
1348
+ let extStart;
1349
+ let maxBytes = (bundledStrings$1[0] ? bundledStrings$1[0].length * 3 + bundledStrings$1[1].length : 0) + 10;
1350
+ if (position$1 + maxBytes > safeEnd)
1351
+ target = makeRoom(position$1 + maxBytes);
1352
+ target[position$1++] = 0xd9; // tag 16-bit
1353
+ target[position$1++] = 0xdf; // tag 0xdff9
1354
+ target[position$1++] = 0xf9;
1355
+ // TODO: If we only have one bundle with any string data, only write one string bundle
1356
+ target[position$1++] = bundledStrings$1.position ? 0x84 : 0x82; // array of 4 or 2 elements depending on if we write bundles
1357
+ target[position$1++] = 0x1a; // 32-bit unsigned int
1358
+ extStart = position$1 - start;
1359
+ position$1 += 4; // reserve for writing bundle reference
1360
+ if (bundledStrings$1.position) {
1361
+ writeBundles(start, encode); // write the last bundles
1362
+ }
1363
+ bundledStrings$1 = ['', '']; // create new ones
1364
+ bundledStrings$1.size = 0;
1365
+ bundledStrings$1.position = extStart;
1366
+ }
1367
+ let twoByte = hasNonLatin.test(value);
1368
+ bundledStrings$1[twoByte ? 0 : 1] += value;
1369
+ target[position$1++] = twoByte ? 0xce : 0xcf;
1370
+ encode(strLength);
1371
+ return
1372
+ }
1373
+ let headerSize;
1374
+ // first we estimate the header size, so we can write to the correct location
1375
+ if (strLength < 0x20) {
1376
+ headerSize = 1;
1377
+ } else if (strLength < 0x100) {
1378
+ headerSize = 2;
1379
+ } else if (strLength < 0x10000) {
1380
+ headerSize = 3;
1381
+ } else {
1382
+ headerSize = 5;
1383
+ }
1384
+ let maxBytes = strLength * 3;
1385
+ if (position$1 + maxBytes > safeEnd)
1386
+ target = makeRoom(position$1 + maxBytes);
1387
+
1388
+ if (strLength < 0x40 || !encodeUtf8) {
1389
+ let i, c1, c2, strPosition = position$1 + headerSize;
1390
+ for (i = 0; i < strLength; i++) {
1391
+ c1 = value.charCodeAt(i);
1392
+ if (c1 < 0x80) {
1393
+ target[strPosition++] = c1;
1394
+ } else if (c1 < 0x800) {
1395
+ target[strPosition++] = c1 >> 6 | 0xc0;
1396
+ target[strPosition++] = c1 & 0x3f | 0x80;
1397
+ } else if (
1398
+ (c1 & 0xfc00) === 0xd800 &&
1399
+ ((c2 = value.charCodeAt(i + 1)) & 0xfc00) === 0xdc00
1400
+ ) {
1401
+ c1 = 0x10000 + ((c1 & 0x03ff) << 10) + (c2 & 0x03ff);
1402
+ i++;
1403
+ target[strPosition++] = c1 >> 18 | 0xf0;
1404
+ target[strPosition++] = c1 >> 12 & 0x3f | 0x80;
1405
+ target[strPosition++] = c1 >> 6 & 0x3f | 0x80;
1406
+ target[strPosition++] = c1 & 0x3f | 0x80;
1407
+ } else {
1408
+ target[strPosition++] = c1 >> 12 | 0xe0;
1409
+ target[strPosition++] = c1 >> 6 & 0x3f | 0x80;
1410
+ target[strPosition++] = c1 & 0x3f | 0x80;
1411
+ }
1412
+ }
1413
+ length = strPosition - position$1 - headerSize;
1414
+ } else {
1415
+ length = encodeUtf8(value, position$1 + headerSize, maxBytes);
1416
+ }
1417
+
1418
+ if (length < 0x18) {
1419
+ target[position$1++] = 0x60 | length;
1420
+ } else if (length < 0x100) {
1421
+ if (headerSize < 2) {
1422
+ target.copyWithin(position$1 + 2, position$1 + 1, position$1 + 1 + length);
1423
+ }
1424
+ target[position$1++] = 0x78;
1425
+ target[position$1++] = length;
1426
+ } else if (length < 0x10000) {
1427
+ if (headerSize < 3) {
1428
+ target.copyWithin(position$1 + 3, position$1 + 2, position$1 + 2 + length);
1429
+ }
1430
+ target[position$1++] = 0x79;
1431
+ target[position$1++] = length >> 8;
1432
+ target[position$1++] = length & 0xff;
1433
+ } else {
1434
+ if (headerSize < 5) {
1435
+ target.copyWithin(position$1 + 5, position$1 + 3, position$1 + 3 + length);
1436
+ }
1437
+ target[position$1++] = 0x7a;
1438
+ targetView.setUint32(position$1, length);
1439
+ position$1 += 4;
1440
+ }
1441
+ position$1 += length;
1442
+ } else if (type === 'number') {
1443
+ if (value >>> 0 === value) {// positive integer, 32-bit or less
1444
+ // positive uint
1445
+ if (value < 0x18) {
1446
+ target[position$1++] = value;
1447
+ } else if (value < 0x100) {
1448
+ target[position$1++] = 0x18;
1449
+ target[position$1++] = value;
1450
+ } else if (value < 0x10000) {
1451
+ target[position$1++] = 0x19;
1452
+ target[position$1++] = value >> 8;
1453
+ target[position$1++] = value & 0xff;
1454
+ } else {
1455
+ target[position$1++] = 0x1a;
1456
+ targetView.setUint32(position$1, value);
1457
+ position$1 += 4;
1458
+ }
1459
+ } else if (value >> 0 === value) { // negative integer
1460
+ if (value >= -0x18) {
1461
+ target[position$1++] = 0x1f - value;
1462
+ } else if (value >= -0x100) {
1463
+ target[position$1++] = 0x38;
1464
+ target[position$1++] = ~value;
1465
+ } else if (value >= -0x10000) {
1466
+ target[position$1++] = 0x39;
1467
+ targetView.setUint16(position$1, ~value);
1468
+ position$1 += 2;
1469
+ } else {
1470
+ target[position$1++] = 0x3a;
1471
+ targetView.setUint32(position$1, ~value);
1472
+ position$1 += 4;
1473
+ }
1474
+ } else {
1475
+ let useFloat32;
1476
+ if ((useFloat32 = this.useFloat32) > 0 && value < 0x100000000 && value >= -0x80000000) {
1477
+ target[position$1++] = 0xfa;
1478
+ targetView.setFloat32(position$1, value);
1479
+ let xShifted;
1480
+ if (useFloat32 < 4 ||
1481
+ // this checks for rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
1482
+ ((xShifted = value * mult10[((target[position$1] & 0x7f) << 1) | (target[position$1 + 1] >> 7)]) >> 0) === xShifted) {
1483
+ position$1 += 4;
1484
+ return
1485
+ } else
1486
+ position$1--; // move back into position for writing a double
1487
+ }
1488
+ target[position$1++] = 0xfb;
1489
+ targetView.setFloat64(position$1, value);
1490
+ position$1 += 8;
1491
+ }
1492
+ } else if (type === 'object') {
1493
+ if (!value)
1494
+ target[position$1++] = 0xf6;
1495
+ else {
1496
+ if (referenceMap) {
1497
+ let referee = referenceMap.get(value);
1498
+ if (referee) {
1499
+ target[position$1++] = 0xd8;
1500
+ target[position$1++] = 29; // http://cbor.schmorp.de/value-sharing
1501
+ target[position$1++] = 0x19; // 16-bit uint
1502
+ if (!referee.references) {
1503
+ let idsToInsert = referenceMap.idsToInsert || (referenceMap.idsToInsert = []);
1504
+ referee.references = [];
1505
+ idsToInsert.push(referee);
1506
+ }
1507
+ referee.references.push(position$1 - start);
1508
+ position$1 += 2; // TODO: also support 32-bit
1509
+ return
1510
+ } else
1511
+ referenceMap.set(value, { offset: position$1 - start });
1512
+ }
1513
+ let constructor = value.constructor;
1514
+ if (constructor === Object) {
1515
+ writeObject(value, true);
1516
+ } else if (constructor === Array) {
1517
+ length = value.length;
1518
+ if (length < 0x18) {
1519
+ target[position$1++] = 0x80 | length;
1520
+ } else {
1521
+ writeArrayHeader(length);
1522
+ }
1523
+ for (let i = 0; i < length; i++) {
1524
+ encode(value[i]);
1525
+ }
1526
+ } else if (constructor === Map) {
1527
+ if (this.mapsAsObjects ? this.useTag259ForMaps !== false : this.useTag259ForMaps) {
1528
+ // use Tag 259 (https://github.com/shanewholloway/js-cbor-codec/blob/master/docs/CBOR-259-spec--explicit-maps.md) for maps if the user wants it that way
1529
+ target[position$1++] = 0xd9;
1530
+ target[position$1++] = 1;
1531
+ target[position$1++] = 3;
1532
+ }
1533
+ length = value.size;
1534
+ if (length < 0x18) {
1535
+ target[position$1++] = 0xa0 | length;
1536
+ } else if (length < 0x100) {
1537
+ target[position$1++] = 0xb8;
1538
+ target[position$1++] = length;
1539
+ } else if (length < 0x10000) {
1540
+ target[position$1++] = 0xb9;
1541
+ target[position$1++] = length >> 8;
1542
+ target[position$1++] = length & 0xff;
1543
+ } else {
1544
+ target[position$1++] = 0xba;
1545
+ targetView.setUint32(position$1, length);
1546
+ position$1 += 4;
1547
+ }
1548
+ if (encoder.keyMap) {
1549
+ for (let [ key, entryValue ] of value) {
1550
+ encode(encoder.encodeKey(key));
1551
+ encode(entryValue);
1552
+ }
1553
+ } else {
1554
+ for (let [ key, entryValue ] of value) {
1555
+ encode(key);
1556
+ encode(entryValue);
1557
+ }
1558
+ }
1559
+ } else {
1560
+ for (let i = 0, l = extensions.length; i < l; i++) {
1561
+ let extensionClass = extensionClasses[i];
1562
+ if (value instanceof extensionClass) {
1563
+ let extension = extensions[i];
1564
+ let tag = extension.tag;
1565
+ if (tag == undefined)
1566
+ tag = extension.getTag && extension.getTag.call(this, value);
1567
+ if (tag < 0x18) {
1568
+ target[position$1++] = 0xc0 | tag;
1569
+ } else if (tag < 0x100) {
1570
+ target[position$1++] = 0xd8;
1571
+ target[position$1++] = tag;
1572
+ } else if (tag < 0x10000) {
1573
+ target[position$1++] = 0xd9;
1574
+ target[position$1++] = tag >> 8;
1575
+ target[position$1++] = tag & 0xff;
1576
+ } else if (tag > -1) {
1577
+ target[position$1++] = 0xda;
1578
+ targetView.setUint32(position$1, tag);
1579
+ position$1 += 4;
1580
+ } // else undefined, don't write tag
1581
+ extension.encode.call(this, value, encode, makeRoom);
1582
+ return
1583
+ }
1584
+ }
1585
+ if (value[Symbol.iterator]) {
1586
+ target[position$1++] = 0x9f; // indefinite length array
1587
+ for (let entry of value) {
1588
+ encode(entry);
1589
+ }
1590
+ target[position$1++] = 0xff; // stop-code
1591
+ return
1592
+ }
1593
+ // no extension found, write as object
1594
+ writeObject(value, !value.hasOwnProperty); // if it doesn't have hasOwnProperty, don't do hasOwnProperty checks
1595
+ }
1596
+ }
1597
+ } else if (type === 'boolean') {
1598
+ target[position$1++] = value ? 0xf5 : 0xf4;
1599
+ } else if (type === 'bigint') {
1600
+ if (value < (BigInt(1)<<BigInt(64)) && value >= 0) {
1601
+ // use an unsigned int as long as it fits
1602
+ target[position$1++] = 0x1b;
1603
+ targetView.setBigUint64(position$1, value);
1604
+ } else if (value > -(BigInt(1)<<BigInt(64)) && value < 0) {
1605
+ // if we can fit an unsigned int, use that
1606
+ target[position$1++] = 0x3b;
1607
+ targetView.setBigUint64(position$1, -value - BigInt(1));
1608
+ } else {
1609
+ // overflow
1610
+ if (this.largeBigIntToFloat) {
1611
+ target[position$1++] = 0xfb;
1612
+ targetView.setFloat64(position$1, Number(value));
1613
+ } else {
1614
+ throw new RangeError(value + ' was too large to fit in CBOR 64-bit integer format, set largeBigIntToFloat to convert to float-64')
1615
+ }
1616
+ }
1617
+ position$1 += 8;
1618
+ } else if (type === 'undefined') {
1619
+ target[position$1++] = 0xf7;
1620
+ } else {
1621
+ throw new Error('Unknown type: ' + type)
1622
+ }
1623
+ };
1624
+
1625
+ const writeObject = this.useRecords === false ? this.variableMapSize ? (object) => {
1626
+ // this method is slightly slower, but generates "preferred serialization" (optimally small for smaller objects)
1627
+ let keys = Object.keys(object);
1628
+ let vals = Object.values(object);
1629
+ let length = keys.length;
1630
+ if (length < 0x18) {
1631
+ target[position$1++] = 0xa0 | length;
1632
+ } else if (length < 0x100) {
1633
+ target[position$1++] = 0xb8;
1634
+ target[position$1++] = length;
1635
+ } else if (length < 0x10000) {
1636
+ target[position$1++] = 0xb9;
1637
+ target[position$1++] = length >> 8;
1638
+ target[position$1++] = length & 0xff;
1639
+ } else {
1640
+ target[position$1++] = 0xba;
1641
+ targetView.setUint32(position$1, length);
1642
+ position$1 += 4;
1643
+ }
1644
+ if (encoder.keyMap) {
1645
+ for (let i = 0; i < length; i++) {
1646
+ encode(encodeKey(keys[i]));
1647
+ encode(vals[i]);
1648
+ }
1649
+ } else {
1650
+ for (let i = 0; i < length; i++) {
1651
+ encode(keys[i]);
1652
+ encode(vals[i]);
1653
+ }
1654
+ }
1655
+ } :
1656
+ (object, safePrototype) => {
1657
+ target[position$1++] = 0xb9; // always use map 16, so we can preallocate and set the length afterwards
1658
+ let objectOffset = position$1 - start;
1659
+ position$1 += 2;
1660
+ let size = 0;
1661
+ if (encoder.keyMap) {
1662
+ for (let key in object) if (safePrototype || object.hasOwnProperty(key)) {
1663
+ encode(encoder.encodeKey(key));
1664
+ encode(object[key]);
1665
+ size++;
1666
+ }
1667
+ } else {
1668
+ for (let key in object) if (safePrototype || object.hasOwnProperty(key)) {
1669
+ encode(key);
1670
+ encode(object[key]);
1671
+ size++;
1672
+ }
1673
+ }
1674
+ target[objectOffset++ + start] = size >> 8;
1675
+ target[objectOffset + start] = size & 0xff;
1676
+ } :
1677
+ (object, safePrototype) => {
1678
+ let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
1679
+ let newTransitions = 0;
1680
+ let length = 0;
1681
+ let parentRecordId;
1682
+ let keys;
1683
+ if (this.keyMap) {
1684
+ keys = Object.keys(object).map(k => this.encodeKey(k));
1685
+ length = keys.length;
1686
+ for (let i = 0; i < length; i++) {
1687
+ let key = keys[i];
1688
+ nextTransition = transition[key];
1689
+ if (!nextTransition) {
1690
+ nextTransition = transition[key] = Object.create(null);
1691
+ newTransitions++;
1692
+ }
1693
+ transition = nextTransition;
1694
+ }
1695
+ } else {
1696
+ for (let key in object) if (safePrototype || object.hasOwnProperty(key)) {
1697
+ nextTransition = transition[key];
1698
+ if (!nextTransition) {
1699
+ if (transition[RECORD_SYMBOL] & 0x100000) {// this indicates it is a brancheable/extendable terminal node, so we will use this record id and extend it
1700
+ parentRecordId = transition[RECORD_SYMBOL] & 0xffff;
1701
+ }
1702
+ nextTransition = transition[key] = Object.create(null);
1703
+ newTransitions++;
1704
+ }
1705
+ transition = nextTransition;
1706
+ length++;
1707
+ }
1708
+ }
1709
+ let recordId = transition[RECORD_SYMBOL];
1710
+ if (recordId !== undefined) {
1711
+ recordId &= 0xffff;
1712
+ target[position$1++] = 0xd9;
1713
+ target[position$1++] = (recordId >> 8) | 0xe0;
1714
+ target[position$1++] = recordId & 0xff;
1715
+ } else {
1716
+ if (!keys)
1717
+ keys = transition.__keys__ || (transition.__keys__ = Object.keys(object));
1718
+ if (parentRecordId === undefined) {
1719
+ recordId = structures.nextId++;
1720
+ if (!recordId) {
1721
+ recordId = 0;
1722
+ structures.nextId = 1;
1723
+ }
1724
+ if (recordId >= MAX_STRUCTURES) {// cycle back around
1725
+ structures.nextId = (recordId = maxSharedStructures) + 1;
1726
+ }
1727
+ } else {
1728
+ recordId = parentRecordId;
1729
+ }
1730
+ structures[recordId] = keys;
1731
+ if (recordId < maxSharedStructures) {
1732
+ target[position$1++] = 0xd9;
1733
+ target[position$1++] = (recordId >> 8) | 0xe0;
1734
+ target[position$1++] = recordId & 0xff;
1735
+ transition = structures.transitions;
1736
+ for (let i = 0; i < length; i++) {
1737
+ if (transition[RECORD_SYMBOL] === undefined || (transition[RECORD_SYMBOL] & 0x100000))
1738
+ transition[RECORD_SYMBOL] = recordId;
1739
+ transition = transition[keys[i]];
1740
+ }
1741
+ transition[RECORD_SYMBOL] = recordId | 0x100000; // indicates it is a extendable terminal
1742
+ hasSharedUpdate = true;
1743
+ } else {
1744
+ transition[RECORD_SYMBOL] = recordId;
1745
+ targetView.setUint32(position$1, 0xd9dfff00); // tag two byte, then record definition id
1746
+ position$1 += 3;
1747
+ if (newTransitions)
1748
+ transitionsCount += serializationsSinceTransitionRebuild * newTransitions;
1749
+ // record the removal of the id, we can maintain our shared structure
1750
+ if (recordIdsToRemove.length >= MAX_STRUCTURES - maxSharedStructures)
1751
+ recordIdsToRemove.shift()[RECORD_SYMBOL] = undefined; // we are cycling back through, and have to remove old ones
1752
+ recordIdsToRemove.push(transition);
1753
+ writeArrayHeader(length + 2);
1754
+ encode(0xe000 + recordId);
1755
+ encode(keys);
1756
+ for (let v of Object.values(object)) encode(v);
1757
+ return
1758
+ }
1759
+ }
1760
+ if (length < 0x18) { // write the array header
1761
+ target[position$1++] = 0x80 | length;
1762
+ } else {
1763
+ writeArrayHeader(length);
1764
+ }
1765
+ for (let key in object)
1766
+ if (safePrototype || object.hasOwnProperty(key))
1767
+ encode(object[key]);
1768
+ };
1769
+ const makeRoom = (end) => {
1770
+ let newSize;
1771
+ if (end > 0x1000000) {
1772
+ // special handling for really large buffers
1773
+ if ((end - start) > MAX_BUFFER_SIZE)
1774
+ throw new Error('Encoded buffer would be larger than maximum buffer size')
1775
+ newSize = Math.min(MAX_BUFFER_SIZE,
1776
+ Math.round(Math.max((end - start) * (end > 0x4000000 ? 1.25 : 2), 0x400000) / 0x1000) * 0x1000);
1777
+ } else // faster handling for smaller buffers
1778
+ newSize = ((Math.max((end - start) << 2, target.length - 1) >> 12) + 1) << 12;
1779
+ let newBuffer = new ByteArrayAllocate(newSize);
1780
+ targetView = new DataView(newBuffer.buffer, 0, newSize);
1781
+ if (target.copy)
1782
+ target.copy(newBuffer, 0, start, end);
1783
+ else
1784
+ newBuffer.set(target.slice(start, end));
1785
+ position$1 -= start;
1786
+ start = 0;
1787
+ safeEnd = newBuffer.length - 10;
1788
+ return target = newBuffer
1789
+ };
1790
+ }
1791
+ useBuffer(buffer) {
1792
+ // this means we are finished using our own buffer and we can write over it safely
1793
+ target = buffer;
1794
+ targetView = new DataView(target.buffer, target.byteOffset, target.byteLength);
1795
+ position$1 = 0;
1796
+ }
1797
+ clearSharedData() {
1798
+ if (this.structures)
1799
+ this.structures = [];
1800
+ if (this.sharedValues)
1801
+ this.sharedValues = undefined;
1802
+ }
1803
+ updateSharedData() {
1804
+ let lastVersion = this.sharedVersion || 0;
1805
+ this.sharedVersion = lastVersion + 1;
1806
+ let structuresCopy = this.structures.slice(0);
1807
+ let sharedData = new SharedData(structuresCopy, this.sharedValues, this.sharedVersion);
1808
+ let saveResults = this.saveShared(sharedData,
1809
+ existingShared => (existingShared && existingShared.version || 0) == lastVersion);
1810
+ if (saveResults === false) {
1811
+ // get updated structures and try again if the update failed
1812
+ sharedData = this.getShared() || {};
1813
+ this.structures = sharedData.structures || [];
1814
+ this.sharedValues = sharedData.packedValues;
1815
+ this.sharedVersion = sharedData.version;
1816
+ this.structures.nextId = this.structures.length;
1817
+ } else {
1818
+ // restore structures
1819
+ structuresCopy.forEach((structure, i) => this.structures[i] = structure);
1820
+ }
1821
+ // saveShared may fail to write and reload, or may have reloaded to check compatibility and overwrite saved data, either way load the correct shared data
1822
+ return saveResults
1823
+ }
1824
+ }
1825
+ class SharedData {
1826
+ constructor(structures, values, version) {
1827
+ this.structures = structures;
1828
+ this.packedValues = values;
1829
+ this.version = version;
1830
+ }
1831
+ }
1832
+
1833
+ function writeArrayHeader(length) {
1834
+ if (length < 0x18)
1835
+ target[position$1++] = 0x80 | length;
1836
+ else if (length < 0x100) {
1837
+ target[position$1++] = 0x98;
1838
+ target[position$1++] = length;
1839
+ } else if (length < 0x10000) {
1840
+ target[position$1++] = 0x99;
1841
+ target[position$1++] = length >> 8;
1842
+ target[position$1++] = length & 0xff;
1843
+ } else {
1844
+ target[position$1++] = 0x9a;
1845
+ targetView.setUint32(position$1, length);
1846
+ position$1 += 4;
1847
+ }
1848
+ }
1849
+
1850
+ function findRepetitiveStrings(value, packedValues) {
1851
+ switch(typeof value) {
1852
+ case 'string':
1853
+ if (value.length > 3) {
1854
+ if (packedValues.objectMap[value] > -1 || packedValues.values.length >= packedValues.maxValues)
1855
+ return
1856
+ let packedStatus = packedValues.get(value);
1857
+ if (packedStatus) {
1858
+ if (++packedStatus.count == 2) {
1859
+ packedValues.values.push(value);
1860
+ }
1861
+ } else {
1862
+ packedValues.set(value, {
1863
+ count: 1,
1864
+ });
1865
+ if (packedValues.samplingPackedValues) {
1866
+ let status = packedValues.samplingPackedValues.get(value);
1867
+ if (status)
1868
+ status.count++;
1869
+ else
1870
+ packedValues.samplingPackedValues.set(value, {
1871
+ count: 1,
1872
+ });
1873
+ }
1874
+ }
1875
+ }
1876
+ break
1877
+ case 'object':
1878
+ if (value) {
1879
+ if (value instanceof Array) {
1880
+ for (let i = 0, l = value.length; i < l; i++) {
1881
+ findRepetitiveStrings(value[i], packedValues);
1882
+ }
1883
+
1884
+ } else {
1885
+ let includeKeys = !packedValues.encoder.useRecords;
1886
+ for (var key in value) {
1887
+ if (value.hasOwnProperty(key)) {
1888
+ if (includeKeys)
1889
+ findRepetitiveStrings(key, packedValues);
1890
+ findRepetitiveStrings(value[key], packedValues);
1891
+ }
1892
+ }
1893
+ }
1894
+ }
1895
+ break
1896
+ case 'function': console.log(value);
1897
+ }
1898
+ }
1899
+ const isLittleEndianMachine$1 = new Uint8Array(new Uint16Array([1]).buffer)[0] == 1;
1900
+ extensionClasses = [ Date, Set, Error, RegExp, Tag, ArrayBuffer,
1901
+ Uint8Array, Uint8ClampedArray, Uint16Array, Uint32Array,
1902
+ typeof BigUint64Array == 'undefined' ? function() {} : BigUint64Array, Int8Array, Int16Array, Int32Array,
1903
+ typeof BigInt64Array == 'undefined' ? function() {} : BigInt64Array,
1904
+ Float32Array, Float64Array, SharedData ];
1905
+
1906
+ //Object.getPrototypeOf(Uint8Array.prototype).constructor /*TypedArray*/
1907
+ extensions = [{ // Date
1908
+ tag: 1,
1909
+ encode(date, encode) {
1910
+ let seconds = date.getTime() / 1000;
1911
+ if ((this.useTimestamp32 || date.getMilliseconds() === 0) && seconds >= 0 && seconds < 0x100000000) {
1912
+ // Timestamp 32
1913
+ target[position$1++] = 0x1a;
1914
+ targetView.setUint32(position$1, seconds);
1915
+ position$1 += 4;
1916
+ } else {
1917
+ // Timestamp float64
1918
+ target[position$1++] = 0xfb;
1919
+ targetView.setFloat64(position$1, seconds);
1920
+ position$1 += 8;
1921
+ }
1922
+ }
1923
+ }, { // Set
1924
+ tag: 258, // https://github.com/input-output-hk/cbor-sets-spec/blob/master/CBOR_SETS.md
1925
+ encode(set, encode) {
1926
+ let array = Array.from(set);
1927
+ encode(array);
1928
+ }
1929
+ }, { // Error
1930
+ tag: 27, // http://cbor.schmorp.de/generic-object
1931
+ encode(error, encode) {
1932
+ encode([ error.name, error.message ]);
1933
+ }
1934
+ }, { // RegExp
1935
+ tag: 27, // http://cbor.schmorp.de/generic-object
1936
+ encode(regex, encode) {
1937
+ encode([ 'RegExp', regex.source, regex.flags ]);
1938
+ }
1939
+ }, { // Tag
1940
+ getTag(tag) {
1941
+ return tag.tag
1942
+ },
1943
+ encode(tag, encode) {
1944
+ encode(tag.value);
1945
+ }
1946
+ }, { // ArrayBuffer
1947
+ encode(arrayBuffer, encode, makeRoom) {
1948
+ writeBuffer(arrayBuffer, makeRoom);
1949
+ }
1950
+ }, { // Uint8Array
1951
+ getTag(typedArray) {
1952
+ if (typedArray.constructor === Uint8Array) {
1953
+ if (this.tagUint8Array || hasNodeBuffer && this.tagUint8Array !== false)
1954
+ return 64;
1955
+ } // else no tag
1956
+ },
1957
+ encode(typedArray, encode, makeRoom) {
1958
+ writeBuffer(typedArray, makeRoom);
1959
+ }
1960
+ },
1961
+ typedArrayEncoder(68, 1),
1962
+ typedArrayEncoder(69, 2),
1963
+ typedArrayEncoder(70, 4),
1964
+ typedArrayEncoder(71, 8),
1965
+ typedArrayEncoder(72, 1),
1966
+ typedArrayEncoder(77, 2),
1967
+ typedArrayEncoder(78, 4),
1968
+ typedArrayEncoder(79, 8),
1969
+ typedArrayEncoder(85, 4),
1970
+ typedArrayEncoder(86, 8),
1971
+ {
1972
+ encode(sharedData, encode) { // write SharedData
1973
+ let packedValues = sharedData.packedValues || [];
1974
+ let sharedStructures = sharedData.structures || [];
1975
+ if (packedValues.values.length > 0) {
1976
+ target[position$1++] = 0xd8; // one-byte tag
1977
+ target[position$1++] = 51; // tag 51 for packed shared structures https://www.potaroo.net/ietf/ids/draft-ietf-cbor-packed-03.txt
1978
+ writeArrayHeader(4);
1979
+ let valuesArray = packedValues.values;
1980
+ encode(valuesArray);
1981
+ writeArrayHeader(0); // prefixes
1982
+ writeArrayHeader(0); // suffixes
1983
+ packedObjectMap = Object.create(sharedPackedObjectMap || null);
1984
+ for (let i = 0, l = valuesArray.length; i < l; i++) {
1985
+ packedObjectMap[valuesArray[i]] = i;
1986
+ }
1987
+ }
1988
+ if (sharedStructures) {
1989
+ targetView.setUint32(position$1, 0xd9dffe00);
1990
+ position$1 += 3;
1991
+ let definitions = sharedStructures.slice(0);
1992
+ definitions.unshift(0xe000);
1993
+ definitions.push(new Tag(sharedData.version, 0x53687264));
1994
+ encode(definitions);
1995
+ } else
1996
+ encode(new Tag(sharedData.version, 0x53687264));
1997
+ }
1998
+ }];
1999
+ function typedArrayEncoder(tag, size) {
2000
+ if (!isLittleEndianMachine$1 && size > 1)
2001
+ tag -= 4; // the big endian equivalents are 4 less
2002
+ return {
2003
+ tag: tag,
2004
+ encode: function writeExtBuffer(typedArray, encode) {
2005
+ let length = typedArray.byteLength;
2006
+ let offset = typedArray.byteOffset || 0;
2007
+ let buffer = typedArray.buffer || typedArray;
2008
+ encode(hasNodeBuffer ? Buffer.from(buffer, offset, length) :
2009
+ new Uint8Array(buffer, offset, length));
2010
+ }
2011
+ }
2012
+ }
2013
+ function writeBuffer(buffer, makeRoom) {
2014
+ let length = buffer.byteLength;
2015
+ if (length < 0x18) {
2016
+ target[position$1++] = 0x40 + length;
2017
+ } else if (length < 0x100) {
2018
+ target[position$1++] = 0x58;
2019
+ target[position$1++] = length;
2020
+ } else if (length < 0x10000) {
2021
+ target[position$1++] = 0x59;
2022
+ target[position$1++] = length >> 8;
2023
+ target[position$1++] = length & 0xff;
2024
+ } else {
2025
+ target[position$1++] = 0x5a;
2026
+ targetView.setUint32(position$1, length);
2027
+ position$1 += 4;
2028
+ }
2029
+ if (position$1 + length >= target.length) {
2030
+ makeRoom(position$1 + length);
2031
+ }
2032
+ // if it is already a typed array (has an ArrayBuffer), use that, but if it is an ArrayBuffer itself,
2033
+ // must wrap it to set it.
2034
+ target.set(buffer.buffer ? buffer : new Uint8Array(buffer), position$1);
2035
+ position$1 += length;
2036
+ }
2037
+
2038
+ function insertIds(serialized, idsToInsert) {
2039
+ // insert the ids that need to be referenced for structured clones
2040
+ let nextId;
2041
+ let distanceToMove = idsToInsert.length * 2;
2042
+ let lastEnd = serialized.length - distanceToMove;
2043
+ idsToInsert.sort((a, b) => a.offset > b.offset ? 1 : -1);
2044
+ for (let id = 0; id < idsToInsert.length; id++) {
2045
+ let referee = idsToInsert[id];
2046
+ referee.id = id;
2047
+ for (let position of referee.references) {
2048
+ serialized[position++] = id >> 8;
2049
+ serialized[position] = id & 0xff;
2050
+ }
2051
+ }
2052
+ while (nextId = idsToInsert.pop()) {
2053
+ let offset = nextId.offset;
2054
+ serialized.copyWithin(offset + distanceToMove, offset, lastEnd);
2055
+ distanceToMove -= 2;
2056
+ let position = offset + distanceToMove;
2057
+ serialized[position++] = 0xd8;
2058
+ serialized[position++] = 28; // http://cbor.schmorp.de/value-sharing
2059
+ lastEnd = offset;
2060
+ }
2061
+ return serialized
2062
+ }
2063
+ function writeBundles(start, encode) {
2064
+ targetView.setUint32(bundledStrings$1.position + start, position$1 - bundledStrings$1.position - start + 1); // the offset to bundle
2065
+ let writeStrings = bundledStrings$1;
2066
+ bundledStrings$1 = null;
2067
+ encode(writeStrings[0]);
2068
+ encode(writeStrings[1]);
2069
+ }
2070
+
2071
+ function addExtension$1(extension) {
2072
+ if (extension.Class) {
2073
+ if (!extension.encode)
2074
+ throw new Error('Extension has no encode function')
2075
+ extensionClasses.unshift(extension.Class);
2076
+ extensions.unshift(extension);
2077
+ }
2078
+ addExtension(extension);
2079
+ }
2080
+ let defaultEncoder = new Encoder({ useRecords: false });
2081
+ const encode = defaultEncoder.encode;
2082
+ const { NEVER, ALWAYS, DECIMAL_ROUND, DECIMAL_FIT } = FLOAT32_OPTIONS;
2083
+ const REUSE_BUFFER_MODE = 512;
2067
2084
  const RESET_BUFFER_MODE = 1024;
2068
2085
 
2069
- /**
2070
- * Given an Iterable first argument, returns an Iterable where each value is encoded as a Buffer
2071
- * If the argument is only Async Iterable, the return value will be an Async Iterable.
2072
- * @param {Iterable|Iterator|AsyncIterable|AsyncIterator} objectIterator - iterable source, like a Readable object stream, an array, Set, or custom object
2073
- * @param {options} [options] - cbor-x Encoder options
2074
- * @returns {IterableIterator|Promise.<AsyncIterableIterator>}
2075
- */
2076
- function encodeIter (objectIterator, options = {}) {
2077
- if (!objectIterator || typeof objectIterator !== 'object') {
2078
- throw new Error('first argument must be an Iterable, Async Iterable, or a Promise for an Async Iterable')
2079
- } else if (typeof objectIterator[Symbol.iterator] === 'function') {
2080
- return encodeIterSync(objectIterator, options)
2081
- } else if (typeof objectIterator.then === 'function' || typeof objectIterator[Symbol.asyncIterator] === 'function') {
2082
- return encodeIterAsync(objectIterator, options)
2083
- } else {
2084
- throw new Error('first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a Promise')
2085
- }
2086
- }
2087
-
2088
- function * encodeIterSync (objectIterator, options) {
2089
- const encoder = new Encoder(options);
2090
- for (const value of objectIterator) {
2091
- yield encoder.encode(value);
2092
- }
2093
- }
2094
-
2095
- async function * encodeIterAsync (objectIterator, options) {
2096
- const encoder = new Encoder(options);
2097
- for await (const value of objectIterator) {
2098
- yield encoder.encode(value);
2099
- }
2100
- }
2101
-
2102
- /**
2103
- * Given an Iterable/Iterator input which yields buffers, returns an IterableIterator which yields sync decoded objects
2104
- * Or, given an Async Iterable/Iterator which yields promises resolving in buffers, returns an AsyncIterableIterator.
2105
- * @param {Iterable|Iterator|AsyncIterable|AsyncIterableIterator} bufferIterator
2106
- * @param {object} [options] - Decoder options
2107
- * @returns {IterableIterator|Promise.<AsyncIterableIterator}
2108
- */
2109
- function decodeIter (bufferIterator, options = {}) {
2110
- if (!bufferIterator || typeof bufferIterator !== 'object') {
2111
- throw new Error('first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a promise')
2112
- }
2113
-
2114
- const decoder = new Decoder(options);
2115
- let incomplete;
2116
- const parser = (chunk) => {
2117
- let yields;
2118
- // if there's incomplete data from previous chunk, concatinate and try again
2119
- if (incomplete) {
2120
- chunk = Buffer.concat([incomplete, chunk]);
2121
- incomplete = undefined;
2122
- }
2123
-
2124
- try {
2125
- yields = decoder.decodeMultiple(chunk);
2126
- } catch (err) {
2127
- if (err.incomplete) {
2128
- incomplete = chunk.slice(err.lastPosition);
2129
- yields = err.values;
2130
- } else {
2131
- throw err
2132
- }
2133
- }
2134
- return yields
2135
- };
2136
-
2137
- if (typeof bufferIterator[Symbol.iterator] === 'function') {
2138
- return (function * iter () {
2139
- for (const value of bufferIterator) {
2140
- yield * parser(value);
2141
- }
2142
- })()
2143
- } else if (typeof bufferIterator[Symbol.asyncIterator] === 'function') {
2144
- return (async function * iter () {
2145
- for await (const value of bufferIterator) {
2146
- yield * parser(value);
2147
- }
2148
- })()
2149
- }
2086
+ /**
2087
+ * Given an Iterable first argument, returns an Iterable where each value is encoded as a Buffer
2088
+ * If the argument is only Async Iterable, the return value will be an Async Iterable.
2089
+ * @param {Iterable|Iterator|AsyncIterable|AsyncIterator} objectIterator - iterable source, like a Readable object stream, an array, Set, or custom object
2090
+ * @param {options} [options] - cbor-x Encoder options
2091
+ * @returns {IterableIterator|Promise.<AsyncIterableIterator>}
2092
+ */
2093
+ function encodeIter (objectIterator, options = {}) {
2094
+ if (!objectIterator || typeof objectIterator !== 'object') {
2095
+ throw new Error('first argument must be an Iterable, Async Iterable, or a Promise for an Async Iterable')
2096
+ } else if (typeof objectIterator[Symbol.iterator] === 'function') {
2097
+ return encodeIterSync(objectIterator, options)
2098
+ } else if (typeof objectIterator.then === 'function' || typeof objectIterator[Symbol.asyncIterator] === 'function') {
2099
+ return encodeIterAsync(objectIterator, options)
2100
+ } else {
2101
+ throw new Error('first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a Promise')
2102
+ }
2103
+ }
2104
+
2105
+ function * encodeIterSync (objectIterator, options) {
2106
+ const encoder = new Encoder(options);
2107
+ for (const value of objectIterator) {
2108
+ yield encoder.encode(value);
2109
+ }
2110
+ }
2111
+
2112
+ async function * encodeIterAsync (objectIterator, options) {
2113
+ const encoder = new Encoder(options);
2114
+ for await (const value of objectIterator) {
2115
+ yield encoder.encode(value);
2116
+ }
2117
+ }
2118
+
2119
+ /**
2120
+ * Given an Iterable/Iterator input which yields buffers, returns an IterableIterator which yields sync decoded objects
2121
+ * Or, given an Async Iterable/Iterator which yields promises resolving in buffers, returns an AsyncIterableIterator.
2122
+ * @param {Iterable|Iterator|AsyncIterable|AsyncIterableIterator} bufferIterator
2123
+ * @param {object} [options] - Decoder options
2124
+ * @returns {IterableIterator|Promise.<AsyncIterableIterator}
2125
+ */
2126
+ function decodeIter (bufferIterator, options = {}) {
2127
+ if (!bufferIterator || typeof bufferIterator !== 'object') {
2128
+ throw new Error('first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a promise')
2129
+ }
2130
+
2131
+ const decoder = new Decoder(options);
2132
+ let incomplete;
2133
+ const parser = (chunk) => {
2134
+ let yields;
2135
+ // if there's incomplete data from previous chunk, concatinate and try again
2136
+ if (incomplete) {
2137
+ chunk = Buffer.concat([incomplete, chunk]);
2138
+ incomplete = undefined;
2139
+ }
2140
+
2141
+ try {
2142
+ yields = decoder.decodeMultiple(chunk);
2143
+ } catch (err) {
2144
+ if (err.incomplete) {
2145
+ incomplete = chunk.slice(err.lastPosition);
2146
+ yields = err.values;
2147
+ } else {
2148
+ throw err
2149
+ }
2150
+ }
2151
+ return yields
2152
+ };
2153
+
2154
+ if (typeof bufferIterator[Symbol.iterator] === 'function') {
2155
+ return (function * iter () {
2156
+ for (const value of bufferIterator) {
2157
+ yield * parser(value);
2158
+ }
2159
+ })()
2160
+ } else if (typeof bufferIterator[Symbol.asyncIterator] === 'function') {
2161
+ return (async function * iter () {
2162
+ for await (const value of bufferIterator) {
2163
+ yield * parser(value);
2164
+ }
2165
+ })()
2166
+ }
2150
2167
  }
2151
2168
 
2152
2169
  exports.ALWAYS = ALWAYS;