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/dist/index.js +1954 -1919
- package/dist/index.js.map +1 -0
- package/dist/index.min.js +68 -67
- package/dist/index.min.js.map +1 -0
- package/dist/node.cjs +2266 -1984
- package/dist/node.cjs.map +1 -0
- package/dist/str.cjs +100 -0
- package/dist/test.js +2882 -674
- package/dist/test.js.map +1 -0
- package/index.d.ts +23 -12
- package/node-index.js +24 -23
- package/pack.js +957 -933
- package/package.json +83 -83
- package/rollup.config.js +7 -3
- package/struct.js +262 -0
- package/unpack.d.ts +52 -50
- package/unpack.js +1078 -1053
package/pack.js
CHANGED
|
@@ -1,933 +1,957 @@
|
|
|
1
|
-
"use strict"
|
|
2
|
-
import { Unpackr, mult10, C1Type, typedArrays, addExtension as unpackAddExtension } from './unpack.js'
|
|
3
|
-
let textEncoder
|
|
4
|
-
try {
|
|
5
|
-
textEncoder = new TextEncoder()
|
|
6
|
-
} catch (error) {}
|
|
7
|
-
let extensions, extensionClasses
|
|
8
|
-
const hasNodeBuffer = typeof Buffer !== 'undefined'
|
|
9
|
-
const ByteArrayAllocate = hasNodeBuffer ?
|
|
10
|
-
function(length) { return Buffer.allocUnsafeSlow(length) } : Uint8Array
|
|
11
|
-
const ByteArray = hasNodeBuffer ? Buffer : Uint8Array
|
|
12
|
-
const MAX_BUFFER_SIZE = hasNodeBuffer ? 0x100000000 : 0x7fd00000
|
|
13
|
-
let target, keysTarget
|
|
14
|
-
let targetView
|
|
15
|
-
let position = 0
|
|
16
|
-
let safeEnd
|
|
17
|
-
let bundledStrings = null
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
export
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
let
|
|
27
|
-
let
|
|
28
|
-
let
|
|
29
|
-
let
|
|
30
|
-
let
|
|
31
|
-
let
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
let
|
|
43
|
-
let
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
let
|
|
59
|
-
let
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
let
|
|
65
|
-
let
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
bundledStrings
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
if (
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
if (
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
target
|
|
199
|
-
|
|
200
|
-
position
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
extStart
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
headerSize =
|
|
227
|
-
} else {
|
|
228
|
-
headerSize =
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
target[strPosition++] = c1 >> 12 |
|
|
255
|
-
target[strPosition++] = c1 >> 6 & 0x3f | 0x80
|
|
256
|
-
target[strPosition++] = c1 & 0x3f | 0x80
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
target[position++] =
|
|
299
|
-
target[position++] = value
|
|
300
|
-
} else {
|
|
301
|
-
target[position++] =
|
|
302
|
-
|
|
303
|
-
position
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
position
|
|
315
|
-
} else {
|
|
316
|
-
target[position++] =
|
|
317
|
-
targetView.
|
|
318
|
-
position +=
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
target[position++] =
|
|
368
|
-
} else {
|
|
369
|
-
target[position++] =
|
|
370
|
-
|
|
371
|
-
position
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
target[position++] =
|
|
384
|
-
} else {
|
|
385
|
-
target[position++] =
|
|
386
|
-
|
|
387
|
-
position
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
let
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
//
|
|
454
|
-
target[position++] =
|
|
455
|
-
targetView.
|
|
456
|
-
} else {
|
|
457
|
-
//
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
target[position++] =
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
target[position++] =
|
|
491
|
-
} else {
|
|
492
|
-
target[position++] =
|
|
493
|
-
|
|
494
|
-
position
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
if (recordId
|
|
621
|
-
recordId = sharedLimitId
|
|
622
|
-
structures.
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
target[position++] =
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
target[position++] =
|
|
647
|
-
target[position++] =
|
|
648
|
-
target[position++] =
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
target
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
}
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
target
|
|
735
|
-
target[position++] =
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
target
|
|
741
|
-
target[position++] =
|
|
742
|
-
|
|
743
|
-
targetView.
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
target
|
|
752
|
-
target[position++] =
|
|
753
|
-
target[position++] =
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
target[position++] =
|
|
772
|
-
target[position++] =
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
if (this.moreTypes)
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
}
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
position
|
|
815
|
-
}
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
target
|
|
826
|
-
target[position++] =
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
target
|
|
831
|
-
target[position++] =
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
1
|
+
"use strict"
|
|
2
|
+
import { Unpackr, mult10, C1Type, typedArrays, addExtension as unpackAddExtension } from './unpack.js'
|
|
3
|
+
let textEncoder
|
|
4
|
+
try {
|
|
5
|
+
textEncoder = new TextEncoder()
|
|
6
|
+
} catch (error) {}
|
|
7
|
+
let extensions, extensionClasses
|
|
8
|
+
const hasNodeBuffer = typeof Buffer !== 'undefined'
|
|
9
|
+
const ByteArrayAllocate = hasNodeBuffer ?
|
|
10
|
+
function(length) { return Buffer.allocUnsafeSlow(length) } : Uint8Array
|
|
11
|
+
const ByteArray = hasNodeBuffer ? Buffer : Uint8Array
|
|
12
|
+
const MAX_BUFFER_SIZE = hasNodeBuffer ? 0x100000000 : 0x7fd00000
|
|
13
|
+
let target, keysTarget
|
|
14
|
+
let targetView
|
|
15
|
+
let position = 0
|
|
16
|
+
let safeEnd
|
|
17
|
+
let bundledStrings = null
|
|
18
|
+
let writeStructSlots
|
|
19
|
+
const MAX_BUNDLE_SIZE = 0xf000
|
|
20
|
+
const hasNonLatin = /[\u0080-\uFFFF]/
|
|
21
|
+
export const RECORD_SYMBOL = Symbol('record-id')
|
|
22
|
+
export class Packr extends Unpackr {
|
|
23
|
+
constructor(options) {
|
|
24
|
+
super(options)
|
|
25
|
+
this.offset = 0
|
|
26
|
+
let typeBuffer
|
|
27
|
+
let start
|
|
28
|
+
let hasSharedUpdate
|
|
29
|
+
let structures
|
|
30
|
+
let referenceMap
|
|
31
|
+
let lastSharedStructuresLength = 0
|
|
32
|
+
let encodeUtf8 = ByteArray.prototype.utf8Write ? function(string, position) {
|
|
33
|
+
return target.utf8Write(string, position, 0xffffffff)
|
|
34
|
+
} : (textEncoder && textEncoder.encodeInto) ?
|
|
35
|
+
function(string, position) {
|
|
36
|
+
return textEncoder.encodeInto(string, target.subarray(position)).written
|
|
37
|
+
} : false
|
|
38
|
+
|
|
39
|
+
let packr = this
|
|
40
|
+
if (!options)
|
|
41
|
+
options = {}
|
|
42
|
+
let isSequential = options && options.sequential
|
|
43
|
+
let hasSharedStructures = options.structures || options.saveStructures
|
|
44
|
+
let maxSharedStructures = options.maxSharedStructures
|
|
45
|
+
if (maxSharedStructures == null)
|
|
46
|
+
maxSharedStructures = hasSharedStructures ? 32 : 0
|
|
47
|
+
if (maxSharedStructures > 8160)
|
|
48
|
+
throw new Error('Maximum maxSharedStructure is 8160')
|
|
49
|
+
if (options.structuredClone && options.moreTypes == undefined) {
|
|
50
|
+
options.moreTypes = true
|
|
51
|
+
}
|
|
52
|
+
let maxOwnStructures = options.maxOwnStructures
|
|
53
|
+
if (maxOwnStructures == null)
|
|
54
|
+
maxOwnStructures = hasSharedStructures ? 32 : 64
|
|
55
|
+
if (!this.structures && options.useRecords != false)
|
|
56
|
+
this.structures = []
|
|
57
|
+
// two byte record ids for shared structures
|
|
58
|
+
let useTwoByteRecords = maxSharedStructures > 32 || (maxOwnStructures + maxSharedStructures > 64)
|
|
59
|
+
let sharedLimitId = maxSharedStructures + 0x40
|
|
60
|
+
let maxStructureId = maxSharedStructures + maxOwnStructures + 0x40
|
|
61
|
+
if (maxStructureId > 8256) {
|
|
62
|
+
throw new Error('Maximum maxSharedStructure + maxOwnStructure is 8192')
|
|
63
|
+
}
|
|
64
|
+
let recordIdsToRemove = []
|
|
65
|
+
let transitionsCount = 0
|
|
66
|
+
let serializationsSinceTransitionRebuild = 0
|
|
67
|
+
|
|
68
|
+
this.pack = this.encode = function(value, encodeOptions) {
|
|
69
|
+
if (!target) {
|
|
70
|
+
target = new ByteArrayAllocate(8192)
|
|
71
|
+
targetView = target.dataView = new DataView(target.buffer, 0, 8192)
|
|
72
|
+
position = 0
|
|
73
|
+
}
|
|
74
|
+
safeEnd = target.length - 10
|
|
75
|
+
if (safeEnd - position < 0x800) {
|
|
76
|
+
// don't start too close to the end,
|
|
77
|
+
target = new ByteArrayAllocate(target.length)
|
|
78
|
+
targetView = target.dataView = new DataView(target.buffer, 0, target.length)
|
|
79
|
+
safeEnd = target.length - 10
|
|
80
|
+
position = 0
|
|
81
|
+
} else
|
|
82
|
+
position = (position + 7) & 0x7ffffff8 // Word align to make any future copying of this buffer faster
|
|
83
|
+
start = position
|
|
84
|
+
referenceMap = packr.structuredClone ? new Map() : null
|
|
85
|
+
if (packr.bundleStrings && typeof value !== 'string') {
|
|
86
|
+
bundledStrings = []
|
|
87
|
+
bundledStrings.size = Infinity // force a new bundle start on first string
|
|
88
|
+
} else
|
|
89
|
+
bundledStrings = null
|
|
90
|
+
structures = packr.structures
|
|
91
|
+
if (structures) {
|
|
92
|
+
if (structures.uninitialized)
|
|
93
|
+
structures = packr._mergeStructures(packr.getStructures())
|
|
94
|
+
let sharedLength = structures.sharedLength || 0
|
|
95
|
+
if (sharedLength > maxSharedStructures) {
|
|
96
|
+
//if (maxSharedStructures <= 32 && structures.sharedLength > 32) // TODO: could support this, but would need to update the limit ids
|
|
97
|
+
throw new Error('Shared structures is larger than maximum shared structures, try increasing maxSharedStructures to ' + structures.sharedLength)
|
|
98
|
+
}
|
|
99
|
+
if (!structures.transitions) {
|
|
100
|
+
// rebuild our structure transitions
|
|
101
|
+
structures.transitions = Object.create(null)
|
|
102
|
+
for (let i = 0; i < sharedLength; i++) {
|
|
103
|
+
let keys = structures[i]
|
|
104
|
+
if (!keys)
|
|
105
|
+
continue
|
|
106
|
+
let nextTransition, transition = structures.transitions
|
|
107
|
+
for (let j = 0, l = keys.length; j < l; j++) {
|
|
108
|
+
let key = keys[j]
|
|
109
|
+
nextTransition = transition[key]
|
|
110
|
+
if (!nextTransition) {
|
|
111
|
+
nextTransition = transition[key] = Object.create(null)
|
|
112
|
+
}
|
|
113
|
+
transition = nextTransition
|
|
114
|
+
}
|
|
115
|
+
transition[RECORD_SYMBOL] = i + 0x40
|
|
116
|
+
}
|
|
117
|
+
lastSharedStructuresLength = sharedLength
|
|
118
|
+
}
|
|
119
|
+
if (!isSequential) {
|
|
120
|
+
structures.nextId = sharedLength + 0x40
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (hasSharedUpdate)
|
|
124
|
+
hasSharedUpdate = false
|
|
125
|
+
try {
|
|
126
|
+
if (packr.randomAccessStructure && value.constructor && value.constructor === Object)
|
|
127
|
+
writeStruct(value);
|
|
128
|
+
else
|
|
129
|
+
pack(value)
|
|
130
|
+
if (bundledStrings) {
|
|
131
|
+
writeBundles(start, pack)
|
|
132
|
+
}
|
|
133
|
+
packr.offset = position // update the offset so next serialization doesn't write over our buffer, but can continue writing to same buffer sequentially
|
|
134
|
+
if (referenceMap && referenceMap.idsToInsert) {
|
|
135
|
+
position += referenceMap.idsToInsert.length * 6
|
|
136
|
+
if (position > safeEnd)
|
|
137
|
+
makeRoom(position)
|
|
138
|
+
packr.offset = position
|
|
139
|
+
let serialized = insertIds(target.subarray(start, position), referenceMap.idsToInsert)
|
|
140
|
+
referenceMap = null
|
|
141
|
+
return serialized
|
|
142
|
+
}
|
|
143
|
+
if (encodeOptions & REUSE_BUFFER_MODE) {
|
|
144
|
+
target.start = start
|
|
145
|
+
target.end = position
|
|
146
|
+
return target
|
|
147
|
+
}
|
|
148
|
+
return target.subarray(start, position) // position can change if we call pack again in saveStructures, so we get the buffer now
|
|
149
|
+
} finally {
|
|
150
|
+
if (structures) {
|
|
151
|
+
if (serializationsSinceTransitionRebuild < 10)
|
|
152
|
+
serializationsSinceTransitionRebuild++
|
|
153
|
+
let sharedLength = structures.sharedLength || maxSharedStructures
|
|
154
|
+
if (structures.length > sharedLength)
|
|
155
|
+
structures.length = sharedLength
|
|
156
|
+
if (transitionsCount > 10000) {
|
|
157
|
+
// force a rebuild occasionally after a lot of transitions so it can get cleaned up
|
|
158
|
+
structures.transitions = null
|
|
159
|
+
serializationsSinceTransitionRebuild = 0
|
|
160
|
+
transitionsCount = 0
|
|
161
|
+
if (recordIdsToRemove.length > 0)
|
|
162
|
+
recordIdsToRemove = []
|
|
163
|
+
} else if (recordIdsToRemove.length > 0 && !isSequential) {
|
|
164
|
+
for (let i = 0, l = recordIdsToRemove.length; i < l; i++) {
|
|
165
|
+
recordIdsToRemove[i][RECORD_SYMBOL] = 0
|
|
166
|
+
}
|
|
167
|
+
recordIdsToRemove = []
|
|
168
|
+
}
|
|
169
|
+
if (hasSharedUpdate && packr.saveStructures) {
|
|
170
|
+
// we can't rely on start/end with REUSE_BUFFER_MODE since they will (probably) change when we save
|
|
171
|
+
let returnBuffer = target.subarray(start, position)
|
|
172
|
+
if (packr.saveStructures(structures, lastSharedStructuresLength) === false) {
|
|
173
|
+
// get updated structures and try again if the update failed
|
|
174
|
+
packr._mergeStructures(packr.getStructures())
|
|
175
|
+
return packr.pack(value)
|
|
176
|
+
}
|
|
177
|
+
lastSharedStructuresLength = sharedLength
|
|
178
|
+
return returnBuffer
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
if (encodeOptions & RESET_BUFFER_MODE)
|
|
182
|
+
position = start
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
const pack = (value) => {
|
|
186
|
+
if (position > safeEnd)
|
|
187
|
+
target = makeRoom(position)
|
|
188
|
+
|
|
189
|
+
var type = typeof value
|
|
190
|
+
var length
|
|
191
|
+
if (type === 'string') {
|
|
192
|
+
let strLength = value.length
|
|
193
|
+
if (bundledStrings && strLength >= 4 && strLength < 0x1000) {
|
|
194
|
+
if ((bundledStrings.size += strLength) > MAX_BUNDLE_SIZE) {
|
|
195
|
+
let extStart
|
|
196
|
+
let maxBytes = (bundledStrings[0] ? bundledStrings[0].length * 3 + bundledStrings[1].length : 0) + 10
|
|
197
|
+
if (position + maxBytes > safeEnd)
|
|
198
|
+
target = makeRoom(position + maxBytes)
|
|
199
|
+
if (bundledStrings.position) { // here we use the 0x62 extension to write the last bundle and reserve sapce for the reference pointer to the next/current bundle
|
|
200
|
+
target[position] = 0xc8 // ext 16
|
|
201
|
+
position += 3 // reserve for the writing bundle size
|
|
202
|
+
target[position++] = 0x62 // 'b'
|
|
203
|
+
extStart = position - start
|
|
204
|
+
position += 4 // reserve for writing bundle reference
|
|
205
|
+
writeBundles(start, pack) // write the last bundles
|
|
206
|
+
targetView.setUint16(extStart + start - 3, position - start - extStart)
|
|
207
|
+
} else { // here we use the 0x62 extension just to reserve the space for the reference pointer to the bundle (will be updated once the bundle is written)
|
|
208
|
+
target[position++] = 0xd6 // fixext 4
|
|
209
|
+
target[position++] = 0x62 // 'b'
|
|
210
|
+
extStart = position - start
|
|
211
|
+
position += 4 // reserve for writing bundle reference
|
|
212
|
+
}
|
|
213
|
+
bundledStrings = ['', ''] // create new ones
|
|
214
|
+
bundledStrings.size = 0
|
|
215
|
+
bundledStrings.position = extStart
|
|
216
|
+
}
|
|
217
|
+
let twoByte = hasNonLatin.test(value)
|
|
218
|
+
bundledStrings[twoByte ? 0 : 1] += value
|
|
219
|
+
target[position++] = 0xc1
|
|
220
|
+
pack(twoByte ? -strLength : strLength);
|
|
221
|
+
return
|
|
222
|
+
}
|
|
223
|
+
let headerSize
|
|
224
|
+
// first we estimate the header size, so we can write to the correct location
|
|
225
|
+
if (strLength < 0x20) {
|
|
226
|
+
headerSize = 1
|
|
227
|
+
} else if (strLength < 0x100) {
|
|
228
|
+
headerSize = 2
|
|
229
|
+
} else if (strLength < 0x10000) {
|
|
230
|
+
headerSize = 3
|
|
231
|
+
} else {
|
|
232
|
+
headerSize = 5
|
|
233
|
+
}
|
|
234
|
+
let maxBytes = strLength * 3
|
|
235
|
+
if (position + maxBytes > safeEnd)
|
|
236
|
+
target = makeRoom(position + maxBytes)
|
|
237
|
+
|
|
238
|
+
if (strLength < 0x40 || !encodeUtf8) {
|
|
239
|
+
let i, c1, c2, strPosition = position + headerSize
|
|
240
|
+
for (i = 0; i < strLength; i++) {
|
|
241
|
+
c1 = value.charCodeAt(i)
|
|
242
|
+
if (c1 < 0x80) {
|
|
243
|
+
target[strPosition++] = c1
|
|
244
|
+
} else if (c1 < 0x800) {
|
|
245
|
+
target[strPosition++] = c1 >> 6 | 0xc0
|
|
246
|
+
target[strPosition++] = c1 & 0x3f | 0x80
|
|
247
|
+
} else if (
|
|
248
|
+
(c1 & 0xfc00) === 0xd800 &&
|
|
249
|
+
((c2 = value.charCodeAt(i + 1)) & 0xfc00) === 0xdc00
|
|
250
|
+
) {
|
|
251
|
+
c1 = 0x10000 + ((c1 & 0x03ff) << 10) + (c2 & 0x03ff)
|
|
252
|
+
i++
|
|
253
|
+
target[strPosition++] = c1 >> 18 | 0xf0
|
|
254
|
+
target[strPosition++] = c1 >> 12 & 0x3f | 0x80
|
|
255
|
+
target[strPosition++] = c1 >> 6 & 0x3f | 0x80
|
|
256
|
+
target[strPosition++] = c1 & 0x3f | 0x80
|
|
257
|
+
} else {
|
|
258
|
+
target[strPosition++] = c1 >> 12 | 0xe0
|
|
259
|
+
target[strPosition++] = c1 >> 6 & 0x3f | 0x80
|
|
260
|
+
target[strPosition++] = c1 & 0x3f | 0x80
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
length = strPosition - position - headerSize
|
|
264
|
+
} else {
|
|
265
|
+
length = encodeUtf8(value, position + headerSize)
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
if (length < 0x20) {
|
|
269
|
+
target[position++] = 0xa0 | length
|
|
270
|
+
} else if (length < 0x100) {
|
|
271
|
+
if (headerSize < 2) {
|
|
272
|
+
target.copyWithin(position + 2, position + 1, position + 1 + length)
|
|
273
|
+
}
|
|
274
|
+
target[position++] = 0xd9
|
|
275
|
+
target[position++] = length
|
|
276
|
+
} else if (length < 0x10000) {
|
|
277
|
+
if (headerSize < 3) {
|
|
278
|
+
target.copyWithin(position + 3, position + 2, position + 2 + length)
|
|
279
|
+
}
|
|
280
|
+
target[position++] = 0xda
|
|
281
|
+
target[position++] = length >> 8
|
|
282
|
+
target[position++] = length & 0xff
|
|
283
|
+
} else {
|
|
284
|
+
if (headerSize < 5) {
|
|
285
|
+
target.copyWithin(position + 5, position + 3, position + 3 + length)
|
|
286
|
+
}
|
|
287
|
+
target[position++] = 0xdb
|
|
288
|
+
targetView.setUint32(position, length)
|
|
289
|
+
position += 4
|
|
290
|
+
}
|
|
291
|
+
position += length
|
|
292
|
+
} else if (type === 'number') {
|
|
293
|
+
if (value >>> 0 === value) {// positive integer, 32-bit or less
|
|
294
|
+
// positive uint
|
|
295
|
+
if (value < 0x40 || (value < 0x80 && this.useRecords === false)) {
|
|
296
|
+
target[position++] = value
|
|
297
|
+
} else if (value < 0x100) {
|
|
298
|
+
target[position++] = 0xcc
|
|
299
|
+
target[position++] = value
|
|
300
|
+
} else if (value < 0x10000) {
|
|
301
|
+
target[position++] = 0xcd
|
|
302
|
+
target[position++] = value >> 8
|
|
303
|
+
target[position++] = value & 0xff
|
|
304
|
+
} else {
|
|
305
|
+
target[position++] = 0xce
|
|
306
|
+
targetView.setUint32(position, value)
|
|
307
|
+
position += 4
|
|
308
|
+
}
|
|
309
|
+
} else if (value >> 0 === value) { // negative integer
|
|
310
|
+
if (value >= -0x20) {
|
|
311
|
+
target[position++] = 0x100 + value
|
|
312
|
+
} else if (value >= -0x80) {
|
|
313
|
+
target[position++] = 0xd0
|
|
314
|
+
target[position++] = value + 0x100
|
|
315
|
+
} else if (value >= -0x8000) {
|
|
316
|
+
target[position++] = 0xd1
|
|
317
|
+
targetView.setInt16(position, value)
|
|
318
|
+
position += 2
|
|
319
|
+
} else {
|
|
320
|
+
target[position++] = 0xd2
|
|
321
|
+
targetView.setInt32(position, value)
|
|
322
|
+
position += 4
|
|
323
|
+
}
|
|
324
|
+
} else {
|
|
325
|
+
let useFloat32
|
|
326
|
+
if ((useFloat32 = this.useFloat32) > 0 && value < 0x100000000 && value >= -0x80000000) {
|
|
327
|
+
target[position++] = 0xca
|
|
328
|
+
targetView.setFloat32(position, value)
|
|
329
|
+
let xShifted
|
|
330
|
+
if (useFloat32 < 4 ||
|
|
331
|
+
// this checks for rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
|
|
332
|
+
((xShifted = value * mult10[((target[position] & 0x7f) << 1) | (target[position + 1] >> 7)]) >> 0) === xShifted) {
|
|
333
|
+
position += 4
|
|
334
|
+
return
|
|
335
|
+
} else
|
|
336
|
+
position-- // move back into position for writing a double
|
|
337
|
+
}
|
|
338
|
+
target[position++] = 0xcb
|
|
339
|
+
targetView.setFloat64(position, value)
|
|
340
|
+
position += 8
|
|
341
|
+
}
|
|
342
|
+
} else if (type === 'object') {
|
|
343
|
+
if (!value)
|
|
344
|
+
target[position++] = 0xc0
|
|
345
|
+
else {
|
|
346
|
+
if (referenceMap) {
|
|
347
|
+
let referee = referenceMap.get(value)
|
|
348
|
+
if (referee) {
|
|
349
|
+
if (!referee.id) {
|
|
350
|
+
let idsToInsert = referenceMap.idsToInsert || (referenceMap.idsToInsert = [])
|
|
351
|
+
referee.id = idsToInsert.push(referee)
|
|
352
|
+
}
|
|
353
|
+
target[position++] = 0xd6 // fixext 4
|
|
354
|
+
target[position++] = 0x70 // "p" for pointer
|
|
355
|
+
targetView.setUint32(position, referee.id)
|
|
356
|
+
position += 4
|
|
357
|
+
return
|
|
358
|
+
} else
|
|
359
|
+
referenceMap.set(value, { offset: position - start })
|
|
360
|
+
}
|
|
361
|
+
let constructor = value.constructor
|
|
362
|
+
if (constructor === Object) {
|
|
363
|
+
writeObject(value, true)
|
|
364
|
+
} else if (constructor === Array) {
|
|
365
|
+
length = value.length
|
|
366
|
+
if (length < 0x10) {
|
|
367
|
+
target[position++] = 0x90 | length
|
|
368
|
+
} else if (length < 0x10000) {
|
|
369
|
+
target[position++] = 0xdc
|
|
370
|
+
target[position++] = length >> 8
|
|
371
|
+
target[position++] = length & 0xff
|
|
372
|
+
} else {
|
|
373
|
+
target[position++] = 0xdd
|
|
374
|
+
targetView.setUint32(position, length)
|
|
375
|
+
position += 4
|
|
376
|
+
}
|
|
377
|
+
for (let i = 0; i < length; i++) {
|
|
378
|
+
pack(value[i])
|
|
379
|
+
}
|
|
380
|
+
} else if (constructor === Map) {
|
|
381
|
+
length = value.size
|
|
382
|
+
if (length < 0x10) {
|
|
383
|
+
target[position++] = 0x80 | length
|
|
384
|
+
} else if (length < 0x10000) {
|
|
385
|
+
target[position++] = 0xde
|
|
386
|
+
target[position++] = length >> 8
|
|
387
|
+
target[position++] = length & 0xff
|
|
388
|
+
} else {
|
|
389
|
+
target[position++] = 0xdf
|
|
390
|
+
targetView.setUint32(position, length)
|
|
391
|
+
position += 4
|
|
392
|
+
}
|
|
393
|
+
for (let [ key, entryValue ] of value) {
|
|
394
|
+
pack(key)
|
|
395
|
+
pack(entryValue)
|
|
396
|
+
}
|
|
397
|
+
} else {
|
|
398
|
+
for (let i = 0, l = extensions.length; i < l; i++) {
|
|
399
|
+
let extensionClass = extensionClasses[i]
|
|
400
|
+
if (value instanceof extensionClass) {
|
|
401
|
+
let extension = extensions[i]
|
|
402
|
+
if (extension.write) {
|
|
403
|
+
if (extension.type) {
|
|
404
|
+
target[position++] = 0xd4 // one byte "tag" extension
|
|
405
|
+
target[position++] = extension.type
|
|
406
|
+
target[position++] = 0
|
|
407
|
+
}
|
|
408
|
+
pack(extension.write.call(this, value))
|
|
409
|
+
return
|
|
410
|
+
}
|
|
411
|
+
let currentTarget = target
|
|
412
|
+
let currentTargetView = targetView
|
|
413
|
+
let currentPosition = position
|
|
414
|
+
target = null
|
|
415
|
+
let result
|
|
416
|
+
try {
|
|
417
|
+
result = extension.pack.call(this, value, (size) => {
|
|
418
|
+
// restore target and use it
|
|
419
|
+
target = currentTarget
|
|
420
|
+
currentTarget = null
|
|
421
|
+
position += size
|
|
422
|
+
if (position > safeEnd)
|
|
423
|
+
makeRoom(position)
|
|
424
|
+
return {
|
|
425
|
+
target, targetView, position: position - size
|
|
426
|
+
}
|
|
427
|
+
}, pack)
|
|
428
|
+
} finally {
|
|
429
|
+
// restore current target information (unless already restored)
|
|
430
|
+
if (currentTarget) {
|
|
431
|
+
target = currentTarget
|
|
432
|
+
targetView = currentTargetView
|
|
433
|
+
position = currentPosition
|
|
434
|
+
safeEnd = target.length - 10
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
if (result) {
|
|
438
|
+
if (result.length + position > safeEnd)
|
|
439
|
+
makeRoom(result.length + position)
|
|
440
|
+
position = writeExtensionData(result, target, position, extension.type)
|
|
441
|
+
}
|
|
442
|
+
return
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
// no extension found, write as object
|
|
446
|
+
writeObject(value, !value.hasOwnProperty) // if it doesn't have hasOwnProperty, don't do hasOwnProperty checks
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
} else if (type === 'boolean') {
|
|
450
|
+
target[position++] = value ? 0xc3 : 0xc2
|
|
451
|
+
} else if (type === 'bigint') {
|
|
452
|
+
if (value < (BigInt(1)<<BigInt(63)) && value >= -(BigInt(1)<<BigInt(63))) {
|
|
453
|
+
// use a signed int as long as it fits
|
|
454
|
+
target[position++] = 0xd3
|
|
455
|
+
targetView.setBigInt64(position, value)
|
|
456
|
+
} else if (value < (BigInt(1)<<BigInt(64)) && value > 0) {
|
|
457
|
+
// if we can fit an unsigned int, use that
|
|
458
|
+
target[position++] = 0xcf
|
|
459
|
+
targetView.setBigUint64(position, value)
|
|
460
|
+
} else {
|
|
461
|
+
// overflow
|
|
462
|
+
if (this.largeBigIntToFloat) {
|
|
463
|
+
target[position++] = 0xcb
|
|
464
|
+
targetView.setFloat64(position, Number(value))
|
|
465
|
+
} else {
|
|
466
|
+
throw new RangeError(value + ' was too large to fit in MessagePack 64-bit integer format, set largeBigIntToFloat to convert to float-64')
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
position += 8
|
|
470
|
+
} else if (type === 'undefined') {
|
|
471
|
+
if (this.encodeUndefinedAsNil)
|
|
472
|
+
target[position++] = 0xc0
|
|
473
|
+
else {
|
|
474
|
+
target[position++] = 0xd4 // a number of implementations use fixext1 with type 0, data 0 to denote undefined, so we follow suite
|
|
475
|
+
target[position++] = 0
|
|
476
|
+
target[position++] = 0
|
|
477
|
+
}
|
|
478
|
+
} else if (type === 'function') {
|
|
479
|
+
pack(this.writeFunction && this.writeFunction()) // if there is a writeFunction, use it, otherwise just encode as undefined
|
|
480
|
+
} else {
|
|
481
|
+
throw new Error('Unknown type: ' + type)
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
const writeObject = this.useRecords === false ? this.variableMapSize ? (object) => {
|
|
486
|
+
// this method is slightly slower, but generates "preferred serialization" (optimally small for smaller objects)
|
|
487
|
+
let keys = Object.keys(object)
|
|
488
|
+
let length = keys.length
|
|
489
|
+
if (length < 0x10) {
|
|
490
|
+
target[position++] = 0x80 | length
|
|
491
|
+
} else if (length < 0x10000) {
|
|
492
|
+
target[position++] = 0xde
|
|
493
|
+
target[position++] = length >> 8
|
|
494
|
+
target[position++] = length & 0xff
|
|
495
|
+
} else {
|
|
496
|
+
target[position++] = 0xdf
|
|
497
|
+
targetView.setUint32(position, length)
|
|
498
|
+
position += 4
|
|
499
|
+
}
|
|
500
|
+
let key
|
|
501
|
+
for (let i = 0; i < length; i++) {
|
|
502
|
+
pack(key = keys[i])
|
|
503
|
+
pack(object[key])
|
|
504
|
+
}
|
|
505
|
+
} :
|
|
506
|
+
(object, safePrototype) => {
|
|
507
|
+
target[position++] = 0xde // always using map 16, so we can preallocate and set the length afterwards
|
|
508
|
+
let objectOffset = position - start
|
|
509
|
+
position += 2
|
|
510
|
+
let size = 0
|
|
511
|
+
for (let key in object) {
|
|
512
|
+
if (safePrototype || object.hasOwnProperty(key)) {
|
|
513
|
+
pack(key)
|
|
514
|
+
pack(object[key])
|
|
515
|
+
size++
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
target[objectOffset++ + start] = size >> 8
|
|
519
|
+
target[objectOffset + start] = size & 0xff
|
|
520
|
+
} :
|
|
521
|
+
(options.progressiveRecords && !useTwoByteRecords) ? // this is about 2% faster for highly stable structures, since it only requires one for-in loop (but much more expensive when new structure needs to be written)
|
|
522
|
+
(object, safePrototype) => {
|
|
523
|
+
let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null))
|
|
524
|
+
let objectOffset = position++ - start
|
|
525
|
+
let wroteKeys
|
|
526
|
+
for (let key in object) {
|
|
527
|
+
if (safePrototype || object.hasOwnProperty(key)) {
|
|
528
|
+
nextTransition = transition[key]
|
|
529
|
+
if (nextTransition)
|
|
530
|
+
transition = nextTransition
|
|
531
|
+
else {
|
|
532
|
+
// record doesn't exist, create full new record and insert it
|
|
533
|
+
let keys = Object.keys(object)
|
|
534
|
+
let lastTransition = transition
|
|
535
|
+
transition = structures.transitions
|
|
536
|
+
let newTransitions = 0
|
|
537
|
+
for (let i = 0, l = keys.length; i < l; i++) {
|
|
538
|
+
let key = keys[i]
|
|
539
|
+
nextTransition = transition[key]
|
|
540
|
+
if (!nextTransition) {
|
|
541
|
+
nextTransition = transition[key] = Object.create(null)
|
|
542
|
+
newTransitions++
|
|
543
|
+
}
|
|
544
|
+
transition = nextTransition
|
|
545
|
+
}
|
|
546
|
+
if (objectOffset + start + 1 == position) {
|
|
547
|
+
// first key, so we don't need to insert, we can just write record directly
|
|
548
|
+
position--
|
|
549
|
+
newRecord(transition, keys, newTransitions)
|
|
550
|
+
} else // otherwise we need to insert the record, moving existing data after the record
|
|
551
|
+
insertNewRecord(transition, keys, objectOffset, newTransitions)
|
|
552
|
+
wroteKeys = true
|
|
553
|
+
transition = lastTransition[key]
|
|
554
|
+
}
|
|
555
|
+
pack(object[key])
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
if (!wroteKeys) {
|
|
559
|
+
let recordId = transition[RECORD_SYMBOL]
|
|
560
|
+
if (recordId)
|
|
561
|
+
target[objectOffset + start] = recordId
|
|
562
|
+
else
|
|
563
|
+
insertNewRecord(transition, Object.keys(object), objectOffset, 0)
|
|
564
|
+
}
|
|
565
|
+
} :
|
|
566
|
+
(object, safePrototype) => {
|
|
567
|
+
let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null))
|
|
568
|
+
let newTransitions = 0
|
|
569
|
+
for (let key in object) if (safePrototype || object.hasOwnProperty(key)) {
|
|
570
|
+
nextTransition = transition[key]
|
|
571
|
+
if (!nextTransition) {
|
|
572
|
+
nextTransition = transition[key] = Object.create(null)
|
|
573
|
+
newTransitions++
|
|
574
|
+
}
|
|
575
|
+
transition = nextTransition
|
|
576
|
+
}
|
|
577
|
+
let recordId = transition[RECORD_SYMBOL]
|
|
578
|
+
if (recordId) {
|
|
579
|
+
if (recordId >= 0x60 && useTwoByteRecords) {
|
|
580
|
+
target[position++] = ((recordId -= 0x60) & 0x1f) + 0x60
|
|
581
|
+
target[position++] = recordId >> 5
|
|
582
|
+
} else
|
|
583
|
+
target[position++] = recordId
|
|
584
|
+
} else {
|
|
585
|
+
newRecord(transition, transition.__keys__ || Object.keys(object), newTransitions)
|
|
586
|
+
}
|
|
587
|
+
// now write the values
|
|
588
|
+
for (let key in object)
|
|
589
|
+
if (safePrototype || object.hasOwnProperty(key))
|
|
590
|
+
pack(object[key])
|
|
591
|
+
}
|
|
592
|
+
const makeRoom = (end) => {
|
|
593
|
+
let newSize
|
|
594
|
+
if (end > 0x1000000) {
|
|
595
|
+
// special handling for really large buffers
|
|
596
|
+
if ((end - start) > MAX_BUFFER_SIZE)
|
|
597
|
+
throw new Error('Packed buffer would be larger than maximum buffer size')
|
|
598
|
+
newSize = Math.min(MAX_BUFFER_SIZE,
|
|
599
|
+
Math.round(Math.max((end - start) * (end > 0x4000000 ? 1.25 : 2), 0x400000) / 0x1000) * 0x1000)
|
|
600
|
+
} else // faster handling for smaller buffers
|
|
601
|
+
newSize = ((Math.max((end - start) << 2, target.length - 1) >> 12) + 1) << 12
|
|
602
|
+
let newBuffer = new ByteArrayAllocate(newSize)
|
|
603
|
+
targetView = newBuffer.dataView = new DataView(newBuffer.buffer, 0, newSize)
|
|
604
|
+
end = Math.min(end, target.length)
|
|
605
|
+
if (target.copy)
|
|
606
|
+
target.copy(newBuffer, 0, start, end)
|
|
607
|
+
else
|
|
608
|
+
newBuffer.set(target.slice(start, end))
|
|
609
|
+
position -= start
|
|
610
|
+
start = 0
|
|
611
|
+
safeEnd = newBuffer.length - 10
|
|
612
|
+
return target = newBuffer
|
|
613
|
+
}
|
|
614
|
+
const newRecord = (transition, keys, newTransitions) => {
|
|
615
|
+
let recordId = structures.nextId
|
|
616
|
+
if (!recordId)
|
|
617
|
+
recordId = 0x40
|
|
618
|
+
if (recordId < sharedLimitId && this.shouldShareStructure && !this.shouldShareStructure(keys)) {
|
|
619
|
+
recordId = structures.nextOwnId
|
|
620
|
+
if (!(recordId < maxStructureId))
|
|
621
|
+
recordId = sharedLimitId
|
|
622
|
+
structures.nextOwnId = recordId + 1
|
|
623
|
+
} else {
|
|
624
|
+
if (recordId >= maxStructureId)// cycle back around
|
|
625
|
+
recordId = sharedLimitId
|
|
626
|
+
structures.nextId = recordId + 1
|
|
627
|
+
}
|
|
628
|
+
let highByte = keys.highByte = recordId >= 0x60 && useTwoByteRecords ? (recordId - 0x60) >> 5 : -1
|
|
629
|
+
transition[RECORD_SYMBOL] = recordId
|
|
630
|
+
transition.__keys__ = keys
|
|
631
|
+
structures[recordId - 0x40] = keys
|
|
632
|
+
|
|
633
|
+
if (recordId < sharedLimitId) {
|
|
634
|
+
keys.isShared = true
|
|
635
|
+
structures.sharedLength = recordId - 0x3f
|
|
636
|
+
hasSharedUpdate = true
|
|
637
|
+
if (highByte >= 0) {
|
|
638
|
+
target[position++] = (recordId & 0x1f) + 0x60
|
|
639
|
+
target[position++] = highByte
|
|
640
|
+
} else {
|
|
641
|
+
target[position++] = recordId
|
|
642
|
+
}
|
|
643
|
+
} else {
|
|
644
|
+
if (highByte >= 0) {
|
|
645
|
+
target[position++] = 0xd5 // fixext 2
|
|
646
|
+
target[position++] = 0x72 // "r" record defintion extension type
|
|
647
|
+
target[position++] = (recordId & 0x1f) + 0x60
|
|
648
|
+
target[position++] = highByte
|
|
649
|
+
} else {
|
|
650
|
+
target[position++] = 0xd4 // fixext 1
|
|
651
|
+
target[position++] = 0x72 // "r" record defintion extension type
|
|
652
|
+
target[position++] = recordId
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
if (newTransitions)
|
|
656
|
+
transitionsCount += serializationsSinceTransitionRebuild * newTransitions
|
|
657
|
+
// record the removal of the id, we can maintain our shared structure
|
|
658
|
+
if (recordIdsToRemove.length >= maxOwnStructures)
|
|
659
|
+
recordIdsToRemove.shift()[RECORD_SYMBOL] = 0 // we are cycling back through, and have to remove old ones
|
|
660
|
+
recordIdsToRemove.push(transition)
|
|
661
|
+
pack(keys)
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
const insertNewRecord = (transition, keys, insertionOffset, newTransitions) => {
|
|
665
|
+
let mainTarget = target
|
|
666
|
+
let mainPosition = position
|
|
667
|
+
let mainSafeEnd = safeEnd
|
|
668
|
+
let mainStart = start
|
|
669
|
+
target = keysTarget
|
|
670
|
+
position = 0
|
|
671
|
+
start = 0
|
|
672
|
+
if (!target)
|
|
673
|
+
keysTarget = target = new ByteArrayAllocate(8192)
|
|
674
|
+
safeEnd = target.length - 10
|
|
675
|
+
newRecord(transition, keys, newTransitions)
|
|
676
|
+
keysTarget = target
|
|
677
|
+
let keysPosition = position
|
|
678
|
+
target = mainTarget
|
|
679
|
+
position = mainPosition
|
|
680
|
+
safeEnd = mainSafeEnd
|
|
681
|
+
start = mainStart
|
|
682
|
+
if (keysPosition > 1) {
|
|
683
|
+
let newEnd = position + keysPosition - 1
|
|
684
|
+
if (newEnd > safeEnd)
|
|
685
|
+
makeRoom(newEnd)
|
|
686
|
+
let insertionPosition = insertionOffset + start
|
|
687
|
+
target.copyWithin(insertionPosition + keysPosition, insertionPosition + 1, position)
|
|
688
|
+
target.set(keysTarget.slice(0, keysPosition), insertionPosition)
|
|
689
|
+
position = newEnd
|
|
690
|
+
} else {
|
|
691
|
+
target[insertionOffset + start] = keysTarget[0]
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
const writeStruct = (object, safePrototype) => {
|
|
695
|
+
let newPosition = writeStructSlots(object, target, position, structures, makeRoom, (value, newPosition) => {
|
|
696
|
+
position = newPosition;
|
|
697
|
+
if (start > 0) {
|
|
698
|
+
pack(value);
|
|
699
|
+
if (start == 0)
|
|
700
|
+
return { position, targetView }; // indicate the buffer was re-allocated
|
|
701
|
+
} else
|
|
702
|
+
pack(value);
|
|
703
|
+
return position;
|
|
704
|
+
})
|
|
705
|
+
if (newPosition === 0) // bail and go to a msgpack object
|
|
706
|
+
return writeObject(object, true);
|
|
707
|
+
position = newPosition;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
useBuffer(buffer) {
|
|
711
|
+
// this means we are finished using our own buffer and we can write over it safely
|
|
712
|
+
target = buffer
|
|
713
|
+
targetView = new DataView(target.buffer, target.byteOffset, target.byteLength)
|
|
714
|
+
position = 0
|
|
715
|
+
}
|
|
716
|
+
clearSharedData() {
|
|
717
|
+
if (this.structures)
|
|
718
|
+
this.structures = []
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
function copyBinary(source, target, targetOffset, offset, endOffset) {
|
|
723
|
+
while (offset < endOffset) {
|
|
724
|
+
target[targetOffset++] = source[offset++]
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
extensionClasses = [ Date, Set, Error, RegExp, ArrayBuffer, Object.getPrototypeOf(Uint8Array.prototype).constructor /*TypedArray*/, C1Type ]
|
|
729
|
+
extensions = [{
|
|
730
|
+
pack(date, allocateForWrite, pack) {
|
|
731
|
+
let seconds = date.getTime() / 1000
|
|
732
|
+
if ((this.useTimestamp32 || date.getMilliseconds() === 0) && seconds >= 0 && seconds < 0x100000000) {
|
|
733
|
+
// Timestamp 32
|
|
734
|
+
let { target, targetView, position} = allocateForWrite(6)
|
|
735
|
+
target[position++] = 0xd6
|
|
736
|
+
target[position++] = 0xff
|
|
737
|
+
targetView.setUint32(position, seconds)
|
|
738
|
+
} else if (seconds > 0 && seconds < 0x100000000) {
|
|
739
|
+
// Timestamp 64
|
|
740
|
+
let { target, targetView, position} = allocateForWrite(10)
|
|
741
|
+
target[position++] = 0xd7
|
|
742
|
+
target[position++] = 0xff
|
|
743
|
+
targetView.setUint32(position, date.getMilliseconds() * 4000000 + ((seconds / 1000 / 0x100000000) >> 0))
|
|
744
|
+
targetView.setUint32(position + 4, seconds)
|
|
745
|
+
} else if (isNaN(seconds)) {
|
|
746
|
+
if (this.onInvalidDate) {
|
|
747
|
+
allocateForWrite(0)
|
|
748
|
+
return pack(this.onInvalidDate())
|
|
749
|
+
}
|
|
750
|
+
// Intentionally invalid timestamp
|
|
751
|
+
let { target, targetView, position} = allocateForWrite(3)
|
|
752
|
+
target[position++] = 0xd4
|
|
753
|
+
target[position++] = 0xff
|
|
754
|
+
target[position++] = 0xff
|
|
755
|
+
} else {
|
|
756
|
+
// Timestamp 96
|
|
757
|
+
let { target, targetView, position} = allocateForWrite(15)
|
|
758
|
+
target[position++] = 0xc7
|
|
759
|
+
target[position++] = 12
|
|
760
|
+
target[position++] = 0xff
|
|
761
|
+
targetView.setUint32(position, date.getMilliseconds() * 1000000)
|
|
762
|
+
targetView.setBigInt64(position + 4, BigInt(Math.floor(seconds)))
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
}, {
|
|
766
|
+
pack(set, allocateForWrite, pack) {
|
|
767
|
+
let array = Array.from(set)
|
|
768
|
+
let { target, position} = allocateForWrite(this.moreTypes ? 3 : 0)
|
|
769
|
+
if (this.moreTypes) {
|
|
770
|
+
target[position++] = 0xd4
|
|
771
|
+
target[position++] = 0x73 // 's' for Set
|
|
772
|
+
target[position++] = 0
|
|
773
|
+
}
|
|
774
|
+
pack(array)
|
|
775
|
+
}
|
|
776
|
+
}, {
|
|
777
|
+
pack(error, allocateForWrite, pack) {
|
|
778
|
+
let { target, position} = allocateForWrite(this.moreTypes ? 3 : 0)
|
|
779
|
+
if (this.moreTypes) {
|
|
780
|
+
target[position++] = 0xd4
|
|
781
|
+
target[position++] = 0x65 // 'e' for error
|
|
782
|
+
target[position++] = 0
|
|
783
|
+
}
|
|
784
|
+
pack([ error.name, error.message ])
|
|
785
|
+
}
|
|
786
|
+
}, {
|
|
787
|
+
pack(regex, allocateForWrite, pack) {
|
|
788
|
+
let { target, position} = allocateForWrite(this.moreTypes ? 3 : 0)
|
|
789
|
+
if (this.moreTypes) {
|
|
790
|
+
target[position++] = 0xd4
|
|
791
|
+
target[position++] = 0x78 // 'x' for regeXp
|
|
792
|
+
target[position++] = 0
|
|
793
|
+
}
|
|
794
|
+
pack([ regex.source, regex.flags ])
|
|
795
|
+
}
|
|
796
|
+
}, {
|
|
797
|
+
pack(arrayBuffer, allocateForWrite) {
|
|
798
|
+
if (this.moreTypes)
|
|
799
|
+
writeExtBuffer(arrayBuffer, 0x10, allocateForWrite)
|
|
800
|
+
else
|
|
801
|
+
writeBuffer(hasNodeBuffer ? Buffer.from(arrayBuffer) : new Uint8Array(arrayBuffer), allocateForWrite)
|
|
802
|
+
}
|
|
803
|
+
}, {
|
|
804
|
+
pack(typedArray, allocateForWrite) {
|
|
805
|
+
let constructor = typedArray.constructor
|
|
806
|
+
if (constructor !== ByteArray && this.moreTypes)
|
|
807
|
+
writeExtBuffer(typedArray, typedArrays.indexOf(constructor.name), allocateForWrite)
|
|
808
|
+
else
|
|
809
|
+
writeBuffer(typedArray, allocateForWrite)
|
|
810
|
+
}
|
|
811
|
+
}, {
|
|
812
|
+
pack(c1, allocateForWrite) { // specific 0xC1 object
|
|
813
|
+
let { target, position} = allocateForWrite(1)
|
|
814
|
+
target[position] = 0xc1
|
|
815
|
+
}
|
|
816
|
+
}]
|
|
817
|
+
|
|
818
|
+
function writeExtBuffer(typedArray, type, allocateForWrite, encode) {
|
|
819
|
+
let length = typedArray.byteLength
|
|
820
|
+
if (length + 1 < 0x100) {
|
|
821
|
+
var { target, position } = allocateForWrite(4 + length)
|
|
822
|
+
target[position++] = 0xc7
|
|
823
|
+
target[position++] = length + 1
|
|
824
|
+
} else if (length + 1 < 0x10000) {
|
|
825
|
+
var { target, position } = allocateForWrite(5 + length)
|
|
826
|
+
target[position++] = 0xc8
|
|
827
|
+
target[position++] = (length + 1) >> 8
|
|
828
|
+
target[position++] = (length + 1) & 0xff
|
|
829
|
+
} else {
|
|
830
|
+
var { target, position, targetView } = allocateForWrite(7 + length)
|
|
831
|
+
target[position++] = 0xc9
|
|
832
|
+
targetView.setUint32(position, length + 1) // plus one for the type byte
|
|
833
|
+
position += 4
|
|
834
|
+
}
|
|
835
|
+
target[position++] = 0x74 // "t" for typed array
|
|
836
|
+
target[position++] = type
|
|
837
|
+
target.set(new Uint8Array(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength), position)
|
|
838
|
+
}
|
|
839
|
+
function writeBuffer(buffer, allocateForWrite) {
|
|
840
|
+
let length = buffer.byteLength
|
|
841
|
+
var target, position
|
|
842
|
+
if (length < 0x100) {
|
|
843
|
+
var { target, position } = allocateForWrite(length + 2)
|
|
844
|
+
target[position++] = 0xc4
|
|
845
|
+
target[position++] = length
|
|
846
|
+
} else if (length < 0x10000) {
|
|
847
|
+
var { target, position } = allocateForWrite(length + 3)
|
|
848
|
+
target[position++] = 0xc5
|
|
849
|
+
target[position++] = length >> 8
|
|
850
|
+
target[position++] = length & 0xff
|
|
851
|
+
} else {
|
|
852
|
+
var { target, position, targetView } = allocateForWrite(length + 5)
|
|
853
|
+
target[position++] = 0xc6
|
|
854
|
+
targetView.setUint32(position, length)
|
|
855
|
+
position += 4
|
|
856
|
+
}
|
|
857
|
+
target.set(buffer, position)
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
function writeExtensionData(result, target, position, type) {
|
|
861
|
+
let length = result.length
|
|
862
|
+
switch (length) {
|
|
863
|
+
case 1:
|
|
864
|
+
target[position++] = 0xd4
|
|
865
|
+
break
|
|
866
|
+
case 2:
|
|
867
|
+
target[position++] = 0xd5
|
|
868
|
+
break
|
|
869
|
+
case 4:
|
|
870
|
+
target[position++] = 0xd6
|
|
871
|
+
break
|
|
872
|
+
case 8:
|
|
873
|
+
target[position++] = 0xd7
|
|
874
|
+
break
|
|
875
|
+
case 16:
|
|
876
|
+
target[position++] = 0xd8
|
|
877
|
+
break
|
|
878
|
+
default:
|
|
879
|
+
if (length < 0x100) {
|
|
880
|
+
target[position++] = 0xc7
|
|
881
|
+
target[position++] = length
|
|
882
|
+
} else if (length < 0x10000) {
|
|
883
|
+
target[position++] = 0xc8
|
|
884
|
+
target[position++] = length >> 8
|
|
885
|
+
target[position++] = length & 0xff
|
|
886
|
+
} else {
|
|
887
|
+
target[position++] = 0xc9
|
|
888
|
+
target[position++] = length >> 24
|
|
889
|
+
target[position++] = (length >> 16) & 0xff
|
|
890
|
+
target[position++] = (length >> 8) & 0xff
|
|
891
|
+
target[position++] = length & 0xff
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
target[position++] = type
|
|
895
|
+
target.set(result, position)
|
|
896
|
+
position += length
|
|
897
|
+
return position
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
function insertIds(serialized, idsToInsert) {
|
|
901
|
+
// insert the ids that need to be referenced for structured clones
|
|
902
|
+
let nextId
|
|
903
|
+
let distanceToMove = idsToInsert.length * 6
|
|
904
|
+
let lastEnd = serialized.length - distanceToMove
|
|
905
|
+
idsToInsert.sort((a, b) => a.offset > b.offset ? 1 : -1)
|
|
906
|
+
while (nextId = idsToInsert.pop()) {
|
|
907
|
+
let offset = nextId.offset
|
|
908
|
+
let id = nextId.id
|
|
909
|
+
serialized.copyWithin(offset + distanceToMove, offset, lastEnd)
|
|
910
|
+
distanceToMove -= 6
|
|
911
|
+
let position = offset + distanceToMove
|
|
912
|
+
serialized[position++] = 0xd6
|
|
913
|
+
serialized[position++] = 0x69 // 'i'
|
|
914
|
+
serialized[position++] = id >> 24
|
|
915
|
+
serialized[position++] = (id >> 16) & 0xff
|
|
916
|
+
serialized[position++] = (id >> 8) & 0xff
|
|
917
|
+
serialized[position++] = id & 0xff
|
|
918
|
+
lastEnd = offset
|
|
919
|
+
}
|
|
920
|
+
return serialized
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
function writeBundles(start, pack) {
|
|
924
|
+
if (bundledStrings.length > 0) {
|
|
925
|
+
targetView.setUint32(bundledStrings.position + start, position - bundledStrings.position - start)
|
|
926
|
+
let writeStrings = bundledStrings
|
|
927
|
+
bundledStrings = null
|
|
928
|
+
let startPosition = position
|
|
929
|
+
pack(writeStrings[0])
|
|
930
|
+
pack(writeStrings[1])
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
export function addExtension(extension) {
|
|
935
|
+
if (extension.Class) {
|
|
936
|
+
if (!extension.pack && !extension.write)
|
|
937
|
+
throw new Error('Extension has no pack or write function')
|
|
938
|
+
if (extension.pack && !extension.type)
|
|
939
|
+
throw new Error('Extension has no type (numeric code to identify the extension)')
|
|
940
|
+
extensionClasses.unshift(extension.Class)
|
|
941
|
+
extensions.unshift(extension)
|
|
942
|
+
}
|
|
943
|
+
unpackAddExtension(extension)
|
|
944
|
+
}
|
|
945
|
+
export function setWriteStructSlots(func) {
|
|
946
|
+
writeStructSlots = func;
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
let defaultPackr = new Packr({ useRecords: false })
|
|
950
|
+
export const pack = defaultPackr.pack
|
|
951
|
+
export const encode = defaultPackr.pack
|
|
952
|
+
export const Encoder = Packr
|
|
953
|
+
export { FLOAT32_OPTIONS } from './unpack.js'
|
|
954
|
+
import { FLOAT32_OPTIONS } from './unpack.js'
|
|
955
|
+
export const { NEVER, ALWAYS, DECIMAL_ROUND, DECIMAL_FIT } = FLOAT32_OPTIONS
|
|
956
|
+
export const REUSE_BUFFER_MODE = 512
|
|
957
|
+
export const RESET_BUFFER_MODE = 1024
|