msgpackr 1.6.1 → 1.6.3

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