msgpackr 1.6.0 → 1.7.0-alpha1

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