msgpackr 1.7.0-alpha5 → 1.7.0-beta1
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/README.md +1 -1
- package/dist/index.js +11 -2
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +62 -62
- package/dist/index.min.js.map +1 -1
- package/dist/node.cjs +96 -35
- package/dist/node.cjs.map +1 -1
- package/dist/test.js +101 -36
- package/dist/test.js.map +1 -1
- package/package.json +1 -1
- package/struct.js +80 -32
- package/unpack.js +16 -4
package/package.json
CHANGED
package/struct.js
CHANGED
|
@@ -41,11 +41,13 @@ const ASCII = 3; // the MIBenum from https://www.iana.org/assignments/character-
|
|
|
41
41
|
const NUMBER = 0;
|
|
42
42
|
const UTF8 = 2;
|
|
43
43
|
const OBJECT_DATA = 1;
|
|
44
|
+
const DATE = 16;
|
|
44
45
|
const TYPE_NAMES = ['num', 'object', 'string', 'ascii'];
|
|
46
|
+
TYPE_NAMES[DATE] = 'date';
|
|
45
47
|
const float32Headers = [false, true, true, false, false, true, true, false];
|
|
46
48
|
let updatedPosition;
|
|
47
49
|
const hasNodeBuffer = typeof Buffer !== 'undefined'
|
|
48
|
-
let textEncoder
|
|
50
|
+
let textEncoder, currentSource;
|
|
49
51
|
try {
|
|
50
52
|
textEncoder = new TextEncoder()
|
|
51
53
|
} catch (error) {}
|
|
@@ -89,7 +91,7 @@ function writeStruct(object, target, position, structures, makeRoom, pack, packr
|
|
|
89
91
|
return 0;
|
|
90
92
|
position += headerSize;
|
|
91
93
|
let queuedReferences = [];
|
|
92
|
-
let
|
|
94
|
+
let usedAscii0;
|
|
93
95
|
let keyIndex = 0;
|
|
94
96
|
for (let key in object) {
|
|
95
97
|
let value = object[key];
|
|
@@ -105,7 +107,8 @@ function writeStruct(object, target, position, structures, makeRoom, pack, packr
|
|
|
105
107
|
string16: null,
|
|
106
108
|
object16: null,
|
|
107
109
|
num32: null,
|
|
108
|
-
float64: null
|
|
110
|
+
float64: null,
|
|
111
|
+
date64: null
|
|
109
112
|
};
|
|
110
113
|
}
|
|
111
114
|
if (position > safeEnd) {
|
|
@@ -198,25 +201,47 @@ function writeStruct(object, target, position, structures, makeRoom, pack, packr
|
|
|
198
201
|
refPosition += encodeUtf8(target, value, refPosition);
|
|
199
202
|
isNotAscii = refPosition - strStart > strLength;
|
|
200
203
|
}
|
|
201
|
-
if (refOffset <
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
204
|
+
if (refOffset < 0xa0 || (refOffset < 0xf6 && (nextTransition.ascii8 || nextTransition.string8))) {
|
|
205
|
+
// short strings
|
|
206
|
+
if (isNotAscii) {
|
|
207
|
+
if (!(transition = nextTransition.string8)) {
|
|
208
|
+
if (typedStructs.length > 10 && (transition = nextTransition.ascii8)) {
|
|
209
|
+
// we can safely change ascii to utf8 in place since they are compatible
|
|
210
|
+
transition.__type = UTF8;
|
|
211
|
+
nextTransition.ascii8 = null;
|
|
212
|
+
nextTransition.string8 = transition;
|
|
213
|
+
pack(null, 0, true); // special call to notify that structures have been updated
|
|
214
|
+
} else {
|
|
215
|
+
transition = createTypeTransition(nextTransition, UTF8, 1);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
} else if (refOffset === 0 && !usedAscii0) {
|
|
219
|
+
usedAscii0 = true;
|
|
220
|
+
transition = nextTransition.ascii0 || createTypeTransition(nextTransition, ASCII, 0);
|
|
221
|
+
break; // don't increment position
|
|
222
|
+
}// else ascii:
|
|
223
|
+
else if (!(transition = nextTransition.ascii8) && !(typedStructs.length > 10 && (transition = nextTransition.string8)))
|
|
224
|
+
transition = createTypeTransition(nextTransition, ASCII, 1);
|
|
206
225
|
target[position++] = refOffset;
|
|
207
226
|
} else {
|
|
208
|
-
|
|
227
|
+
// TODO: Enable ascii16 at some point, but get the logic right
|
|
228
|
+
//if (isNotAscii)
|
|
209
229
|
transition = nextTransition.string16 || createTypeTransition(nextTransition, UTF8, 2);
|
|
210
|
-
else
|
|
211
|
-
transition = nextTransition.ascii16 || createTypeTransition(nextTransition, ASCII, 2);
|
|
230
|
+
//else
|
|
231
|
+
//transition = nextTransition.ascii16 || createTypeTransition(nextTransition, ASCII, 2);
|
|
212
232
|
targetView.setUint16(position, refOffset, true);
|
|
213
233
|
position += 2;
|
|
214
234
|
}
|
|
215
235
|
break;
|
|
216
236
|
case 'object':
|
|
217
237
|
if (value) {
|
|
218
|
-
|
|
219
|
-
|
|
238
|
+
if (value.constructor === Date) {
|
|
239
|
+
transition = nextTransition.date64 || createTypeTransition(nextTransition, DATE, 8);
|
|
240
|
+
targetView.setFloat64(position, value.getTime(), true);
|
|
241
|
+
position += 8;
|
|
242
|
+
} else {
|
|
243
|
+
queuedReferences.push(key, value, keyIndex);
|
|
244
|
+
}
|
|
220
245
|
break;
|
|
221
246
|
} else { // null
|
|
222
247
|
nextTransition = anyType(nextTransition, position, targetView, -10); // match CBOR with this
|
|
@@ -306,7 +331,7 @@ function writeStruct(object, target, position, structures, makeRoom, pack, packr
|
|
|
306
331
|
targetView.setUint32(position, refOffset, true);
|
|
307
332
|
position += 4;
|
|
308
333
|
}
|
|
309
|
-
} else {
|
|
334
|
+
} else { // null or undefined
|
|
310
335
|
transition = nextTransition.object16 || createTypeTransition(nextTransition, OBJECT_DATA, 2);
|
|
311
336
|
targetView.setInt16(position, value === null ? -10 : -9, true);
|
|
312
337
|
position += 2;
|
|
@@ -434,7 +459,8 @@ function onLoadedStructures(sharedData) {
|
|
|
434
459
|
string16: null,
|
|
435
460
|
object16: null,
|
|
436
461
|
num32: null,
|
|
437
|
-
float64: null
|
|
462
|
+
float64: null,
|
|
463
|
+
date64: null,
|
|
438
464
|
};
|
|
439
465
|
}
|
|
440
466
|
transition = createTypeTransition(nextTransition, type, size);
|
|
@@ -446,9 +472,8 @@ function onLoadedStructures(sharedData) {
|
|
|
446
472
|
this.lastTypedStructuresLength = typed.length;
|
|
447
473
|
return named;
|
|
448
474
|
}
|
|
449
|
-
var sourceSymbol = Symbol('source')
|
|
475
|
+
var sourceSymbol = Symbol.for('source')
|
|
450
476
|
function readStruct(src, position, srcEnd, unpackr) {
|
|
451
|
-
// var stringLength = (src[position++] << 8) | src[position++];
|
|
452
477
|
let recordId = src[position++] - 0x20;
|
|
453
478
|
if (recordId >= 24) {
|
|
454
479
|
switch(recordId) {
|
|
@@ -509,13 +534,13 @@ function readStruct(src, position, srcEnd, unpackr) {
|
|
|
509
534
|
case 0: getRef = () => 0; break;
|
|
510
535
|
case 1:
|
|
511
536
|
getRef = (source, position) => {
|
|
512
|
-
let ref = source.
|
|
537
|
+
let ref = source.bytes[position + property.offset];
|
|
513
538
|
return ref >= 0xf6 ? toConstant(ref) : ref;
|
|
514
539
|
};
|
|
515
540
|
break;
|
|
516
541
|
case 2:
|
|
517
542
|
getRef = (source, position) => {
|
|
518
|
-
let src = source.
|
|
543
|
+
let src = source.bytes;
|
|
519
544
|
let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
|
|
520
545
|
let ref = dataView.getUint16(position + property.offset, true);
|
|
521
546
|
return ref >= 0xff00 ? toConstant(ref & 0xff) : ref;
|
|
@@ -523,7 +548,7 @@ function readStruct(src, position, srcEnd, unpackr) {
|
|
|
523
548
|
break;
|
|
524
549
|
case 4:
|
|
525
550
|
getRef = (source, position) => {
|
|
526
|
-
let src = source.
|
|
551
|
+
let src = source.bytes;
|
|
527
552
|
let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
|
|
528
553
|
let ref = dataView.getUint32(position + property.offset, true);
|
|
529
554
|
return ref >= 0xffffff00 ? toConstant(ref & 0xff) : ref;
|
|
@@ -541,7 +566,7 @@ function readStruct(src, position, srcEnd, unpackr) {
|
|
|
541
566
|
property.multiGetCount = 0;
|
|
542
567
|
get = function() {
|
|
543
568
|
let source = this[sourceSymbol];
|
|
544
|
-
let src = source.
|
|
569
|
+
let src = source.bytes;
|
|
545
570
|
let position = source.position;
|
|
546
571
|
let refStart = currentOffset + position;
|
|
547
572
|
let ref = getRef(source, position);
|
|
@@ -557,7 +582,7 @@ function readStruct(src, position, srcEnd, unpackr) {
|
|
|
557
582
|
next = next.next;
|
|
558
583
|
}
|
|
559
584
|
if (end == null)
|
|
560
|
-
end = source.
|
|
585
|
+
end = source.bytesEnd - refStart;
|
|
561
586
|
if (source.srcString) {
|
|
562
587
|
return source.srcString.slice(ref, end);
|
|
563
588
|
}
|
|
@@ -573,7 +598,7 @@ function readStruct(src, position, srcEnd, unpackr) {
|
|
|
573
598
|
asciiEnd = null;
|
|
574
599
|
} while((next = next.next));
|
|
575
600
|
if (asciiEnd == null)
|
|
576
|
-
asciiEnd = source.
|
|
601
|
+
asciiEnd = source.bytesEnd - refStart
|
|
577
602
|
source.srcString = src.toString('latin1', refStart, refStart + asciiEnd);
|
|
578
603
|
return source.srcString.slice(ref, end);
|
|
579
604
|
}
|
|
@@ -597,7 +622,7 @@ function readStruct(src, position, srcEnd, unpackr) {
|
|
|
597
622
|
let refStart = currentOffset + position;
|
|
598
623
|
let ref = getRef(source, position);
|
|
599
624
|
if (typeof ref !== 'number') return ref;
|
|
600
|
-
let src = source.
|
|
625
|
+
let src = source.bytes;
|
|
601
626
|
let end, next = property.next;
|
|
602
627
|
while(next) {
|
|
603
628
|
end = next.getRef(source, position);
|
|
@@ -608,11 +633,16 @@ function readStruct(src, position, srcEnd, unpackr) {
|
|
|
608
633
|
next = next.next;
|
|
609
634
|
}
|
|
610
635
|
if (end == null)
|
|
611
|
-
end = source.
|
|
636
|
+
end = source.bytesEnd - refStart;
|
|
612
637
|
if (type === UTF8) {
|
|
613
638
|
return src.toString('utf8', ref + refStart, end + refStart);
|
|
614
639
|
} else {
|
|
615
|
-
|
|
640
|
+
currentSource = source;
|
|
641
|
+
try {
|
|
642
|
+
return unpackr.unpack(src, { start: ref + refStart, end: end + refStart });
|
|
643
|
+
} finally {
|
|
644
|
+
currentSource = null;
|
|
645
|
+
}
|
|
616
646
|
}
|
|
617
647
|
};
|
|
618
648
|
break;
|
|
@@ -621,7 +651,7 @@ function readStruct(src, position, srcEnd, unpackr) {
|
|
|
621
651
|
case 4:
|
|
622
652
|
get = function () {
|
|
623
653
|
let source = this[sourceSymbol];
|
|
624
|
-
let src = source.
|
|
654
|
+
let src = source.bytes;
|
|
625
655
|
let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
|
|
626
656
|
let position = source.position + property.offset;
|
|
627
657
|
let value = dataView.getInt32(position, true)
|
|
@@ -640,7 +670,7 @@ function readStruct(src, position, srcEnd, unpackr) {
|
|
|
640
670
|
case 8:
|
|
641
671
|
get = function () {
|
|
642
672
|
let source = this[sourceSymbol];
|
|
643
|
-
let src = source.
|
|
673
|
+
let src = source.bytes;
|
|
644
674
|
let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
|
|
645
675
|
let value = dataView.getFloat64(source.position + property.offset, true);
|
|
646
676
|
if (isNaN(value)) {
|
|
@@ -654,12 +684,22 @@ function readStruct(src, position, srcEnd, unpackr) {
|
|
|
654
684
|
case 1:
|
|
655
685
|
get = function () {
|
|
656
686
|
let source = this[sourceSymbol];
|
|
657
|
-
let src = source.
|
|
687
|
+
let src = source.bytes;
|
|
658
688
|
let value = src[source.position + property.offset];
|
|
659
689
|
return value < 0xf6 ? value : toConstant(value);
|
|
660
690
|
};
|
|
661
691
|
break;
|
|
662
692
|
}
|
|
693
|
+
break;
|
|
694
|
+
case DATE:
|
|
695
|
+
get = function () {
|
|
696
|
+
let source = this[sourceSymbol];
|
|
697
|
+
let src = source.bytes;
|
|
698
|
+
let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
|
|
699
|
+
return new Date(dataView.getFloat64(source.position + property.offset, true));
|
|
700
|
+
};
|
|
701
|
+
break;
|
|
702
|
+
|
|
663
703
|
}
|
|
664
704
|
property.get = get;
|
|
665
705
|
}
|
|
@@ -668,10 +708,10 @@ function readStruct(src, position, srcEnd, unpackr) {
|
|
|
668
708
|
}
|
|
669
709
|
var instance = new construct();
|
|
670
710
|
instance[sourceSymbol] = {
|
|
671
|
-
src,
|
|
711
|
+
bytes: src,
|
|
672
712
|
position,
|
|
673
713
|
srcString: '',
|
|
674
|
-
srcEnd
|
|
714
|
+
bytesEnd: srcEnd
|
|
675
715
|
}
|
|
676
716
|
return instance;
|
|
677
717
|
}
|
|
@@ -684,6 +724,14 @@ function toConstant(code) {
|
|
|
684
724
|
}
|
|
685
725
|
throw new Error('Unknown constant');
|
|
686
726
|
}
|
|
727
|
+
|
|
728
|
+
function saveState() {
|
|
729
|
+
if (currentSource) {
|
|
730
|
+
currentSource.bytes = Uint8Array.prototype.slice.call(currentSource.bytes, currentSource.position, currentSource.bytesEnd);
|
|
731
|
+
currentSource.position = 0;
|
|
732
|
+
currentSource.bytesEnd = currentSource.bytes.length;
|
|
733
|
+
}
|
|
734
|
+
}
|
|
687
735
|
function prepareStructures(structures, packr) {
|
|
688
736
|
if (packr.typedStructs) {
|
|
689
737
|
let structMap = new Map();
|
|
@@ -713,5 +761,5 @@ function prepareStructures(structures, packr) {
|
|
|
713
761
|
return structures;
|
|
714
762
|
}
|
|
715
763
|
|
|
716
|
-
setReadStruct(readStruct, onLoadedStructures);
|
|
764
|
+
setReadStruct(readStruct, onLoadedStructures, saveState);
|
|
717
765
|
|
package/unpack.js
CHANGED
|
@@ -28,7 +28,7 @@ export const C1 = new C1Type()
|
|
|
28
28
|
C1.name = 'MessagePack 0xC1'
|
|
29
29
|
var sequentialMode = false
|
|
30
30
|
var inlineObjectReadThreshold = 2
|
|
31
|
-
var readStruct, onLoadedStructures
|
|
31
|
+
var readStruct, onLoadedStructures, onSaveState
|
|
32
32
|
try {
|
|
33
33
|
new Function('')
|
|
34
34
|
} catch(error) {
|
|
@@ -208,7 +208,7 @@ export function checkedRead(options) {
|
|
|
208
208
|
// else more to read, but we are reading sequentially, so don't clear source yet
|
|
209
209
|
return result
|
|
210
210
|
} catch(error) {
|
|
211
|
-
if (currentStructures
|
|
211
|
+
if (currentStructures?.restoreStructures)
|
|
212
212
|
restoreStructures()
|
|
213
213
|
clearSource()
|
|
214
214
|
if (error instanceof RangeError || error.message.startsWith('Unexpected end of buffer') || position > srcEnd) {
|
|
@@ -930,7 +930,16 @@ function readKey() {
|
|
|
930
930
|
|
|
931
931
|
// the registration of the record definition extension (as "r")
|
|
932
932
|
const recordDefinition = (id, highByte) => {
|
|
933
|
-
|
|
933
|
+
let structure
|
|
934
|
+
if (currentUnpackr.freezeData) {
|
|
935
|
+
currentUnpackr.freezeData = false;
|
|
936
|
+
try {
|
|
937
|
+
structure = read()
|
|
938
|
+
} finally {
|
|
939
|
+
currentUnpackr.freezeData = true;
|
|
940
|
+
}
|
|
941
|
+
} else
|
|
942
|
+
structure = read()
|
|
934
943
|
let firstByte = id
|
|
935
944
|
if (highByte !== undefined) {
|
|
936
945
|
id = id < 32 ? -((highByte << 5) + id) : ((highByte << 5) + id)
|
|
@@ -1032,6 +1041,8 @@ currentExtensions[0xff] = (data) => {
|
|
|
1032
1041
|
// currentExtensions[0x52] = () =>
|
|
1033
1042
|
|
|
1034
1043
|
function saveState(callback) {
|
|
1044
|
+
if (onSaveState)
|
|
1045
|
+
onSaveState();
|
|
1035
1046
|
let savedSrcEnd = srcEnd
|
|
1036
1047
|
let savedPosition = position
|
|
1037
1048
|
let savedStringPosition = stringPosition
|
|
@@ -1101,7 +1112,8 @@ export function roundFloat32(float32Number) {
|
|
|
1101
1112
|
let multiplier = mult10[((u8Array[3] & 0x7f) << 1) | (u8Array[2] >> 7)]
|
|
1102
1113
|
return ((multiplier * float32Number + (float32Number > 0 ? 0.5 : -0.5)) >> 0) / multiplier
|
|
1103
1114
|
}
|
|
1104
|
-
export function setReadStruct(updatedReadStruct, loadedStructs) {
|
|
1115
|
+
export function setReadStruct(updatedReadStruct, loadedStructs, saveState) {
|
|
1105
1116
|
readStruct = updatedReadStruct;
|
|
1106
1117
|
onLoadedStructures = loadedStructs;
|
|
1118
|
+
onSaveState = saveState;
|
|
1107
1119
|
}
|