msgpackr 1.6.1 → 1.7.0-alpha2

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