cbor-x 1.3.2 → 1.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/node.cjs CHANGED
@@ -5,1084 +5,1091 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var stream = require('stream');
6
6
  var module$1 = require('module');
7
7
 
8
- let decoder;
9
- try {
10
- decoder = new TextDecoder();
11
- } catch(error) {}
12
- let src;
13
- let srcEnd;
14
- let position = 0;
15
- const EMPTY_ARRAY = [];
16
- const LEGACY_RECORD_INLINE_ID = 105;
17
- const RECORD_DEFINITIONS_ID = 0xdffe;
18
- const RECORD_INLINE_ID = 0xdfff; // temporary first-come first-serve tag // proposed tag: 0x7265 // 're'
19
- const BUNDLED_STRINGS_ID = 0xdff9;
20
- const PACKED_REFERENCE_TAG_ID = 6;
21
- const STOP_CODE = {};
22
- let strings = EMPTY_ARRAY;
23
- let stringPosition = 0;
24
- let currentDecoder = {};
25
- let currentStructures;
26
- let srcString;
27
- let srcStringStart = 0;
28
- let srcStringEnd = 0;
29
- let bundledStrings;
30
- let referenceMap;
31
- let currentExtensions = [];
32
- let currentExtensionRanges = [];
33
- let packedValues;
34
- let dataView;
35
- let restoreMapsAsObject;
36
- let defaultOptions = {
37
- useRecords: false,
38
- mapsAsObjects: true
39
- };
40
- let sequentialMode = false;
41
-
42
- class Decoder {
43
- constructor(options) {
44
- if (options) {
45
- if ((options.keyMap || options._keyMap) && !options.useRecords) {
46
- options.useRecords = false;
47
- options.mapsAsObjects = true;
48
- }
49
- if (options.useRecords === false && options.mapsAsObjects === undefined)
50
- options.mapsAsObjects = true;
51
- if (options.getStructures)
52
- options.getShared = options.getStructures;
53
- if (options.getShared && !options.structures)
54
- (options.structures = []).uninitialized = true; // this is what we use to denote an uninitialized structures
55
- if (options.keyMap) {
56
- this.mapKey = new Map();
57
- for (let [k,v] of Object.entries(options.keyMap)) this.mapKey.set(v,k);
58
- }
59
- }
60
- Object.assign(this, options);
61
- }
62
- /*
63
- decodeKey(key) {
64
- return this.keyMap
65
- ? Object.keys(this.keyMap)[Object.values(this.keyMap).indexOf(key)] || key
66
- : key
67
- }
68
- */
69
- decodeKey(key) {
70
- return this.keyMap ? this.mapKey.get(key) || key : key
71
- }
72
-
73
- encodeKey(key) {
74
- return this.keyMap && this.keyMap.hasOwnProperty(key) ? this.keyMap[key] : key
75
- }
76
-
77
- encodeKeys(rec) {
78
- if (!this._keyMap) return rec
79
- let map = new Map();
80
- for (let [k,v] of Object.entries(rec)) map.set((this._keyMap.hasOwnProperty(k) ? this._keyMap[k] : k), v);
81
- return map
82
- }
83
-
84
- decodeKeys(map) {
85
- if (!this._keyMap || map.constructor.name != 'Map') return map
86
- if (!this._mapKey) {
87
- this._mapKey = new Map();
88
- for (let [k,v] of Object.entries(this._keyMap)) this._mapKey.set(v,k);
89
- }
90
- let res = {};
91
- //map.forEach((v,k) => res[Object.keys(this._keyMap)[Object.values(this._keyMap).indexOf(k)] || k] = v)
92
- map.forEach((v,k) => res[this._mapKey.has(k) ? this._mapKey.get(k) : k] = v);
93
- return res
94
- }
95
-
96
- mapDecode(source, end) {
97
-
98
- let res = this.decode(source);
99
- if (this._keyMap) {
100
- //Experiemntal support for Optimised KeyMap decoding
101
- switch (res.constructor.name) {
102
- case 'Array': return res.map(r => this.decodeKeys(r))
103
- //case 'Map': return this.decodeKeys(res)
104
- }
105
- }
106
- return res
107
- }
108
-
109
- decode(source, end) {
110
- if (src) {
111
- // re-entrant execution, save the state and restore it after we do this decode
112
- return saveState(() => {
113
- clearSource();
114
- return this ? this.decode(source, end) : Decoder.prototype.decode.call(defaultOptions, source, end)
115
- })
116
- }
117
- srcEnd = end > -1 ? end : source.length;
118
- position = 0;
119
- stringPosition = 0;
120
- srcStringEnd = 0;
121
- srcString = null;
122
- strings = EMPTY_ARRAY;
123
- bundledStrings = null;
124
- src = source;
125
- // this provides cached access to the data view for a buffer if it is getting reused, which is a recommend
126
- // technique for getting data from a database where it can be copied into an existing buffer instead of creating
127
- // new ones
128
- try {
129
- dataView = source.dataView || (source.dataView = new DataView(source.buffer, source.byteOffset, source.byteLength));
130
- } catch(error) {
131
- // if it doesn't have a buffer, maybe it is the wrong type of object
132
- src = null;
133
- if (source instanceof Uint8Array)
134
- throw error
135
- throw new Error('Source must be a Uint8Array or Buffer but was a ' + ((source && typeof source == 'object') ? source.constructor.name : typeof source))
136
- }
137
- if (this instanceof Decoder) {
138
- currentDecoder = this;
139
- packedValues = this.sharedValues &&
140
- (this.pack ? new Array(this.maxPrivatePackedValues || 16).concat(this.sharedValues) :
141
- this.sharedValues);
142
- if (this.structures) {
143
- currentStructures = this.structures;
144
- return checkedRead()
145
- } else if (!currentStructures || currentStructures.length > 0) {
146
- currentStructures = [];
147
- }
148
- } else {
149
- currentDecoder = defaultOptions;
150
- if (!currentStructures || currentStructures.length > 0)
151
- currentStructures = [];
152
- packedValues = null;
153
- }
154
- return checkedRead()
155
- }
156
- decodeMultiple(source, forEach) {
157
- let values, lastPosition = 0;
158
- try {
159
- let size = source.length;
160
- sequentialMode = true;
161
- let value = this ? this.decode(source, size) : defaultDecoder.decode(source, size);
162
- if (forEach) {
163
- if (forEach(value) === false) {
164
- return
165
- }
166
- while(position < size) {
167
- lastPosition = position;
168
- if (forEach(checkedRead()) === false) {
169
- return
170
- }
171
- }
172
- }
173
- else {
174
- values = [ value ];
175
- while(position < size) {
176
- lastPosition = position;
177
- values.push(checkedRead());
178
- }
179
- return values
180
- }
181
- } catch(error) {
182
- error.lastPosition = lastPosition;
183
- error.values = values;
184
- throw error
185
- } finally {
186
- sequentialMode = false;
187
- clearSource();
188
- }
189
- }
190
- }
191
- function checkedRead() {
192
- try {
193
- let result = read();
194
- if (bundledStrings) // bundled strings to skip past
195
- position = bundledStrings.postBundlePosition;
196
-
197
- if (position == srcEnd) {
198
- // finished reading this source, cleanup references
199
- currentStructures = null;
200
- src = null;
201
- if (referenceMap)
202
- referenceMap = null;
203
- } else if (position > srcEnd) {
204
- // over read
205
- let error = new Error('Unexpected end of CBOR data');
206
- error.incomplete = true;
207
- throw error
208
- } else if (!sequentialMode) {
209
- throw new Error('Data read, but end of buffer not reached')
210
- }
211
- // else more to read, but we are reading sequentially, so don't clear source yet
212
- return result
213
- } catch(error) {
214
- clearSource();
215
- if (error instanceof RangeError || error.message.startsWith('Unexpected end of buffer')) {
216
- error.incomplete = true;
217
- }
218
- throw error
219
- }
220
- }
221
-
222
- function read() {
223
- let token = src[position++];
224
- let majorType = token >> 5;
225
- token = token & 0x1f;
226
- if (token > 0x17) {
227
- switch (token) {
228
- case 0x18:
229
- token = src[position++];
230
- break
231
- case 0x19:
232
- if (majorType == 7) {
233
- return getFloat16()
234
- }
235
- token = dataView.getUint16(position);
236
- position += 2;
237
- break
238
- case 0x1a:
239
- if (majorType == 7) {
240
- let value = dataView.getFloat32(position);
241
- if (currentDecoder.useFloat32 > 2) {
242
- // this does rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
243
- let multiplier = mult10[((src[position] & 0x7f) << 1) | (src[position + 1] >> 7)];
244
- position += 4;
245
- return ((multiplier * value + (value > 0 ? 0.5 : -0.5)) >> 0) / multiplier
246
- }
247
- position += 4;
248
- return value
249
- }
250
- token = dataView.getUint32(position);
251
- position += 4;
252
- break
253
- case 0x1b:
254
- if (majorType == 7) {
255
- let value = dataView.getFloat64(position);
256
- position += 8;
257
- return value
258
- }
259
- if (majorType > 1) {
260
- if (dataView.getUint32(position) > 0)
261
- throw new Error('JavaScript does not support arrays, maps, or strings with length over 4294967295')
262
- token = dataView.getUint32(position + 4);
263
- } else if (currentDecoder.int64AsNumber) {
264
- token = dataView.getUint32(position) * 0x100000000;
265
- token += dataView.getUint32(position + 4);
266
- } else
267
- token = dataView.getBigUint64(position);
268
- position += 8;
269
- break
270
- case 0x1f:
271
- // indefinite length
272
- switch(majorType) {
273
- case 2: // byte string
274
- case 3: // text string
275
- throw new Error('Indefinite length not supported for byte or text strings')
276
- case 4: // array
277
- let array = [];
278
- let value, i = 0;
279
- while ((value = read()) != STOP_CODE) {
280
- array[i++] = value;
281
- }
282
- return majorType == 4 ? array : majorType == 3 ? array.join('') : Buffer.concat(array)
283
- case 5: // map
284
- let key;
285
- if (currentDecoder.mapsAsObjects) {
286
- let object = {};
287
- if (currentDecoder.keyMap) while((key = read()) != STOP_CODE) object[currentDecoder.decodeKey(key)] = read();
288
- else while ((key = read()) != STOP_CODE) object[key] = read();
289
- return object
290
- } else {
291
- if (restoreMapsAsObject) {
292
- currentDecoder.mapsAsObjects = true;
293
- restoreMapsAsObject = false;
294
- }
295
- let map = new Map();
296
- if (currentDecoder.keyMap) while((key = read()) != STOP_CODE) map.set(currentDecoder.decodeKey(key), read());
297
- else while ((key = read()) != STOP_CODE) map.set(key, read());
298
- return map
299
- }
300
- case 7:
301
- return STOP_CODE
302
- default:
303
- throw new Error('Invalid major type for indefinite length ' + majorType)
304
- }
305
- default:
306
- throw new Error('Unknown token ' + token)
307
- }
308
- }
309
- switch (majorType) {
310
- case 0: // positive int
311
- return token
312
- case 1: // negative int
313
- return ~token
314
- case 2: // buffer
315
- return readBin(token)
316
- case 3: // string
317
- if (srcStringEnd >= position) {
318
- return srcString.slice(position - srcStringStart, (position += token) - srcStringStart)
319
- }
320
- if (srcStringEnd == 0 && srcEnd < 140 && token < 32) {
321
- // for small blocks, avoiding the overhead of the extract call is helpful
322
- let string = token < 16 ? shortStringInJS(token) : longStringInJS(token);
323
- if (string != null)
324
- return string
325
- }
326
- return readFixedString(token)
327
- case 4: // array
328
- let array = new Array(token);
329
- //if (currentDecoder.keyMap) for (let i = 0; i < token; i++) array[i] = currentDecoder.decodeKey(read())
330
- //else
331
- for (let i = 0; i < token; i++) array[i] = read();
332
- return array
333
- case 5: // map
334
- if (currentDecoder.mapsAsObjects) {
335
- let object = {};
336
- if (currentDecoder.keyMap) for (let i = 0; i < token; i++) object[currentDecoder.decodeKey(read())] = read();
337
- else for (let i = 0; i < token; i++) object[read()] = read();
338
- return object
339
- } else {
340
- if (restoreMapsAsObject) {
341
- currentDecoder.mapsAsObjects = true;
342
- restoreMapsAsObject = false;
343
- }
344
- let map = new Map();
345
- if (currentDecoder.keyMap) for (let i = 0; i < token; i++) map.set(currentDecoder.decodeKey(read()),read());
346
- else for (let i = 0; i < token; i++) map.set(read(), read());
347
- return map
348
- }
349
- case 6: // extension
350
- if (token >= BUNDLED_STRINGS_ID) {
351
- let structure = currentStructures[token & 0x1fff]; // check record structures first
352
- // 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))
353
- if (structure) {
354
- if (!structure.read) structure.read = createStructureReader(structure);
355
- return structure.read()
356
- }
357
- if (token < 0x10000) {
358
- 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)
359
- return recordDefinition(read())
360
- else if (token == RECORD_DEFINITIONS_ID) {
361
- let length = readJustLength();
362
- let id = read();
363
- for (let i = 2; i < length; i++) {
364
- recordDefinition([id++, read()]);
365
- }
366
- return read()
367
- } else if (token == BUNDLED_STRINGS_ID) {
368
- return readBundleExt()
369
- }
370
- if (currentDecoder.getShared) {
371
- loadShared();
372
- structure = currentStructures[token & 0x1fff];
373
- if (structure) {
374
- if (!structure.read)
375
- structure.read = createStructureReader(structure);
376
- return structure.read()
377
- }
378
- }
379
- }
380
- }
381
- let extension = currentExtensions[token];
382
- if (extension) {
383
- if (extension.handlesRead)
384
- return extension(read)
385
- else
386
- return extension(read())
387
- } else {
388
- let input = read();
389
- for (let i = 0; i < currentExtensionRanges.length; i++) {
390
- let value = currentExtensionRanges[i](token, input);
391
- if (value !== undefined)
392
- return value
393
- }
394
- return new Tag(input, token)
395
- }
396
- case 7: // fixed value
397
- switch (token) {
398
- case 0x14: return false
399
- case 0x15: return true
400
- case 0x16: return null
401
- case 0x17: return; // undefined
402
- case 0x1f:
403
- default:
404
- let packedValue = (packedValues || getPackedValues())[token];
405
- if (packedValue !== undefined)
406
- return packedValue
407
- throw new Error('Unknown token ' + token)
408
- }
409
- default: // negative int
410
- if (isNaN(token)) {
411
- let error = new Error('Unexpected end of CBOR data');
412
- error.incomplete = true;
413
- throw error
414
- }
415
- throw new Error('Unknown CBOR token ' + token)
416
- }
417
- }
418
- const validName = /^[a-zA-Z_$][a-zA-Z\d_$]*$/;
419
- function createStructureReader(structure) {
420
- function readObject() {
421
- // get the array size from the header
422
- let length = src[position++];
423
- //let majorType = token >> 5
424
- length = length & 0x1f;
425
- if (length > 0x17) {
426
- switch (length) {
427
- case 0x18:
428
- length = src[position++];
429
- break
430
- case 0x19:
431
- length = dataView.getUint16(position);
432
- position += 2;
433
- break
434
- case 0x1a:
435
- length = dataView.getUint32(position);
436
- position += 4;
437
- break
438
- default:
439
- throw new Error('Expected array header, but got ' + src[position - 1])
440
- }
441
- }
442
- // This initial function is quick to instantiate, but runs slower. After several iterations pay the cost to build the faster function
443
- let compiledReader = this.compiledReader; // first look to see if we have the fast compiled function
444
- while(compiledReader) {
445
- // we have a fast compiled object literal reader
446
- if (compiledReader.propertyCount === length)
447
- return compiledReader(read) // with the right length, so we use it
448
- compiledReader = compiledReader.next; // see if there is another reader with the right length
449
- }
450
- if (this.slowReads++ >= 3) { // create a fast compiled reader
451
- let array = this.length == length ? this : this.slice(0, length);
452
- compiledReader = currentDecoder.keyMap
453
- ? new Function('r', 'return {' + array.map(k => currentDecoder.decodeKey(k)).map(k => validName.test(k) ? k + ':r()' : ('[' + JSON.stringify(k) + ']:r()')).join(',') + '}')
454
- : new Function('r', 'return {' + array.map(key => validName.test(key) ? key + ':r()' : ('[' + JSON.stringify(key) + ']:r()')).join(',') + '}');
455
- if (this.compiledReader)
456
- 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
457
- compiledReader.propertyCount = length;
458
- this.compiledReader = compiledReader;
459
- return compiledReader(read)
460
- }
461
- let object = {};
462
- if (currentDecoder.keyMap) for (let i = 0; i < length; i++) object[currentDecoder.decodeKey(this[i])] = read();
463
- else for (let i = 0; i < length; i++) object[this[i]] = read();
464
- return object
465
- }
466
- structure.slowReads = 0;
467
- return readObject
468
- }
469
-
470
- let readFixedString = readStringJS;
471
-
472
- exports.isNativeAccelerationEnabled = false;
473
- function setExtractor(extractStrings) {
474
- exports.isNativeAccelerationEnabled = true;
475
- readFixedString = readString();
476
- function readString(headerLength) {
477
- return function readString(length) {
478
- let string = strings[stringPosition++];
479
- if (string == null) {
480
- if (bundledStrings)
481
- return readStringJS(length)
482
- let extraction = extractStrings(position, srcEnd, length, src);
483
- if (typeof extraction == 'string') {
484
- string = extraction;
485
- strings = EMPTY_ARRAY;
486
- } else {
487
- strings = extraction;
488
- stringPosition = 1;
489
- srcStringEnd = 1; // even if a utf-8 string was decoded, must indicate we are in the midst of extracted strings and can't skip strings
490
- string = strings[0];
491
- if (string === undefined)
492
- throw new Error('Unexpected end of buffer')
493
- }
494
- }
495
- let srcStringLength = string.length;
496
- if (srcStringLength <= length) {
497
- position += length;
498
- return string
499
- }
500
- srcString = string;
501
- srcStringStart = position;
502
- srcStringEnd = position + srcStringLength;
503
- position += length;
504
- return string.slice(0, length) // we know we just want the beginning
505
- }
506
- }
507
- }
508
- function readStringJS(length) {
509
- let result;
510
- if (length < 16) {
511
- if (result = shortStringInJS(length))
512
- return result
513
- }
514
- if (length > 64 && decoder)
515
- return decoder.decode(src.subarray(position, position += length))
516
- const end = position + length;
517
- const units = [];
518
- result = '';
519
- while (position < end) {
520
- const byte1 = src[position++];
521
- if ((byte1 & 0x80) === 0) {
522
- // 1 byte
523
- units.push(byte1);
524
- } else if ((byte1 & 0xe0) === 0xc0) {
525
- // 2 bytes
526
- const byte2 = src[position++] & 0x3f;
527
- units.push(((byte1 & 0x1f) << 6) | byte2);
528
- } else if ((byte1 & 0xf0) === 0xe0) {
529
- // 3 bytes
530
- const byte2 = src[position++] & 0x3f;
531
- const byte3 = src[position++] & 0x3f;
532
- units.push(((byte1 & 0x1f) << 12) | (byte2 << 6) | byte3);
533
- } else if ((byte1 & 0xf8) === 0xf0) {
534
- // 4 bytes
535
- const byte2 = src[position++] & 0x3f;
536
- const byte3 = src[position++] & 0x3f;
537
- const byte4 = src[position++] & 0x3f;
538
- let unit = ((byte1 & 0x07) << 0x12) | (byte2 << 0x0c) | (byte3 << 0x06) | byte4;
539
- if (unit > 0xffff) {
540
- unit -= 0x10000;
541
- units.push(((unit >>> 10) & 0x3ff) | 0xd800);
542
- unit = 0xdc00 | (unit & 0x3ff);
543
- }
544
- units.push(unit);
545
- } else {
546
- units.push(byte1);
547
- }
548
-
549
- if (units.length >= 0x1000) {
550
- result += fromCharCode.apply(String, units);
551
- units.length = 0;
552
- }
553
- }
554
-
555
- if (units.length > 0) {
556
- result += fromCharCode.apply(String, units);
557
- }
558
-
559
- return result
560
- }
561
- let fromCharCode = String.fromCharCode;
562
- function longStringInJS(length) {
563
- let start = position;
564
- let bytes = new Array(length);
565
- for (let i = 0; i < length; i++) {
566
- const byte = src[position++];
567
- if ((byte & 0x80) > 0) {
568
- position = start;
569
- return
570
- }
571
- bytes[i] = byte;
572
- }
573
- return fromCharCode.apply(String, bytes)
574
- }
575
- function shortStringInJS(length) {
576
- if (length < 4) {
577
- if (length < 2) {
578
- if (length === 0)
579
- return ''
580
- else {
581
- let a = src[position++];
582
- if ((a & 0x80) > 1) {
583
- position -= 1;
584
- return
585
- }
586
- return fromCharCode(a)
587
- }
588
- } else {
589
- let a = src[position++];
590
- let b = src[position++];
591
- if ((a & 0x80) > 0 || (b & 0x80) > 0) {
592
- position -= 2;
593
- return
594
- }
595
- if (length < 3)
596
- return fromCharCode(a, b)
597
- let c = src[position++];
598
- if ((c & 0x80) > 0) {
599
- position -= 3;
600
- return
601
- }
602
- return fromCharCode(a, b, c)
603
- }
604
- } else {
605
- let a = src[position++];
606
- let b = src[position++];
607
- let c = src[position++];
608
- let d = src[position++];
609
- if ((a & 0x80) > 0 || (b & 0x80) > 0 || (c & 0x80) > 0 || (d & 0x80) > 0) {
610
- position -= 4;
611
- return
612
- }
613
- if (length < 6) {
614
- if (length === 4)
615
- return fromCharCode(a, b, c, d)
616
- else {
617
- let e = src[position++];
618
- if ((e & 0x80) > 0) {
619
- position -= 5;
620
- return
621
- }
622
- return fromCharCode(a, b, c, d, e)
623
- }
624
- } else if (length < 8) {
625
- let e = src[position++];
626
- let f = src[position++];
627
- if ((e & 0x80) > 0 || (f & 0x80) > 0) {
628
- position -= 6;
629
- return
630
- }
631
- if (length < 7)
632
- return fromCharCode(a, b, c, d, e, f)
633
- let g = src[position++];
634
- if ((g & 0x80) > 0) {
635
- position -= 7;
636
- return
637
- }
638
- return fromCharCode(a, b, c, d, e, f, g)
639
- } else {
640
- let e = src[position++];
641
- let f = src[position++];
642
- let g = src[position++];
643
- let h = src[position++];
644
- if ((e & 0x80) > 0 || (f & 0x80) > 0 || (g & 0x80) > 0 || (h & 0x80) > 0) {
645
- position -= 8;
646
- return
647
- }
648
- if (length < 10) {
649
- if (length === 8)
650
- return fromCharCode(a, b, c, d, e, f, g, h)
651
- else {
652
- let i = src[position++];
653
- if ((i & 0x80) > 0) {
654
- position -= 9;
655
- return
656
- }
657
- return fromCharCode(a, b, c, d, e, f, g, h, i)
658
- }
659
- } else if (length < 12) {
660
- let i = src[position++];
661
- let j = src[position++];
662
- if ((i & 0x80) > 0 || (j & 0x80) > 0) {
663
- position -= 10;
664
- return
665
- }
666
- if (length < 11)
667
- return fromCharCode(a, b, c, d, e, f, g, h, i, j)
668
- let k = src[position++];
669
- if ((k & 0x80) > 0) {
670
- position -= 11;
671
- return
672
- }
673
- return fromCharCode(a, b, c, d, e, f, g, h, i, j, k)
674
- } else {
675
- let i = src[position++];
676
- let j = src[position++];
677
- let k = src[position++];
678
- let l = src[position++];
679
- if ((i & 0x80) > 0 || (j & 0x80) > 0 || (k & 0x80) > 0 || (l & 0x80) > 0) {
680
- position -= 12;
681
- return
682
- }
683
- if (length < 14) {
684
- if (length === 12)
685
- return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l)
686
- else {
687
- let m = src[position++];
688
- if ((m & 0x80) > 0) {
689
- position -= 13;
690
- return
691
- }
692
- return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m)
693
- }
694
- } else {
695
- let m = src[position++];
696
- let n = src[position++];
697
- if ((m & 0x80) > 0 || (n & 0x80) > 0) {
698
- position -= 14;
699
- return
700
- }
701
- if (length < 15)
702
- return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m, n)
703
- let o = src[position++];
704
- if ((o & 0x80) > 0) {
705
- position -= 15;
706
- return
707
- }
708
- return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
709
- }
710
- }
711
- }
712
- }
713
- }
714
-
715
- function readBin(length) {
716
- return currentDecoder.copyBuffers ?
717
- // specifically use the copying slice (not the node one)
718
- Uint8Array.prototype.slice.call(src, position, position += length) :
719
- src.subarray(position, position += length)
720
- }
721
-
722
- function getFloat16() {
723
- let byte0 = src[position++];
724
- let byte1 = src[position++];
725
- let half = (byte0 << 8) + byte1;
726
- let exp = (half >> 10) & 0x1f;
727
- let mant = half & 0x3ff;
728
- let val;
729
- if (exp == 0) val = Math.exp(mant, -24);
730
- else if (exp != 31) val = Math.exp(mant + 1024, exp - 25);
731
- else val = mant == 0 ? Infinity : NaN;
732
- return half & 0x8000 ? -val : val
733
- }
734
-
735
- let keyCache = new Array(4096);
736
-
737
- class Tag {
738
- constructor(value, tag) {
739
- this.value = value;
740
- this.tag = tag;
741
- }
742
- }
743
-
744
- let glbl = typeof self == 'object' ? self : global;
745
-
746
- currentExtensions[0] = (dateString) => {
747
- // string date extension
748
- return new Date(dateString)
749
- };
750
-
751
- currentExtensions[1] = (epochSec) => {
752
- // numeric date extension
753
- return new Date(Math.round(epochSec * 1000))
754
- };
755
-
756
- currentExtensions[2] = (buffer) => {
757
- // bigint extension
758
- let value = BigInt(0);
759
- for (let i = 0, l = buffer.byteLength; i < l; i++) {
760
- value = BigInt(buffer[i]) + value << BigInt(8);
761
- }
762
- return value
763
- };
764
-
765
- currentExtensions[3] = (buffer) => {
766
- // negative bigint extension
767
- return BigInt(-1) - currentExtensions[2](buffer)
768
- };
769
- currentExtensions[4] = (fraction) => {
770
- // best to reparse to maintain accuracy
771
- return +(fraction[1] + 'e' + fraction[0])
772
- };
773
-
774
- currentExtensions[5] = (fraction) => {
775
- // probably not sufficiently accurate
776
- return fraction[1] * Math.exp(fraction[0] * Math.log(2))
777
- };
778
-
779
- // the registration of the record definition extension
780
- const recordDefinition = (definition) => {
781
- let id = definition[0] - 0xe000;
782
- let structure = definition[1];
783
- let existingStructure = currentStructures[id];
784
- if (existingStructure && existingStructure.isShared) {
785
- (currentStructures.restoreStructures || (currentStructures.restoreStructures = []))[id] = existingStructure;
786
- }
787
- currentStructures[id] = structure;
788
-
789
- structure.read = createStructureReader(structure);
790
- let object = {};
791
- if (currentDecoder.keyMap) for (let i = 2,l = definition.length; i < l; i++) {
792
- let key = currentDecoder.decodeKey(structure[i - 2]);
793
- object[key] = definition[i];
794
- }
795
- else for (let i = 2,l = definition.length; i < l; i++) {
796
- let key = structure[i - 2];
797
- object[key] = definition[i];
798
- }
799
- return object
800
- };
801
- currentExtensions[LEGACY_RECORD_INLINE_ID] = recordDefinition;
802
- currentExtensions[14] = (value) => {
803
- if (bundledStrings)
804
- return bundledStrings[0].slice(bundledStrings.position0, bundledStrings.position0 += value)
805
- return new Tag(value, 14)
806
- };
807
- currentExtensions[15] = (value) => {
808
- if (bundledStrings)
809
- return bundledStrings[1].slice(bundledStrings.position1, bundledStrings.position1 += value)
810
- return new Tag(value, 15)
811
- };
812
-
813
- currentExtensions[27] = (data) => { // http://cbor.schmorp.de/generic-object
814
- return (glbl[data[0]] || Error)(data[1], data[2])
815
- };
816
- const packedTable = (read) => {
817
- if (src[position++] != 0x84)
818
- throw new Error('Packed values structure must be followed by a 4 element array')
819
- let newPackedValues = read(); // packed values
820
- packedValues = packedValues ? newPackedValues.concat(packedValues.slice(newPackedValues.length)) : newPackedValues;
821
- packedValues.prefixes = read();
822
- packedValues.suffixes = read();
823
- return read() // read the rump
824
- };
825
- packedTable.handlesRead = true;
826
- currentExtensions[51] = packedTable;
827
-
828
- currentExtensions[PACKED_REFERENCE_TAG_ID] = (data) => { // packed reference
829
- if (!packedValues) {
830
- if (currentDecoder.getShared)
831
- loadShared();
832
- else
833
- return new Tag(data, PACKED_REFERENCE_TAG_ID)
834
- }
835
- if (typeof data == 'number')
836
- return packedValues[16 + (data >= 0 ? 2 * data : (-2 * data - 1))]
837
- throw new Error('No support for non-integer packed references yet')
838
- };
839
- currentExtensions[25] = (id) => {
840
- return stringRefs[id]
841
- };
842
- currentExtensions[256] = (read) => {
843
- stringRefs = [];
844
- try {
845
- return read()
846
- } finally {
847
- stringRefs = null;
848
- }
849
- };
850
- currentExtensions[256].handlesRead = true;
851
-
852
- currentExtensions[28] = (read) => {
853
- // shareable http://cbor.schmorp.de/value-sharing (for structured clones)
854
- if (!referenceMap) {
855
- referenceMap = new Map();
856
- referenceMap.id = 0;
857
- }
858
- let id = referenceMap.id++;
859
- let token = src[position];
860
- let target;
861
- // TODO: handle Maps, Sets, and other types that can cycle; this is complicated, because you potentially need to read
862
- // ahead past references to record structure definitions
863
- if ((token >> 5) == 4)
864
- target = [];
865
- else
866
- target = {};
867
-
868
- let refEntry = { target }; // a placeholder object
869
- referenceMap.set(id, refEntry);
870
- let targetProperties = read(); // read the next value as the target object to id
871
- if (refEntry.used) // there is a cycle, so we have to assign properties to original target
872
- return Object.assign(target, targetProperties)
873
- refEntry.target = targetProperties; // the placeholder wasn't used, replace with the deserialized one
874
- return targetProperties // no cycle, can just use the returned read object
875
- };
876
- currentExtensions[28].handlesRead = true;
877
-
878
- currentExtensions[29] = (id) => {
879
- // sharedref http://cbor.schmorp.de/value-sharing (for structured clones)
880
- let refEntry = referenceMap.get(id);
881
- refEntry.used = true;
882
- return refEntry.target
883
- };
884
-
885
- currentExtensions[258] = (array) => new Set(array); // https://github.com/input-output-hk/cbor-sets-spec/blob/master/CBOR_SETS.md
886
- (currentExtensions[259] = (read) => {
887
- // https://github.com/shanewholloway/js-cbor-codec/blob/master/docs/CBOR-259-spec
888
- // for decoding as a standard Map
889
- if (currentDecoder.mapsAsObjects) {
890
- currentDecoder.mapsAsObjects = false;
891
- restoreMapsAsObject = true;
892
- }
893
- return read()
894
- }).handlesRead = true;
895
- function combine(a, b) {
896
- if (typeof a === 'string')
897
- return a + b
898
- if (a instanceof Array)
899
- return a.concat(b)
900
- return Object.assign({}, a, b)
901
- }
902
- function getPackedValues() {
903
- if (!packedValues) {
904
- if (currentDecoder.getShared)
905
- loadShared();
906
- else
907
- throw new Error('No packed values available')
908
- }
909
- return packedValues
910
- }
911
- const SHARED_DATA_TAG_ID = 0x53687264; // ascii 'Shrd'
912
- currentExtensionRanges.push((tag, input) => {
913
- if (tag >= 225 && tag <= 255)
914
- return combine(getPackedValues().prefixes[tag - 224], input)
915
- if (tag >= 28704 && tag <= 32767)
916
- return combine(getPackedValues().prefixes[tag - 28672], input)
917
- if (tag >= 1879052288 && tag <= 2147483647)
918
- return combine(getPackedValues().prefixes[tag - 1879048192], input)
919
- if (tag >= 216 && tag <= 223)
920
- return combine(input, getPackedValues().suffixes[tag - 216])
921
- if (tag >= 27647 && tag <= 28671)
922
- return combine(input, getPackedValues().suffixes[tag - 27639])
923
- if (tag >= 1811940352 && tag <= 1879048191)
924
- return combine(input, getPackedValues().suffixes[tag - 1811939328])
925
- 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)
926
- return {
927
- packedValues: packedValues,
928
- structures: currentStructures.slice(0),
929
- version: input,
930
- }
931
- }
932
- if (tag == 55799) // self-descriptive CBOR tag, just return input value
933
- return input
934
- });
935
-
936
- const isLittleEndianMachine = new Uint8Array(new Uint16Array([1]).buffer)[0] == 1;
937
- const typedArrays = ['Uint8', 'Uint8Clamped', 'Uint16', 'Uint32', 'BigUint64','Int8', 'Int16', 'Int32', 'BigInt64', 'Float32', 'Float64'];
938
- const typedArrayTags = [64, 68, 69, 70, 71, 72, 77, 78, 79, 85, 86];
939
- for (let i = 0; i < typedArrays.length; i++) {
940
- registerTypedArray(typedArrays[i], typedArrayTags[i]);
941
- }
942
- function registerTypedArray(typedArrayId, tag, littleEndian) {
943
- let TypedArray = glbl[typedArrayId + 'Array'];
944
- let bytesPerElement = TypedArray.BYTES_PER_ELEMENT;
945
- for (let littleEndian = 0; littleEndian < 2; littleEndian++) {
946
- if (!littleEndian && bytesPerElement == 1)
947
- continue
948
- let sizeShift = bytesPerElement == 2 ? 1 : bytesPerElement == 4 ? 2 : 3;
949
- currentExtensions[littleEndian ? tag : (tag - 4)] = (bytesPerElement == 1 || littleEndian == isLittleEndianMachine) ? (buffer) => {
950
- if (!TypedArray)
951
- throw new Error('Could not find typed array for code ' + tag)
952
- // we have to always slice/copy here to get a new ArrayBuffer that is word/byte aligned
953
- return new TypedArray(Uint8Array.prototype.slice.call(buffer, 0).buffer)
954
- } : buffer => {
955
- if (!TypedArray)
956
- throw new Error('Could not find typed array for code ' + tag)
957
- let dv = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
958
- let elements = buffer.length >> sizeShift;
959
- let ta = new TypedArray(elements);
960
- let method = dv['get' + typedArrayId];
961
- for (let i = 0; i < elements; i++) {
962
- ta[i] = method.call(dv, i << sizeShift, littleEndian);
963
- }
964
- return ta
965
- };
966
- }
967
- }
968
-
969
- function readBundleExt() {
970
- let length = readJustLength();
971
- let bundlePosition = position + read();
972
- for (let i = 2; i < length; i++) {
973
- // skip past bundles that were already read
974
- let bundleLength = readJustLength(); // this will increment position, so must add to position afterwards
975
- position += bundleLength;
976
- }
977
- let dataPosition = position;
978
- position = bundlePosition;
979
- bundledStrings = [readStringJS(readJustLength()), readStringJS(readJustLength())];
980
- bundledStrings.position0 = 0;
981
- bundledStrings.position1 = 0;
982
- bundledStrings.postBundlePosition = position;
983
- position = dataPosition;
984
- return read()
985
- }
986
-
987
- function readJustLength() {
988
- let token = src[position++] & 0x1f;
989
- if (token > 0x17) {
990
- switch (token) {
991
- case 0x18:
992
- token = src[position++];
993
- break
994
- case 0x19:
995
- token = dataView.getUint16(position);
996
- position += 2;
997
- break
998
- case 0x1a:
999
- token = dataView.getUint32(position);
1000
- position += 4;
1001
- break
1002
- }
1003
- }
1004
- return token
1005
- }
1006
-
1007
- function loadShared() {
1008
- if (currentDecoder.getShared) {
1009
- let sharedData = saveState(() => {
1010
- // save the state in case getShared modifies our buffer
1011
- src = null;
1012
- return currentDecoder.getShared()
1013
- }) || {};
1014
- let updatedStructures = sharedData.structures || [];
1015
- currentDecoder.sharedVersion = sharedData.version;
1016
- packedValues = currentDecoder.sharedValues = sharedData.packedValues;
1017
- if (currentStructures === true)
1018
- currentDecoder.structures = currentStructures = updatedStructures;
1019
- else
1020
- currentStructures.splice.apply(currentStructures, [0, updatedStructures.length].concat(updatedStructures));
1021
- }
1022
- }
1023
-
1024
- function saveState(callback) {
1025
- let savedSrcEnd = srcEnd;
1026
- let savedPosition = position;
1027
- let savedStringPosition = stringPosition;
1028
- let savedSrcStringStart = srcStringStart;
1029
- let savedSrcStringEnd = srcStringEnd;
1030
- let savedSrcString = srcString;
1031
- let savedStrings = strings;
1032
- let savedReferenceMap = referenceMap;
1033
- let savedBundledStrings = bundledStrings;
1034
-
1035
- // TODO: We may need to revisit this if we do more external calls to user code (since it could be slow)
1036
- let savedSrc = new Uint8Array(src.slice(0, srcEnd)); // we copy the data in case it changes while external data is processed
1037
- let savedStructures = currentStructures;
1038
- let savedDecoder = currentDecoder;
1039
- let savedSequentialMode = sequentialMode;
1040
- let value = callback();
1041
- srcEnd = savedSrcEnd;
1042
- position = savedPosition;
1043
- stringPosition = savedStringPosition;
1044
- srcStringStart = savedSrcStringStart;
1045
- srcStringEnd = savedSrcStringEnd;
1046
- srcString = savedSrcString;
1047
- strings = savedStrings;
1048
- referenceMap = savedReferenceMap;
1049
- bundledStrings = savedBundledStrings;
1050
- src = savedSrc;
1051
- sequentialMode = savedSequentialMode;
1052
- currentStructures = savedStructures;
1053
- currentDecoder = savedDecoder;
1054
- dataView = new DataView(src.buffer, src.byteOffset, src.byteLength);
1055
- return value
1056
- }
1057
- function clearSource() {
1058
- src = null;
1059
- referenceMap = null;
1060
- currentStructures = null;
1061
- }
1062
-
1063
- function addExtension(extension) {
1064
- currentExtensions[extension.tag] = extension.decode;
1065
- }
1066
-
1067
- const mult10 = new Array(147); // this is a table matching binary exponents to the multiplier to determine significant digit rounding
1068
- for (let i = 0; i < 256; i++) {
1069
- mult10[i] = +('1e' + Math.floor(45.15 - i * 0.30103));
1070
- }
1071
- let defaultDecoder = new Decoder({ useRecords: false });
1072
- const decode = defaultDecoder.decode;
1073
- const decodeMultiple = defaultDecoder.decodeMultiple;
1074
- const FLOAT32_OPTIONS = {
1075
- NEVER: 0,
1076
- ALWAYS: 1,
1077
- DECIMAL_ROUND: 3,
1078
- DECIMAL_FIT: 4
1079
- };
1080
- let f32Array = new Float32Array(1);
1081
- let u8Array = new Uint8Array(f32Array.buffer, 0, 4);
1082
- function roundFloat32(float32Number) {
1083
- f32Array[0] = float32Number;
1084
- let multiplier = mult10[((u8Array[3] & 0x7f) << 1) | (u8Array[2] >> 7)];
1085
- return ((multiplier * float32Number + (float32Number > 0 ? 0.5 : -0.5)) >> 0) / multiplier
8
+ let decoder;
9
+ try {
10
+ decoder = new TextDecoder();
11
+ } catch(error) {}
12
+ let src;
13
+ let srcEnd;
14
+ let position = 0;
15
+ const EMPTY_ARRAY = [];
16
+ const LEGACY_RECORD_INLINE_ID = 105;
17
+ const RECORD_DEFINITIONS_ID = 0xdffe;
18
+ const RECORD_INLINE_ID = 0xdfff; // temporary first-come first-serve tag // proposed tag: 0x7265 // 're'
19
+ const BUNDLED_STRINGS_ID = 0xdff9;
20
+ const PACKED_REFERENCE_TAG_ID = 6;
21
+ const STOP_CODE = {};
22
+ let strings = EMPTY_ARRAY;
23
+ let stringPosition = 0;
24
+ let currentDecoder = {};
25
+ let currentStructures;
26
+ let srcString;
27
+ let srcStringStart = 0;
28
+ let srcStringEnd = 0;
29
+ let bundledStrings;
30
+ let referenceMap;
31
+ let currentExtensions = [];
32
+ let currentExtensionRanges = [];
33
+ let packedValues;
34
+ let dataView;
35
+ let restoreMapsAsObject;
36
+ let defaultOptions = {
37
+ useRecords: false,
38
+ mapsAsObjects: true
39
+ };
40
+ let sequentialMode = false;
41
+
42
+ class Decoder {
43
+ constructor(options) {
44
+ if (options) {
45
+ if ((options.keyMap || options._keyMap) && !options.useRecords) {
46
+ options.useRecords = false;
47
+ options.mapsAsObjects = true;
48
+ }
49
+ if (options.useRecords === false && options.mapsAsObjects === undefined)
50
+ options.mapsAsObjects = true;
51
+ if (options.getStructures)
52
+ options.getShared = options.getStructures;
53
+ if (options.getShared && !options.structures)
54
+ (options.structures = []).uninitialized = true; // this is what we use to denote an uninitialized structures
55
+ if (options.keyMap) {
56
+ this.mapKey = new Map();
57
+ for (let [k,v] of Object.entries(options.keyMap)) this.mapKey.set(v,k);
58
+ }
59
+ }
60
+ Object.assign(this, options);
61
+ }
62
+ /*
63
+ decodeKey(key) {
64
+ return this.keyMap
65
+ ? Object.keys(this.keyMap)[Object.values(this.keyMap).indexOf(key)] || key
66
+ : key
67
+ }
68
+ */
69
+ decodeKey(key) {
70
+ return this.keyMap ? this.mapKey.get(key) || key : key
71
+ }
72
+
73
+ encodeKey(key) {
74
+ return this.keyMap && this.keyMap.hasOwnProperty(key) ? this.keyMap[key] : key
75
+ }
76
+
77
+ encodeKeys(rec) {
78
+ if (!this._keyMap) return rec
79
+ let map = new Map();
80
+ for (let [k,v] of Object.entries(rec)) map.set((this._keyMap.hasOwnProperty(k) ? this._keyMap[k] : k), v);
81
+ return map
82
+ }
83
+
84
+ decodeKeys(map) {
85
+ if (!this._keyMap || map.constructor.name != 'Map') return map
86
+ if (!this._mapKey) {
87
+ this._mapKey = new Map();
88
+ for (let [k,v] of Object.entries(this._keyMap)) this._mapKey.set(v,k);
89
+ }
90
+ let res = {};
91
+ //map.forEach((v,k) => res[Object.keys(this._keyMap)[Object.values(this._keyMap).indexOf(k)] || k] = v)
92
+ map.forEach((v,k) => res[this._mapKey.has(k) ? this._mapKey.get(k) : k] = v);
93
+ return res
94
+ }
95
+
96
+ mapDecode(source, end) {
97
+
98
+ let res = this.decode(source);
99
+ if (this._keyMap) {
100
+ //Experiemntal support for Optimised KeyMap decoding
101
+ switch (res.constructor.name) {
102
+ case 'Array': return res.map(r => this.decodeKeys(r))
103
+ //case 'Map': return this.decodeKeys(res)
104
+ }
105
+ }
106
+ return res
107
+ }
108
+
109
+ decode(source, end) {
110
+ if (src) {
111
+ // re-entrant execution, save the state and restore it after we do this decode
112
+ return saveState(() => {
113
+ clearSource();
114
+ return this ? this.decode(source, end) : Decoder.prototype.decode.call(defaultOptions, source, end)
115
+ })
116
+ }
117
+ srcEnd = end > -1 ? end : source.length;
118
+ position = 0;
119
+ stringPosition = 0;
120
+ srcStringEnd = 0;
121
+ srcString = null;
122
+ strings = EMPTY_ARRAY;
123
+ bundledStrings = null;
124
+ src = source;
125
+ // this provides cached access to the data view for a buffer if it is getting reused, which is a recommend
126
+ // technique for getting data from a database where it can be copied into an existing buffer instead of creating
127
+ // new ones
128
+ try {
129
+ dataView = source.dataView || (source.dataView = new DataView(source.buffer, source.byteOffset, source.byteLength));
130
+ } catch(error) {
131
+ // if it doesn't have a buffer, maybe it is the wrong type of object
132
+ src = null;
133
+ if (source instanceof Uint8Array)
134
+ throw error
135
+ throw new Error('Source must be a Uint8Array or Buffer but was a ' + ((source && typeof source == 'object') ? source.constructor.name : typeof source))
136
+ }
137
+ if (this instanceof Decoder) {
138
+ currentDecoder = this;
139
+ packedValues = this.sharedValues &&
140
+ (this.pack ? new Array(this.maxPrivatePackedValues || 16).concat(this.sharedValues) :
141
+ this.sharedValues);
142
+ if (this.structures) {
143
+ currentStructures = this.structures;
144
+ return checkedRead()
145
+ } else if (!currentStructures || currentStructures.length > 0) {
146
+ currentStructures = [];
147
+ }
148
+ } else {
149
+ currentDecoder = defaultOptions;
150
+ if (!currentStructures || currentStructures.length > 0)
151
+ currentStructures = [];
152
+ packedValues = null;
153
+ }
154
+ return checkedRead()
155
+ }
156
+ decodeMultiple(source, forEach) {
157
+ let values, lastPosition = 0;
158
+ try {
159
+ let size = source.length;
160
+ sequentialMode = true;
161
+ let value = this ? this.decode(source, size) : defaultDecoder.decode(source, size);
162
+ if (forEach) {
163
+ if (forEach(value) === false) {
164
+ return
165
+ }
166
+ while(position < size) {
167
+ lastPosition = position;
168
+ if (forEach(checkedRead()) === false) {
169
+ return
170
+ }
171
+ }
172
+ }
173
+ else {
174
+ values = [ value ];
175
+ while(position < size) {
176
+ lastPosition = position;
177
+ values.push(checkedRead());
178
+ }
179
+ return values
180
+ }
181
+ } catch(error) {
182
+ error.lastPosition = lastPosition;
183
+ error.values = values;
184
+ throw error
185
+ } finally {
186
+ sequentialMode = false;
187
+ clearSource();
188
+ }
189
+ }
190
+ }
191
+ function checkedRead() {
192
+ try {
193
+ let result = read();
194
+ if (bundledStrings) {
195
+ if (position >= bundledStrings.postBundlePosition) {
196
+ let error = new Error('Unexpected bundle position');
197
+ error.incomplete = true;
198
+ throw error
199
+ }
200
+ // bundled strings to skip past
201
+ position = bundledStrings.postBundlePosition;
202
+ }
203
+
204
+ if (position == srcEnd) {
205
+ // finished reading this source, cleanup references
206
+ currentStructures = null;
207
+ src = null;
208
+ if (referenceMap)
209
+ referenceMap = null;
210
+ } else if (position > srcEnd) {
211
+ // over read
212
+ let error = new Error('Unexpected end of CBOR data');
213
+ error.incomplete = true;
214
+ throw error
215
+ } else if (!sequentialMode) {
216
+ throw new Error('Data read, but end of buffer not reached')
217
+ }
218
+ // else more to read, but we are reading sequentially, so don't clear source yet
219
+ return result
220
+ } catch(error) {
221
+ clearSource();
222
+ if (error instanceof RangeError || error.message.startsWith('Unexpected end of buffer')) {
223
+ error.incomplete = true;
224
+ }
225
+ throw error
226
+ }
227
+ }
228
+
229
+ function read() {
230
+ let token = src[position++];
231
+ let majorType = token >> 5;
232
+ token = token & 0x1f;
233
+ if (token > 0x17) {
234
+ switch (token) {
235
+ case 0x18:
236
+ token = src[position++];
237
+ break
238
+ case 0x19:
239
+ if (majorType == 7) {
240
+ return getFloat16()
241
+ }
242
+ token = dataView.getUint16(position);
243
+ position += 2;
244
+ break
245
+ case 0x1a:
246
+ if (majorType == 7) {
247
+ let value = dataView.getFloat32(position);
248
+ if (currentDecoder.useFloat32 > 2) {
249
+ // this does rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
250
+ let multiplier = mult10[((src[position] & 0x7f) << 1) | (src[position + 1] >> 7)];
251
+ position += 4;
252
+ return ((multiplier * value + (value > 0 ? 0.5 : -0.5)) >> 0) / multiplier
253
+ }
254
+ position += 4;
255
+ return value
256
+ }
257
+ token = dataView.getUint32(position);
258
+ position += 4;
259
+ break
260
+ case 0x1b:
261
+ if (majorType == 7) {
262
+ let value = dataView.getFloat64(position);
263
+ position += 8;
264
+ return value
265
+ }
266
+ if (majorType > 1) {
267
+ if (dataView.getUint32(position) > 0)
268
+ throw new Error('JavaScript does not support arrays, maps, or strings with length over 4294967295')
269
+ token = dataView.getUint32(position + 4);
270
+ } else if (currentDecoder.int64AsNumber) {
271
+ token = dataView.getUint32(position) * 0x100000000;
272
+ token += dataView.getUint32(position + 4);
273
+ } else
274
+ token = dataView.getBigUint64(position);
275
+ position += 8;
276
+ break
277
+ case 0x1f:
278
+ // indefinite length
279
+ switch(majorType) {
280
+ case 2: // byte string
281
+ case 3: // text string
282
+ throw new Error('Indefinite length not supported for byte or text strings')
283
+ case 4: // array
284
+ let array = [];
285
+ let value, i = 0;
286
+ while ((value = read()) != STOP_CODE) {
287
+ array[i++] = value;
288
+ }
289
+ return majorType == 4 ? array : majorType == 3 ? array.join('') : Buffer.concat(array)
290
+ case 5: // map
291
+ let key;
292
+ if (currentDecoder.mapsAsObjects) {
293
+ let object = {};
294
+ if (currentDecoder.keyMap) while((key = read()) != STOP_CODE) object[currentDecoder.decodeKey(key)] = read();
295
+ else while ((key = read()) != STOP_CODE) object[key] = read();
296
+ return object
297
+ } else {
298
+ if (restoreMapsAsObject) {
299
+ currentDecoder.mapsAsObjects = true;
300
+ restoreMapsAsObject = false;
301
+ }
302
+ let map = new Map();
303
+ if (currentDecoder.keyMap) while((key = read()) != STOP_CODE) map.set(currentDecoder.decodeKey(key), read());
304
+ else while ((key = read()) != STOP_CODE) map.set(key, read());
305
+ return map
306
+ }
307
+ case 7:
308
+ return STOP_CODE
309
+ default:
310
+ throw new Error('Invalid major type for indefinite length ' + majorType)
311
+ }
312
+ default:
313
+ throw new Error('Unknown token ' + token)
314
+ }
315
+ }
316
+ switch (majorType) {
317
+ case 0: // positive int
318
+ return token
319
+ case 1: // negative int
320
+ return ~token
321
+ case 2: // buffer
322
+ return readBin(token)
323
+ case 3: // string
324
+ if (srcStringEnd >= position) {
325
+ return srcString.slice(position - srcStringStart, (position += token) - srcStringStart)
326
+ }
327
+ if (srcStringEnd == 0 && srcEnd < 140 && token < 32) {
328
+ // for small blocks, avoiding the overhead of the extract call is helpful
329
+ let string = token < 16 ? shortStringInJS(token) : longStringInJS(token);
330
+ if (string != null)
331
+ return string
332
+ }
333
+ return readFixedString(token)
334
+ case 4: // array
335
+ let array = new Array(token);
336
+ //if (currentDecoder.keyMap) for (let i = 0; i < token; i++) array[i] = currentDecoder.decodeKey(read())
337
+ //else
338
+ for (let i = 0; i < token; i++) array[i] = read();
339
+ return array
340
+ case 5: // map
341
+ if (currentDecoder.mapsAsObjects) {
342
+ let object = {};
343
+ if (currentDecoder.keyMap) for (let i = 0; i < token; i++) object[currentDecoder.decodeKey(read())] = read();
344
+ else for (let i = 0; i < token; i++) object[read()] = read();
345
+ return object
346
+ } else {
347
+ if (restoreMapsAsObject) {
348
+ currentDecoder.mapsAsObjects = true;
349
+ restoreMapsAsObject = false;
350
+ }
351
+ let map = new Map();
352
+ if (currentDecoder.keyMap) for (let i = 0; i < token; i++) map.set(currentDecoder.decodeKey(read()),read());
353
+ else for (let i = 0; i < token; i++) map.set(read(), read());
354
+ return map
355
+ }
356
+ case 6: // extension
357
+ if (token >= BUNDLED_STRINGS_ID) {
358
+ let structure = currentStructures[token & 0x1fff]; // check record structures first
359
+ // 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))
360
+ if (structure) {
361
+ if (!structure.read) structure.read = createStructureReader(structure);
362
+ return structure.read()
363
+ }
364
+ if (token < 0x10000) {
365
+ 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)
366
+ return recordDefinition(read())
367
+ else if (token == RECORD_DEFINITIONS_ID) {
368
+ let length = readJustLength();
369
+ let id = read();
370
+ for (let i = 2; i < length; i++) {
371
+ recordDefinition([id++, read()]);
372
+ }
373
+ return read()
374
+ } else if (token == BUNDLED_STRINGS_ID) {
375
+ return readBundleExt()
376
+ }
377
+ if (currentDecoder.getShared) {
378
+ loadShared();
379
+ structure = currentStructures[token & 0x1fff];
380
+ if (structure) {
381
+ if (!structure.read)
382
+ structure.read = createStructureReader(structure);
383
+ return structure.read()
384
+ }
385
+ }
386
+ }
387
+ }
388
+ let extension = currentExtensions[token];
389
+ if (extension) {
390
+ if (extension.handlesRead)
391
+ return extension(read)
392
+ else
393
+ return extension(read())
394
+ } else {
395
+ let input = read();
396
+ for (let i = 0; i < currentExtensionRanges.length; i++) {
397
+ let value = currentExtensionRanges[i](token, input);
398
+ if (value !== undefined)
399
+ return value
400
+ }
401
+ return new Tag(input, token)
402
+ }
403
+ case 7: // fixed value
404
+ switch (token) {
405
+ case 0x14: return false
406
+ case 0x15: return true
407
+ case 0x16: return null
408
+ case 0x17: return; // undefined
409
+ case 0x1f:
410
+ default:
411
+ let packedValue = (packedValues || getPackedValues())[token];
412
+ if (packedValue !== undefined)
413
+ return packedValue
414
+ throw new Error('Unknown token ' + token)
415
+ }
416
+ default: // negative int
417
+ if (isNaN(token)) {
418
+ let error = new Error('Unexpected end of CBOR data');
419
+ error.incomplete = true;
420
+ throw error
421
+ }
422
+ throw new Error('Unknown CBOR token ' + token)
423
+ }
424
+ }
425
+ const validName = /^[a-zA-Z_$][a-zA-Z\d_$]*$/;
426
+ function createStructureReader(structure) {
427
+ function readObject() {
428
+ // get the array size from the header
429
+ let length = src[position++];
430
+ //let majorType = token >> 5
431
+ length = length & 0x1f;
432
+ if (length > 0x17) {
433
+ switch (length) {
434
+ case 0x18:
435
+ length = src[position++];
436
+ break
437
+ case 0x19:
438
+ length = dataView.getUint16(position);
439
+ position += 2;
440
+ break
441
+ case 0x1a:
442
+ length = dataView.getUint32(position);
443
+ position += 4;
444
+ break
445
+ default:
446
+ throw new Error('Expected array header, but got ' + src[position - 1])
447
+ }
448
+ }
449
+ // This initial function is quick to instantiate, but runs slower. After several iterations pay the cost to build the faster function
450
+ let compiledReader = this.compiledReader; // first look to see if we have the fast compiled function
451
+ while(compiledReader) {
452
+ // we have a fast compiled object literal reader
453
+ if (compiledReader.propertyCount === length)
454
+ return compiledReader(read) // with the right length, so we use it
455
+ compiledReader = compiledReader.next; // see if there is another reader with the right length
456
+ }
457
+ if (this.slowReads++ >= 3) { // create a fast compiled reader
458
+ let array = this.length == length ? this : this.slice(0, length);
459
+ compiledReader = currentDecoder.keyMap
460
+ ? new Function('r', 'return {' + array.map(k => currentDecoder.decodeKey(k)).map(k => validName.test(k) ? k + ':r()' : ('[' + JSON.stringify(k) + ']:r()')).join(',') + '}')
461
+ : new Function('r', 'return {' + array.map(key => validName.test(key) ? key + ':r()' : ('[' + JSON.stringify(key) + ']:r()')).join(',') + '}');
462
+ if (this.compiledReader)
463
+ 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
464
+ compiledReader.propertyCount = length;
465
+ this.compiledReader = compiledReader;
466
+ return compiledReader(read)
467
+ }
468
+ let object = {};
469
+ if (currentDecoder.keyMap) for (let i = 0; i < length; i++) object[currentDecoder.decodeKey(this[i])] = read();
470
+ else for (let i = 0; i < length; i++) object[this[i]] = read();
471
+ return object
472
+ }
473
+ structure.slowReads = 0;
474
+ return readObject
475
+ }
476
+
477
+ let readFixedString = readStringJS;
478
+
479
+ exports.isNativeAccelerationEnabled = false;
480
+ function setExtractor(extractStrings) {
481
+ exports.isNativeAccelerationEnabled = true;
482
+ readFixedString = readString();
483
+ function readString(headerLength) {
484
+ return function readString(length) {
485
+ let string = strings[stringPosition++];
486
+ if (string == null) {
487
+ if (bundledStrings)
488
+ return readStringJS(length)
489
+ let extraction = extractStrings(position, srcEnd, length, src);
490
+ if (typeof extraction == 'string') {
491
+ string = extraction;
492
+ strings = EMPTY_ARRAY;
493
+ } else {
494
+ strings = extraction;
495
+ stringPosition = 1;
496
+ srcStringEnd = 1; // even if a utf-8 string was decoded, must indicate we are in the midst of extracted strings and can't skip strings
497
+ string = strings[0];
498
+ if (string === undefined)
499
+ throw new Error('Unexpected end of buffer')
500
+ }
501
+ }
502
+ let srcStringLength = string.length;
503
+ if (srcStringLength <= length) {
504
+ position += length;
505
+ return string
506
+ }
507
+ srcString = string;
508
+ srcStringStart = position;
509
+ srcStringEnd = position + srcStringLength;
510
+ position += length;
511
+ return string.slice(0, length) // we know we just want the beginning
512
+ }
513
+ }
514
+ }
515
+ function readStringJS(length) {
516
+ let result;
517
+ if (length < 16) {
518
+ if (result = shortStringInJS(length))
519
+ return result
520
+ }
521
+ if (length > 64 && decoder)
522
+ return decoder.decode(src.subarray(position, position += length))
523
+ const end = position + length;
524
+ const units = [];
525
+ result = '';
526
+ while (position < end) {
527
+ const byte1 = src[position++];
528
+ if ((byte1 & 0x80) === 0) {
529
+ // 1 byte
530
+ units.push(byte1);
531
+ } else if ((byte1 & 0xe0) === 0xc0) {
532
+ // 2 bytes
533
+ const byte2 = src[position++] & 0x3f;
534
+ units.push(((byte1 & 0x1f) << 6) | byte2);
535
+ } else if ((byte1 & 0xf0) === 0xe0) {
536
+ // 3 bytes
537
+ const byte2 = src[position++] & 0x3f;
538
+ const byte3 = src[position++] & 0x3f;
539
+ units.push(((byte1 & 0x1f) << 12) | (byte2 << 6) | byte3);
540
+ } else if ((byte1 & 0xf8) === 0xf0) {
541
+ // 4 bytes
542
+ const byte2 = src[position++] & 0x3f;
543
+ const byte3 = src[position++] & 0x3f;
544
+ const byte4 = src[position++] & 0x3f;
545
+ let unit = ((byte1 & 0x07) << 0x12) | (byte2 << 0x0c) | (byte3 << 0x06) | byte4;
546
+ if (unit > 0xffff) {
547
+ unit -= 0x10000;
548
+ units.push(((unit >>> 10) & 0x3ff) | 0xd800);
549
+ unit = 0xdc00 | (unit & 0x3ff);
550
+ }
551
+ units.push(unit);
552
+ } else {
553
+ units.push(byte1);
554
+ }
555
+
556
+ if (units.length >= 0x1000) {
557
+ result += fromCharCode.apply(String, units);
558
+ units.length = 0;
559
+ }
560
+ }
561
+
562
+ if (units.length > 0) {
563
+ result += fromCharCode.apply(String, units);
564
+ }
565
+
566
+ return result
567
+ }
568
+ let fromCharCode = String.fromCharCode;
569
+ function longStringInJS(length) {
570
+ let start = position;
571
+ let bytes = new Array(length);
572
+ for (let i = 0; i < length; i++) {
573
+ const byte = src[position++];
574
+ if ((byte & 0x80) > 0) {
575
+ position = start;
576
+ return
577
+ }
578
+ bytes[i] = byte;
579
+ }
580
+ return fromCharCode.apply(String, bytes)
581
+ }
582
+ function shortStringInJS(length) {
583
+ if (length < 4) {
584
+ if (length < 2) {
585
+ if (length === 0)
586
+ return ''
587
+ else {
588
+ let a = src[position++];
589
+ if ((a & 0x80) > 1) {
590
+ position -= 1;
591
+ return
592
+ }
593
+ return fromCharCode(a)
594
+ }
595
+ } else {
596
+ let a = src[position++];
597
+ let b = src[position++];
598
+ if ((a & 0x80) > 0 || (b & 0x80) > 0) {
599
+ position -= 2;
600
+ return
601
+ }
602
+ if (length < 3)
603
+ return fromCharCode(a, b)
604
+ let c = src[position++];
605
+ if ((c & 0x80) > 0) {
606
+ position -= 3;
607
+ return
608
+ }
609
+ return fromCharCode(a, b, c)
610
+ }
611
+ } else {
612
+ let a = src[position++];
613
+ let b = src[position++];
614
+ let c = src[position++];
615
+ let d = src[position++];
616
+ if ((a & 0x80) > 0 || (b & 0x80) > 0 || (c & 0x80) > 0 || (d & 0x80) > 0) {
617
+ position -= 4;
618
+ return
619
+ }
620
+ if (length < 6) {
621
+ if (length === 4)
622
+ return fromCharCode(a, b, c, d)
623
+ else {
624
+ let e = src[position++];
625
+ if ((e & 0x80) > 0) {
626
+ position -= 5;
627
+ return
628
+ }
629
+ return fromCharCode(a, b, c, d, e)
630
+ }
631
+ } else if (length < 8) {
632
+ let e = src[position++];
633
+ let f = src[position++];
634
+ if ((e & 0x80) > 0 || (f & 0x80) > 0) {
635
+ position -= 6;
636
+ return
637
+ }
638
+ if (length < 7)
639
+ return fromCharCode(a, b, c, d, e, f)
640
+ let g = src[position++];
641
+ if ((g & 0x80) > 0) {
642
+ position -= 7;
643
+ return
644
+ }
645
+ return fromCharCode(a, b, c, d, e, f, g)
646
+ } else {
647
+ let e = src[position++];
648
+ let f = src[position++];
649
+ let g = src[position++];
650
+ let h = src[position++];
651
+ if ((e & 0x80) > 0 || (f & 0x80) > 0 || (g & 0x80) > 0 || (h & 0x80) > 0) {
652
+ position -= 8;
653
+ return
654
+ }
655
+ if (length < 10) {
656
+ if (length === 8)
657
+ return fromCharCode(a, b, c, d, e, f, g, h)
658
+ else {
659
+ let i = src[position++];
660
+ if ((i & 0x80) > 0) {
661
+ position -= 9;
662
+ return
663
+ }
664
+ return fromCharCode(a, b, c, d, e, f, g, h, i)
665
+ }
666
+ } else if (length < 12) {
667
+ let i = src[position++];
668
+ let j = src[position++];
669
+ if ((i & 0x80) > 0 || (j & 0x80) > 0) {
670
+ position -= 10;
671
+ return
672
+ }
673
+ if (length < 11)
674
+ return fromCharCode(a, b, c, d, e, f, g, h, i, j)
675
+ let k = src[position++];
676
+ if ((k & 0x80) > 0) {
677
+ position -= 11;
678
+ return
679
+ }
680
+ return fromCharCode(a, b, c, d, e, f, g, h, i, j, k)
681
+ } else {
682
+ let i = src[position++];
683
+ let j = src[position++];
684
+ let k = src[position++];
685
+ let l = src[position++];
686
+ if ((i & 0x80) > 0 || (j & 0x80) > 0 || (k & 0x80) > 0 || (l & 0x80) > 0) {
687
+ position -= 12;
688
+ return
689
+ }
690
+ if (length < 14) {
691
+ if (length === 12)
692
+ return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l)
693
+ else {
694
+ let m = src[position++];
695
+ if ((m & 0x80) > 0) {
696
+ position -= 13;
697
+ return
698
+ }
699
+ return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m)
700
+ }
701
+ } else {
702
+ let m = src[position++];
703
+ let n = src[position++];
704
+ if ((m & 0x80) > 0 || (n & 0x80) > 0) {
705
+ position -= 14;
706
+ return
707
+ }
708
+ if (length < 15)
709
+ return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m, n)
710
+ let o = src[position++];
711
+ if ((o & 0x80) > 0) {
712
+ position -= 15;
713
+ return
714
+ }
715
+ return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
716
+ }
717
+ }
718
+ }
719
+ }
720
+ }
721
+
722
+ function readBin(length) {
723
+ return currentDecoder.copyBuffers ?
724
+ // specifically use the copying slice (not the node one)
725
+ Uint8Array.prototype.slice.call(src, position, position += length) :
726
+ src.subarray(position, position += length)
727
+ }
728
+
729
+ function getFloat16() {
730
+ let byte0 = src[position++];
731
+ let byte1 = src[position++];
732
+ let half = (byte0 << 8) + byte1;
733
+ let exp = (half >> 10) & 0x1f;
734
+ let mant = half & 0x3ff;
735
+ let val;
736
+ if (exp == 0) val = Math.exp(mant, -24);
737
+ else if (exp != 31) val = Math.exp(mant + 1024, exp - 25);
738
+ else val = mant == 0 ? Infinity : NaN;
739
+ return half & 0x8000 ? -val : val
740
+ }
741
+
742
+ let keyCache = new Array(4096);
743
+
744
+ class Tag {
745
+ constructor(value, tag) {
746
+ this.value = value;
747
+ this.tag = tag;
748
+ }
749
+ }
750
+
751
+ let glbl = typeof self == 'object' ? self : global;
752
+
753
+ currentExtensions[0] = (dateString) => {
754
+ // string date extension
755
+ return new Date(dateString)
756
+ };
757
+
758
+ currentExtensions[1] = (epochSec) => {
759
+ // numeric date extension
760
+ return new Date(Math.round(epochSec * 1000))
761
+ };
762
+
763
+ currentExtensions[2] = (buffer) => {
764
+ // bigint extension
765
+ let value = BigInt(0);
766
+ for (let i = 0, l = buffer.byteLength; i < l; i++) {
767
+ value = BigInt(buffer[i]) + value << BigInt(8);
768
+ }
769
+ return value
770
+ };
771
+
772
+ currentExtensions[3] = (buffer) => {
773
+ // negative bigint extension
774
+ return BigInt(-1) - currentExtensions[2](buffer)
775
+ };
776
+ currentExtensions[4] = (fraction) => {
777
+ // best to reparse to maintain accuracy
778
+ return +(fraction[1] + 'e' + fraction[0])
779
+ };
780
+
781
+ currentExtensions[5] = (fraction) => {
782
+ // probably not sufficiently accurate
783
+ return fraction[1] * Math.exp(fraction[0] * Math.log(2))
784
+ };
785
+
786
+ // the registration of the record definition extension
787
+ const recordDefinition = (definition) => {
788
+ let id = definition[0] - 0xe000;
789
+ let structure = definition[1];
790
+ let existingStructure = currentStructures[id];
791
+ if (existingStructure && existingStructure.isShared) {
792
+ (currentStructures.restoreStructures || (currentStructures.restoreStructures = []))[id] = existingStructure;
793
+ }
794
+ currentStructures[id] = structure;
795
+
796
+ structure.read = createStructureReader(structure);
797
+ let object = {};
798
+ if (currentDecoder.keyMap) for (let i = 2,l = definition.length; i < l; i++) {
799
+ let key = currentDecoder.decodeKey(structure[i - 2]);
800
+ object[key] = definition[i];
801
+ }
802
+ else for (let i = 2,l = definition.length; i < l; i++) {
803
+ let key = structure[i - 2];
804
+ object[key] = definition[i];
805
+ }
806
+ return object
807
+ };
808
+ currentExtensions[LEGACY_RECORD_INLINE_ID] = recordDefinition;
809
+ currentExtensions[14] = (value) => {
810
+ if (bundledStrings)
811
+ return bundledStrings[0].slice(bundledStrings.position0, bundledStrings.position0 += value)
812
+ return new Tag(value, 14)
813
+ };
814
+ currentExtensions[15] = (value) => {
815
+ if (bundledStrings)
816
+ return bundledStrings[1].slice(bundledStrings.position1, bundledStrings.position1 += value)
817
+ return new Tag(value, 15)
818
+ };
819
+
820
+ currentExtensions[27] = (data) => { // http://cbor.schmorp.de/generic-object
821
+ return (glbl[data[0]] || Error)(data[1], data[2])
822
+ };
823
+ const packedTable = (read) => {
824
+ if (src[position++] != 0x84)
825
+ throw new Error('Packed values structure must be followed by a 4 element array')
826
+ let newPackedValues = read(); // packed values
827
+ packedValues = packedValues ? newPackedValues.concat(packedValues.slice(newPackedValues.length)) : newPackedValues;
828
+ packedValues.prefixes = read();
829
+ packedValues.suffixes = read();
830
+ return read() // read the rump
831
+ };
832
+ packedTable.handlesRead = true;
833
+ currentExtensions[51] = packedTable;
834
+
835
+ currentExtensions[PACKED_REFERENCE_TAG_ID] = (data) => { // packed reference
836
+ if (!packedValues) {
837
+ if (currentDecoder.getShared)
838
+ loadShared();
839
+ else
840
+ return new Tag(data, PACKED_REFERENCE_TAG_ID)
841
+ }
842
+ if (typeof data == 'number')
843
+ return packedValues[16 + (data >= 0 ? 2 * data : (-2 * data - 1))]
844
+ throw new Error('No support for non-integer packed references yet')
845
+ };
846
+ currentExtensions[25] = (id) => {
847
+ return stringRefs[id]
848
+ };
849
+ currentExtensions[256] = (read) => {
850
+ stringRefs = [];
851
+ try {
852
+ return read()
853
+ } finally {
854
+ stringRefs = null;
855
+ }
856
+ };
857
+ currentExtensions[256].handlesRead = true;
858
+
859
+ currentExtensions[28] = (read) => {
860
+ // shareable http://cbor.schmorp.de/value-sharing (for structured clones)
861
+ if (!referenceMap) {
862
+ referenceMap = new Map();
863
+ referenceMap.id = 0;
864
+ }
865
+ let id = referenceMap.id++;
866
+ let token = src[position];
867
+ let target;
868
+ // TODO: handle Maps, Sets, and other types that can cycle; this is complicated, because you potentially need to read
869
+ // ahead past references to record structure definitions
870
+ if ((token >> 5) == 4)
871
+ target = [];
872
+ else
873
+ target = {};
874
+
875
+ let refEntry = { target }; // a placeholder object
876
+ referenceMap.set(id, refEntry);
877
+ let targetProperties = read(); // read the next value as the target object to id
878
+ if (refEntry.used) // there is a cycle, so we have to assign properties to original target
879
+ return Object.assign(target, targetProperties)
880
+ refEntry.target = targetProperties; // the placeholder wasn't used, replace with the deserialized one
881
+ return targetProperties // no cycle, can just use the returned read object
882
+ };
883
+ currentExtensions[28].handlesRead = true;
884
+
885
+ currentExtensions[29] = (id) => {
886
+ // sharedref http://cbor.schmorp.de/value-sharing (for structured clones)
887
+ let refEntry = referenceMap.get(id);
888
+ refEntry.used = true;
889
+ return refEntry.target
890
+ };
891
+
892
+ currentExtensions[258] = (array) => new Set(array); // https://github.com/input-output-hk/cbor-sets-spec/blob/master/CBOR_SETS.md
893
+ (currentExtensions[259] = (read) => {
894
+ // https://github.com/shanewholloway/js-cbor-codec/blob/master/docs/CBOR-259-spec
895
+ // for decoding as a standard Map
896
+ if (currentDecoder.mapsAsObjects) {
897
+ currentDecoder.mapsAsObjects = false;
898
+ restoreMapsAsObject = true;
899
+ }
900
+ return read()
901
+ }).handlesRead = true;
902
+ function combine(a, b) {
903
+ if (typeof a === 'string')
904
+ return a + b
905
+ if (a instanceof Array)
906
+ return a.concat(b)
907
+ return Object.assign({}, a, b)
908
+ }
909
+ function getPackedValues() {
910
+ if (!packedValues) {
911
+ if (currentDecoder.getShared)
912
+ loadShared();
913
+ else
914
+ throw new Error('No packed values available')
915
+ }
916
+ return packedValues
917
+ }
918
+ const SHARED_DATA_TAG_ID = 0x53687264; // ascii 'Shrd'
919
+ currentExtensionRanges.push((tag, input) => {
920
+ if (tag >= 225 && tag <= 255)
921
+ return combine(getPackedValues().prefixes[tag - 224], input)
922
+ if (tag >= 28704 && tag <= 32767)
923
+ return combine(getPackedValues().prefixes[tag - 28672], input)
924
+ if (tag >= 1879052288 && tag <= 2147483647)
925
+ return combine(getPackedValues().prefixes[tag - 1879048192], input)
926
+ if (tag >= 216 && tag <= 223)
927
+ return combine(input, getPackedValues().suffixes[tag - 216])
928
+ if (tag >= 27647 && tag <= 28671)
929
+ return combine(input, getPackedValues().suffixes[tag - 27639])
930
+ if (tag >= 1811940352 && tag <= 1879048191)
931
+ return combine(input, getPackedValues().suffixes[tag - 1811939328])
932
+ 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)
933
+ return {
934
+ packedValues: packedValues,
935
+ structures: currentStructures.slice(0),
936
+ version: input,
937
+ }
938
+ }
939
+ if (tag == 55799) // self-descriptive CBOR tag, just return input value
940
+ return input
941
+ });
942
+
943
+ const isLittleEndianMachine = new Uint8Array(new Uint16Array([1]).buffer)[0] == 1;
944
+ const typedArrays = ['Uint8', 'Uint8Clamped', 'Uint16', 'Uint32', 'BigUint64','Int8', 'Int16', 'Int32', 'BigInt64', 'Float32', 'Float64'];
945
+ const typedArrayTags = [64, 68, 69, 70, 71, 72, 77, 78, 79, 85, 86];
946
+ for (let i = 0; i < typedArrays.length; i++) {
947
+ registerTypedArray(typedArrays[i], typedArrayTags[i]);
948
+ }
949
+ function registerTypedArray(typedArrayId, tag, littleEndian) {
950
+ let TypedArray = glbl[typedArrayId + 'Array'];
951
+ let bytesPerElement = TypedArray.BYTES_PER_ELEMENT;
952
+ for (let littleEndian = 0; littleEndian < 2; littleEndian++) {
953
+ if (!littleEndian && bytesPerElement == 1)
954
+ continue
955
+ let sizeShift = bytesPerElement == 2 ? 1 : bytesPerElement == 4 ? 2 : 3;
956
+ currentExtensions[littleEndian ? tag : (tag - 4)] = (bytesPerElement == 1 || littleEndian == isLittleEndianMachine) ? (buffer) => {
957
+ if (!TypedArray)
958
+ throw new Error('Could not find typed array for code ' + tag)
959
+ // we have to always slice/copy here to get a new ArrayBuffer that is word/byte aligned
960
+ return new TypedArray(Uint8Array.prototype.slice.call(buffer, 0).buffer)
961
+ } : buffer => {
962
+ if (!TypedArray)
963
+ throw new Error('Could not find typed array for code ' + tag)
964
+ let dv = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
965
+ let elements = buffer.length >> sizeShift;
966
+ let ta = new TypedArray(elements);
967
+ let method = dv['get' + typedArrayId];
968
+ for (let i = 0; i < elements; i++) {
969
+ ta[i] = method.call(dv, i << sizeShift, littleEndian);
970
+ }
971
+ return ta
972
+ };
973
+ }
974
+ }
975
+
976
+ function readBundleExt() {
977
+ let length = readJustLength();
978
+ let bundlePosition = position + read();
979
+ for (let i = 2; i < length; i++) {
980
+ // skip past bundles that were already read
981
+ let bundleLength = readJustLength(); // this will increment position, so must add to position afterwards
982
+ position += bundleLength;
983
+ }
984
+ let dataPosition = position;
985
+ position = bundlePosition;
986
+ bundledStrings = [readStringJS(readJustLength()), readStringJS(readJustLength())];
987
+ bundledStrings.position0 = 0;
988
+ bundledStrings.position1 = 0;
989
+ bundledStrings.postBundlePosition = position;
990
+ position = dataPosition;
991
+ return read()
992
+ }
993
+
994
+ function readJustLength() {
995
+ let token = src[position++] & 0x1f;
996
+ if (token > 0x17) {
997
+ switch (token) {
998
+ case 0x18:
999
+ token = src[position++];
1000
+ break
1001
+ case 0x19:
1002
+ token = dataView.getUint16(position);
1003
+ position += 2;
1004
+ break
1005
+ case 0x1a:
1006
+ token = dataView.getUint32(position);
1007
+ position += 4;
1008
+ break
1009
+ }
1010
+ }
1011
+ return token
1012
+ }
1013
+
1014
+ function loadShared() {
1015
+ if (currentDecoder.getShared) {
1016
+ let sharedData = saveState(() => {
1017
+ // save the state in case getShared modifies our buffer
1018
+ src = null;
1019
+ return currentDecoder.getShared()
1020
+ }) || {};
1021
+ let updatedStructures = sharedData.structures || [];
1022
+ currentDecoder.sharedVersion = sharedData.version;
1023
+ packedValues = currentDecoder.sharedValues = sharedData.packedValues;
1024
+ if (currentStructures === true)
1025
+ currentDecoder.structures = currentStructures = updatedStructures;
1026
+ else
1027
+ currentStructures.splice.apply(currentStructures, [0, updatedStructures.length].concat(updatedStructures));
1028
+ }
1029
+ }
1030
+
1031
+ function saveState(callback) {
1032
+ let savedSrcEnd = srcEnd;
1033
+ let savedPosition = position;
1034
+ let savedStringPosition = stringPosition;
1035
+ let savedSrcStringStart = srcStringStart;
1036
+ let savedSrcStringEnd = srcStringEnd;
1037
+ let savedSrcString = srcString;
1038
+ let savedStrings = strings;
1039
+ let savedReferenceMap = referenceMap;
1040
+ let savedBundledStrings = bundledStrings;
1041
+
1042
+ // TODO: We may need to revisit this if we do more external calls to user code (since it could be slow)
1043
+ let savedSrc = new Uint8Array(src.slice(0, srcEnd)); // we copy the data in case it changes while external data is processed
1044
+ let savedStructures = currentStructures;
1045
+ let savedDecoder = currentDecoder;
1046
+ let savedSequentialMode = sequentialMode;
1047
+ let value = callback();
1048
+ srcEnd = savedSrcEnd;
1049
+ position = savedPosition;
1050
+ stringPosition = savedStringPosition;
1051
+ srcStringStart = savedSrcStringStart;
1052
+ srcStringEnd = savedSrcStringEnd;
1053
+ srcString = savedSrcString;
1054
+ strings = savedStrings;
1055
+ referenceMap = savedReferenceMap;
1056
+ bundledStrings = savedBundledStrings;
1057
+ src = savedSrc;
1058
+ sequentialMode = savedSequentialMode;
1059
+ currentStructures = savedStructures;
1060
+ currentDecoder = savedDecoder;
1061
+ dataView = new DataView(src.buffer, src.byteOffset, src.byteLength);
1062
+ return value
1063
+ }
1064
+ function clearSource() {
1065
+ src = null;
1066
+ referenceMap = null;
1067
+ currentStructures = null;
1068
+ }
1069
+
1070
+ function addExtension(extension) {
1071
+ currentExtensions[extension.tag] = extension.decode;
1072
+ }
1073
+
1074
+ const mult10 = new Array(147); // this is a table matching binary exponents to the multiplier to determine significant digit rounding
1075
+ for (let i = 0; i < 256; i++) {
1076
+ mult10[i] = +('1e' + Math.floor(45.15 - i * 0.30103));
1077
+ }
1078
+ let defaultDecoder = new Decoder({ useRecords: false });
1079
+ const decode = defaultDecoder.decode;
1080
+ const decodeMultiple = defaultDecoder.decodeMultiple;
1081
+ const FLOAT32_OPTIONS = {
1082
+ NEVER: 0,
1083
+ ALWAYS: 1,
1084
+ DECIMAL_ROUND: 3,
1085
+ DECIMAL_FIT: 4
1086
+ };
1087
+ let f32Array = new Float32Array(1);
1088
+ let u8Array = new Uint8Array(f32Array.buffer, 0, 4);
1089
+ function roundFloat32(float32Number) {
1090
+ f32Array[0] = float32Number;
1091
+ let multiplier = mult10[((u8Array[3] & 0x7f) << 1) | (u8Array[2] >> 7)];
1092
+ return ((multiplier * float32Number + (float32Number > 0 ? 0.5 : -0.5)) >> 0) / multiplier
1086
1093
  }
1087
1094
 
1088
1095
  let textEncoder;