msgpackr 1.7.0-alpha2 → 1.7.0-alpha3
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/LICENSE +21 -21
- package/README.md +335 -335
- package/SECURITY.md +11 -11
- package/benchmark.md +67 -67
- package/dist/index.js +111 -97
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +77 -77
- package/dist/index.min.js.map +1 -1
- package/dist/node.cjs +777 -311
- package/dist/node.cjs.map +1 -1
- package/dist/test.js +692 -180
- package/dist/test.js.map +1 -1
- package/index.js +5 -5
- package/iterators.js +86 -86
- package/pack.d.ts +9 -9
- package/pack.js +16 -11
- package/package.json +1 -1
- package/rollup.config.js +49 -49
- package/stream.js +57 -57
- package/struct.js +635 -186
- package/unpack.js +37 -12
- package/dist/str.cjs +0 -100
package/dist/test.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
(function (msgpackr, chai, fs) {
|
|
1
|
+
(function (msgpackr, chai, inspector, fs) {
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
chai = chai && Object.prototype.hasOwnProperty.call(chai, 'default') ? chai['default'] : chai;
|
|
5
|
+
inspector = inspector && Object.prototype.hasOwnProperty.call(inspector, 'default') ? inspector['default'] : inspector;
|
|
5
6
|
|
|
6
7
|
var decoder;
|
|
7
8
|
try {
|
|
@@ -28,7 +29,7 @@
|
|
|
28
29
|
C1.name = 'MessagePack 0xC1';
|
|
29
30
|
var sequentialMode = false;
|
|
30
31
|
var inlineObjectReadThreshold = 2;
|
|
31
|
-
var readStruct;
|
|
32
|
+
var readStruct, onLoadedStructures;
|
|
32
33
|
try {
|
|
33
34
|
new Function('');
|
|
34
35
|
} catch(error) {
|
|
@@ -58,16 +59,21 @@
|
|
|
58
59
|
}
|
|
59
60
|
Object.assign(this, options);
|
|
60
61
|
}
|
|
61
|
-
unpack(source,
|
|
62
|
+
unpack(source, options) {
|
|
62
63
|
if (src) {
|
|
63
64
|
// re-entrant execution, save the state and restore it after we do this unpack
|
|
64
65
|
return saveState(() => {
|
|
65
66
|
clearSource();
|
|
66
|
-
return this ? this.unpack(source,
|
|
67
|
+
return this ? this.unpack(source, options) : Unpackr.prototype.unpack.call(defaultOptions, source, options)
|
|
67
68
|
})
|
|
68
69
|
}
|
|
69
|
-
|
|
70
|
-
|
|
70
|
+
if (typeof options === 'object') {
|
|
71
|
+
srcEnd = options.end || source.length;
|
|
72
|
+
position = options.start || 0;
|
|
73
|
+
} else {
|
|
74
|
+
position = 0;
|
|
75
|
+
srcEnd = options > -1 ? options : source.length;
|
|
76
|
+
}
|
|
71
77
|
srcStringEnd = 0;
|
|
72
78
|
srcString = null;
|
|
73
79
|
bundledStrings = null;
|
|
@@ -132,6 +138,8 @@
|
|
|
132
138
|
}
|
|
133
139
|
}
|
|
134
140
|
_mergeStructures(loadedStructures, existingStructures) {
|
|
141
|
+
if (onLoadedStructures)
|
|
142
|
+
loadedStructures = onLoadedStructures.call(this, loadedStructures);
|
|
135
143
|
loadedStructures = loadedStructures || [];
|
|
136
144
|
for (let i = 0, l = loadedStructures.length; i < l; i++) {
|
|
137
145
|
let structure = loadedStructures[i];
|
|
@@ -167,9 +175,8 @@
|
|
|
167
175
|
currentStructures.length = sharedLength;
|
|
168
176
|
}
|
|
169
177
|
let result;
|
|
170
|
-
if (currentUnpackr.randomAccessStructure && src[position] < 0x40 && readStruct) {
|
|
171
|
-
|
|
172
|
-
result = readStruct(src, position, srcEnd, currentStructures[id - 0x40] || loadStructures()[id - 0x40], currentUnpackr);
|
|
178
|
+
if (currentUnpackr.randomAccessStructure && src[position] < 0x40 && src[position] >= 0x20 && readStruct) {
|
|
179
|
+
result = readStruct(src, position, srcEnd, currentUnpackr);
|
|
173
180
|
position = srcEnd;
|
|
174
181
|
} else
|
|
175
182
|
result = read();
|
|
@@ -565,6 +572,16 @@
|
|
|
565
572
|
|
|
566
573
|
return result
|
|
567
574
|
}
|
|
575
|
+
function readString(source, start, length) {
|
|
576
|
+
let existingSrc = src;
|
|
577
|
+
src = source;
|
|
578
|
+
position = start;
|
|
579
|
+
try {
|
|
580
|
+
return readStringJS(length);
|
|
581
|
+
} finally {
|
|
582
|
+
src = existingSrc;
|
|
583
|
+
}
|
|
584
|
+
}
|
|
568
585
|
|
|
569
586
|
function readArray(length) {
|
|
570
587
|
let array = new Array(length);
|
|
@@ -785,7 +802,15 @@
|
|
|
785
802
|
function readExt(length) {
|
|
786
803
|
let type = src[position++];
|
|
787
804
|
if (currentExtensions[type]) {
|
|
788
|
-
|
|
805
|
+
let end;
|
|
806
|
+
return currentExtensions[type](src.subarray(position, end = (position += length)), (readPosition) => {
|
|
807
|
+
position = readPosition;
|
|
808
|
+
try {
|
|
809
|
+
return read();
|
|
810
|
+
} finally {
|
|
811
|
+
position = end;
|
|
812
|
+
}
|
|
813
|
+
})
|
|
789
814
|
}
|
|
790
815
|
else
|
|
791
816
|
throw new Error('Unknown extension type ' + type)
|
|
@@ -1000,8 +1025,9 @@
|
|
|
1000
1025
|
mult10[i] = +('1e' + Math.floor(45.15 - i * 0.30103));
|
|
1001
1026
|
}
|
|
1002
1027
|
var defaultUnpackr = new Unpackr({ useRecords: false });
|
|
1003
|
-
function setReadStruct(
|
|
1004
|
-
readStruct =
|
|
1028
|
+
function setReadStruct(updatedReadStruct, loadedStructs) {
|
|
1029
|
+
readStruct = updatedReadStruct;
|
|
1030
|
+
onLoadedStructures = loadedStructs;
|
|
1005
1031
|
}
|
|
1006
1032
|
|
|
1007
1033
|
let textEncoder;
|
|
@@ -1019,7 +1045,7 @@
|
|
|
1019
1045
|
let position$1 = 0;
|
|
1020
1046
|
let safeEnd;
|
|
1021
1047
|
let bundledStrings$1 = null;
|
|
1022
|
-
let writeStructSlots;
|
|
1048
|
+
let writeStructSlots, prepareStructures;
|
|
1023
1049
|
const MAX_BUNDLE_SIZE = 0xf000;
|
|
1024
1050
|
const hasNonLatin = /[\u0080-\uFFFF]/;
|
|
1025
1051
|
const RECORD_SYMBOL = Symbol('record-id');
|
|
@@ -1031,7 +1057,6 @@
|
|
|
1031
1057
|
let hasSharedUpdate;
|
|
1032
1058
|
let structures;
|
|
1033
1059
|
let referenceMap;
|
|
1034
|
-
let lastSharedStructuresLength = 0;
|
|
1035
1060
|
let encodeUtf8 = ByteArray.prototype.utf8Write ? function(string, position) {
|
|
1036
1061
|
return target.utf8Write(string, position, 0xffffffff)
|
|
1037
1062
|
} : (textEncoder && textEncoder.encodeInto) ?
|
|
@@ -1117,7 +1142,7 @@
|
|
|
1117
1142
|
}
|
|
1118
1143
|
transition[RECORD_SYMBOL] = i + 0x40;
|
|
1119
1144
|
}
|
|
1120
|
-
|
|
1145
|
+
this.lastNamedStructuresLength = sharedLength;
|
|
1121
1146
|
}
|
|
1122
1147
|
if (!isSequential) {
|
|
1123
1148
|
structures.nextId = sharedLength + 0x40;
|
|
@@ -1172,12 +1197,13 @@
|
|
|
1172
1197
|
if (hasSharedUpdate && packr.saveStructures) {
|
|
1173
1198
|
// we can't rely on start/end with REUSE_BUFFER_MODE since they will (probably) change when we save
|
|
1174
1199
|
let returnBuffer = target.subarray(start, position$1);
|
|
1175
|
-
|
|
1200
|
+
let newSharedData = prepareStructures ? prepareStructures(structures, packr) : structures;
|
|
1201
|
+
if (packr.saveStructures(newSharedData, newSharedData.isCompatible || packr.lastNamedStructuresLength || 0) === false) {
|
|
1176
1202
|
// get updated structures and try again if the update failed
|
|
1177
1203
|
packr._mergeStructures(packr.getStructures());
|
|
1178
1204
|
return packr.pack(value)
|
|
1179
1205
|
}
|
|
1180
|
-
|
|
1206
|
+
packr.lastNamedStructuresLength = sharedLength;
|
|
1181
1207
|
return returnBuffer
|
|
1182
1208
|
}
|
|
1183
1209
|
}
|
|
@@ -1295,7 +1321,7 @@
|
|
|
1295
1321
|
} else if (type === 'number') {
|
|
1296
1322
|
if (value >>> 0 === value) {// positive integer, 32-bit or less
|
|
1297
1323
|
// positive uint
|
|
1298
|
-
if (value <
|
|
1324
|
+
if (value < 0x20 || (value < 0x80 && this.useRecords === false) || (value < 0x40 && !this.randomAccessStructure)) {
|
|
1299
1325
|
target[position$1++] = value;
|
|
1300
1326
|
} else if (value < 0x100) {
|
|
1301
1327
|
target[position$1++] = 0xcc;
|
|
@@ -1695,16 +1721,18 @@
|
|
|
1695
1721
|
}
|
|
1696
1722
|
};
|
|
1697
1723
|
const writeStruct = (object, safePrototype) => {
|
|
1698
|
-
let newPosition = writeStructSlots(object, target, position$1, structures, makeRoom, (value, newPosition) => {
|
|
1724
|
+
let newPosition = writeStructSlots(object, target, position$1, structures, makeRoom, (value, newPosition, notifySharedUpdate) => {
|
|
1725
|
+
if (notifySharedUpdate)
|
|
1726
|
+
hasSharedUpdate = true;
|
|
1699
1727
|
position$1 = newPosition;
|
|
1700
1728
|
if (start > 0) {
|
|
1701
1729
|
pack(value);
|
|
1702
1730
|
if (start == 0)
|
|
1703
|
-
return { position: position$1, targetView }; // indicate the buffer was re-allocated
|
|
1731
|
+
return { position: position$1, targetView, target }; // indicate the buffer was re-allocated
|
|
1704
1732
|
} else
|
|
1705
1733
|
pack(value);
|
|
1706
1734
|
return position$1;
|
|
1707
|
-
});
|
|
1735
|
+
}, this);
|
|
1708
1736
|
if (newPosition === 0) // bail and go to a msgpack object
|
|
1709
1737
|
return writeObject(object, true);
|
|
1710
1738
|
position$1 = newPosition;
|
|
@@ -1719,6 +1747,8 @@
|
|
|
1719
1747
|
clearSharedData() {
|
|
1720
1748
|
if (this.structures)
|
|
1721
1749
|
this.structures = [];
|
|
1750
|
+
if (this.typedStructs)
|
|
1751
|
+
this.typedStructs = [];
|
|
1722
1752
|
}
|
|
1723
1753
|
}
|
|
1724
1754
|
|
|
@@ -1926,155 +1956,445 @@
|
|
|
1926
1956
|
pack(writeStrings[1]);
|
|
1927
1957
|
}
|
|
1928
1958
|
}
|
|
1929
|
-
function setWriteStructSlots(
|
|
1930
|
-
writeStructSlots =
|
|
1959
|
+
function setWriteStructSlots(writeSlots, makeStructures) {
|
|
1960
|
+
writeStructSlots = writeSlots;
|
|
1961
|
+
prepareStructures = makeStructures;
|
|
1931
1962
|
}
|
|
1932
1963
|
|
|
1933
1964
|
let defaultPackr = new Packr({ useRecords: false });
|
|
1934
1965
|
const REUSE_BUFFER_MODE = 512;
|
|
1935
1966
|
const RESET_BUFFER_MODE = 1024;
|
|
1936
1967
|
|
|
1937
|
-
//
|
|
1938
|
-
const
|
|
1968
|
+
const ASCII = 3; // the MIBenum from https://www.iana.org/assignments/character-sets/character-sets.xhtml (and other character encodings could be referenced by MIBenum)
|
|
1969
|
+
const NUMBER = 0;
|
|
1970
|
+
const UTF8 = 2;
|
|
1971
|
+
const OBJECT_DATA = 1;
|
|
1972
|
+
const TYPE_NAMES = ['num', 'object', 'string', 'ascii'];
|
|
1939
1973
|
const float32Headers = [false, true, true, false, false, true, true, false];
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1974
|
+
let updatedPosition;
|
|
1975
|
+
const hasNodeBuffer$1 = typeof Buffer !== 'undefined';
|
|
1976
|
+
let textEncoder$1;
|
|
1977
|
+
try {
|
|
1978
|
+
textEncoder$1 = new TextEncoder();
|
|
1979
|
+
} catch (error) {}
|
|
1980
|
+
const encodeUtf8 = hasNodeBuffer$1 ? function(target, string, position) {
|
|
1981
|
+
return target.utf8Write(string, position, 0xffffffff)
|
|
1982
|
+
} : (textEncoder$1 && textEncoder$1.encodeInto) ?
|
|
1983
|
+
function(target, string, position) {
|
|
1984
|
+
return textEncoder$1.encodeInto(string, target.subarray(position)).written
|
|
1985
|
+
} : false;
|
|
1986
|
+
setWriteStructSlots(writeStruct, prepareStructures$1);
|
|
1987
|
+
function writeStruct(object, target, position, structures, makeRoom, pack, packr) {
|
|
1988
|
+
let typedStructs = packr.typedStructs || (packr.typedStructs = []);
|
|
1989
|
+
// note that we rely on pack.js to load stored structures before we get to this point
|
|
1990
|
+
packr.lastTypedStructuresLength = typedStructs.length;
|
|
1947
1991
|
let targetView = target.dataView;
|
|
1948
|
-
let
|
|
1949
|
-
let stringData = '';
|
|
1992
|
+
let refsStartPosition = (typedStructs.lastStringStart || 100) + position;
|
|
1950
1993
|
let safeEnd = target.length - 10;
|
|
1994
|
+
let start = position;
|
|
1995
|
+
if (position > safeEnd) {
|
|
1996
|
+
let lastStart = start;
|
|
1997
|
+
target = makeRoom(position);
|
|
1998
|
+
targetView = target.dataView;
|
|
1999
|
+
position -= lastStart;
|
|
2000
|
+
refsStartPosition -= lastStart;
|
|
2001
|
+
start = 0;
|
|
2002
|
+
safeEnd = target.length - 10;
|
|
2003
|
+
}
|
|
2004
|
+
|
|
2005
|
+
let refOffset, refPosition = refsStartPosition;
|
|
2006
|
+
|
|
2007
|
+
let transition = typedStructs.transitions || (typedStructs.transitions = Object.create(null));
|
|
2008
|
+
let nextId = typedStructs.nextId || typedStructs.length;
|
|
2009
|
+
let headerSize =
|
|
2010
|
+
nextId < 0xf ? 1 :
|
|
2011
|
+
nextId < 0xf0 ? 2 :
|
|
2012
|
+
nextId < 0xf000 ? 3 :
|
|
2013
|
+
nextId < 0xf00000 ? 4 : 0;
|
|
2014
|
+
if (headerSize === 0)
|
|
2015
|
+
return 0;
|
|
2016
|
+
position += headerSize;
|
|
2017
|
+
let queuedReferences = [];
|
|
2018
|
+
let keyIndex = 0;
|
|
1951
2019
|
for (let key in object) {
|
|
2020
|
+
let value = object[key];
|
|
1952
2021
|
let nextTransition = transition[key];
|
|
1953
2022
|
if (!nextTransition) {
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
2023
|
+
transition[key] = nextTransition = {
|
|
2024
|
+
key,
|
|
2025
|
+
parent: transition,
|
|
2026
|
+
enumerationOffset: 0,
|
|
2027
|
+
ascii0: null,
|
|
2028
|
+
ascii8: null,
|
|
2029
|
+
num8: null,
|
|
2030
|
+
string16: null,
|
|
2031
|
+
object16: null,
|
|
2032
|
+
num32: null,
|
|
2033
|
+
float64: null
|
|
2034
|
+
};
|
|
1957
2035
|
}
|
|
1958
2036
|
if (position > safeEnd) {
|
|
1959
|
-
let
|
|
2037
|
+
let lastStart = start;
|
|
1960
2038
|
target = makeRoom(position);
|
|
1961
|
-
|
|
2039
|
+
targetView = target.dataView;
|
|
2040
|
+
position -= lastStart;
|
|
2041
|
+
refsStartPosition -= lastStart;
|
|
2042
|
+
refPosition -= lastStart;
|
|
1962
2043
|
start = 0;
|
|
1963
2044
|
safeEnd = target.length - 10;
|
|
1964
2045
|
}
|
|
1965
|
-
transition = nextTransition;
|
|
1966
|
-
let value = object[key];
|
|
1967
2046
|
switch (typeof value) {
|
|
1968
2047
|
case 'number':
|
|
1969
|
-
|
|
1970
|
-
|
|
2048
|
+
let number = value;
|
|
2049
|
+
if (number >> 0 === number && number < 0x20000000 && number > -0x1f000000) {
|
|
2050
|
+
if (number < 0xf6 && number >= 0 && (nextTransition.num8 || number < 0x20 && !nextTransition.num32)) {
|
|
2051
|
+
transition = nextTransition.num8 || createTypeTransition(nextTransition, NUMBER, 1);
|
|
2052
|
+
target[position++] = number;
|
|
2053
|
+
} else {
|
|
2054
|
+
transition = nextTransition.num32 || createTypeTransition(nextTransition, NUMBER, 4);
|
|
2055
|
+
targetView.setUint32(position, number, true);
|
|
2056
|
+
position += 4;
|
|
2057
|
+
}
|
|
1971
2058
|
break;
|
|
1972
|
-
} else if (
|
|
1973
|
-
targetView.setFloat32(position,
|
|
2059
|
+
} else if (number < 0x100000000 && number >= -0x80000000) {
|
|
2060
|
+
targetView.setFloat32(position, number, true);
|
|
1974
2061
|
if (float32Headers[target[position + 3] >>> 5]) {
|
|
1975
2062
|
let xShifted;
|
|
1976
2063
|
// this checks for rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
|
|
1977
|
-
if (((xShifted =
|
|
2064
|
+
if (((xShifted = number * mult10[((target[position + 3] & 0x7f) << 1) | (target[position + 2] >> 7)]) >> 0) === xShifted) {
|
|
2065
|
+
transition = nextTransition.num32 || createTypeTransition(nextTransition, NUMBER, 4);
|
|
1978
2066
|
position += 4;
|
|
1979
|
-
|
|
2067
|
+
break;
|
|
1980
2068
|
}
|
|
1981
2069
|
}
|
|
1982
2070
|
}
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
position +=
|
|
1986
|
-
|
|
2071
|
+
transition = nextTransition.num64 || createTypeTransition(nextTransition, NUMBER, 8);
|
|
2072
|
+
targetView.setFloat64(position, number, true);
|
|
2073
|
+
position += 8;
|
|
2074
|
+
break;
|
|
1987
2075
|
case 'string':
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
2076
|
+
let strLength = value.length;
|
|
2077
|
+
refOffset = refPosition - refsStartPosition;
|
|
2078
|
+
if ((strLength << 2) + position > safeEnd) {
|
|
2079
|
+
let lastStart = start;
|
|
2080
|
+
target = makeRoom(refPosition);
|
|
2081
|
+
targetView = target.dataView;
|
|
2082
|
+
position -= lastStart;
|
|
2083
|
+
refsStartPosition -= lastStart;
|
|
2084
|
+
refPosition -= lastStart;
|
|
2085
|
+
start = 0;
|
|
2086
|
+
safeEnd = target.length - 10;
|
|
1992
2087
|
}
|
|
1993
|
-
if (
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
}
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2088
|
+
if (strLength > ((0xff00 + refOffset) >> 2)) {
|
|
2089
|
+
queuedReferences.push(key, value, position - start);
|
|
2090
|
+
break;
|
|
2091
|
+
}
|
|
2092
|
+
let isNotAscii;
|
|
2093
|
+
let strStart = refPosition;
|
|
2094
|
+
if (strLength < 0x40) {
|
|
2095
|
+
let i, c1, c2;
|
|
2096
|
+
for (i = 0; i < strLength; i++) {
|
|
2097
|
+
c1 = value.charCodeAt(i);
|
|
2098
|
+
if (c1 < 0x80) {
|
|
2099
|
+
target[refPosition++] = c1;
|
|
2100
|
+
} else if (c1 < 0x800) {
|
|
2101
|
+
isNotAscii = true;
|
|
2102
|
+
target[refPosition++] = c1 >> 6 | 0xc0;
|
|
2103
|
+
target[refPosition++] = c1 & 0x3f | 0x80;
|
|
2104
|
+
} else if (
|
|
2105
|
+
(c1 & 0xfc00) === 0xd800 &&
|
|
2106
|
+
((c2 = value.charCodeAt(i + 1)) & 0xfc00) === 0xdc00
|
|
2107
|
+
) {
|
|
2108
|
+
isNotAscii = true;
|
|
2109
|
+
c1 = 0x10000 + ((c1 & 0x03ff) << 10) + (c2 & 0x03ff);
|
|
2110
|
+
i++;
|
|
2111
|
+
target[refPosition++] = c1 >> 18 | 0xf0;
|
|
2112
|
+
target[refPosition++] = c1 >> 12 & 0x3f | 0x80;
|
|
2113
|
+
target[refPosition++] = c1 >> 6 & 0x3f | 0x80;
|
|
2114
|
+
target[refPosition++] = c1 & 0x3f | 0x80;
|
|
2115
|
+
} else {
|
|
2116
|
+
isNotAscii = true;
|
|
2117
|
+
target[refPosition++] = c1 >> 12 | 0xe0;
|
|
2118
|
+
target[refPosition++] = c1 >> 6 & 0x3f | 0x80;
|
|
2119
|
+
target[refPosition++] = c1 & 0x3f | 0x80;
|
|
2120
|
+
}
|
|
2121
|
+
}
|
|
2122
|
+
} else {
|
|
2123
|
+
refPosition += encodeUtf8(target, value, refPosition);
|
|
2124
|
+
isNotAscii = refPosition - strStart > strLength;
|
|
2125
|
+
}
|
|
2126
|
+
if (refOffset < 0x100) {
|
|
2127
|
+
if (isNotAscii)
|
|
2128
|
+
transition = nextTransition.string8 || createTypeTransition(nextTransition, UTF8, 1);
|
|
2129
|
+
else
|
|
2130
|
+
transition = nextTransition.ascii8 || createTypeTransition(nextTransition, ASCII, 1);
|
|
2131
|
+
target[position++] = refOffset;
|
|
2132
|
+
} else {
|
|
2133
|
+
if (isNotAscii)
|
|
2134
|
+
transition = nextTransition.string16 || createTypeTransition(nextTransition, UTF8, 2);
|
|
2135
|
+
else
|
|
2136
|
+
transition = nextTransition.ascii16 || createTypeTransition(nextTransition, ASCII, 2);
|
|
2137
|
+
targetView.setUint16(position, refOffset, true);
|
|
2138
|
+
position += 2;
|
|
2004
2139
|
}
|
|
2005
2140
|
break;
|
|
2006
2141
|
case 'object':
|
|
2007
2142
|
if (value) {
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2143
|
+
//transition = nextTransition.object16 || createTypeTransition(nextTransition, OBJECT_DATA, 2);
|
|
2144
|
+
queuedReferences.push(key, value, keyIndex);
|
|
2145
|
+
break;
|
|
2011
2146
|
} else { // null
|
|
2012
|
-
|
|
2147
|
+
nextTransition = anyType(nextTransition, position, targetView, -10); // match CBOR with this
|
|
2148
|
+
if (nextTransition) {
|
|
2149
|
+
transition = nextTransition;
|
|
2150
|
+
position = updatedPosition;
|
|
2151
|
+
} else queuedReferences.push(key, value, keyIndex);
|
|
2013
2152
|
}
|
|
2014
2153
|
break;
|
|
2015
2154
|
case 'boolean':
|
|
2016
|
-
|
|
2155
|
+
transition = nextTransition.num8 || nextTransition.ascii8 || createTypeTransition(nextTransition, NUMBER, 1);
|
|
2156
|
+
target[position++] = value ? 0xf9 : 0xf8; // match CBOR with these
|
|
2017
2157
|
break;
|
|
2018
2158
|
case 'undefined':
|
|
2019
|
-
|
|
2159
|
+
nextTransition = anyType(nextTransition, position, targetView, -9); // match CBOR with this
|
|
2160
|
+
if (nextTransition) {
|
|
2161
|
+
transition = nextTransition;
|
|
2162
|
+
position = updatedPosition;
|
|
2163
|
+
} else queuedReferences.push(key, value, keyIndex);
|
|
2020
2164
|
break;
|
|
2021
2165
|
}
|
|
2022
|
-
|
|
2023
|
-
position += 4;
|
|
2166
|
+
keyIndex++;
|
|
2024
2167
|
}
|
|
2025
|
-
|
|
2026
|
-
if (!(recordId < 1024)) {
|
|
2027
|
-
// for now just punt and go back to writeObject
|
|
2028
|
-
return 0;
|
|
2029
|
-
// newRecord(transition, transition.__keys__ || Object.keys(object), newTransitions, true)
|
|
2030
|
-
}
|
|
2031
|
-
let stringLength = stringData.length;
|
|
2032
|
-
if (stringData) {
|
|
2033
|
-
if (position + stringLength > safeEnd) {
|
|
2034
|
-
target = makeRoom(position + stringLength);
|
|
2035
|
-
}
|
|
2036
|
-
position += target.latin1Write(stringData, position, 0xffffffff);
|
|
2037
|
-
}
|
|
2038
|
-
target[start] = recordId >> 8;
|
|
2039
|
-
target[start + 1] = recordId & 0xff;
|
|
2040
|
-
target[start + 2] = stringLength >> 8;
|
|
2041
|
-
target[start + 3] = stringLength & 0xff;
|
|
2042
|
-
let queued32BitReferences;
|
|
2168
|
+
|
|
2043
2169
|
for (let i = 0, l = queuedReferences.length; i < l;) {
|
|
2170
|
+
let key = queuedReferences[i++];
|
|
2044
2171
|
let value = queuedReferences[i++];
|
|
2045
|
-
let
|
|
2046
|
-
let
|
|
2047
|
-
if (
|
|
2048
|
-
|
|
2172
|
+
let propertyIndex = queuedReferences[i++];
|
|
2173
|
+
let nextTransition = transition[key];
|
|
2174
|
+
if (!nextTransition) {
|
|
2175
|
+
transition[key] = nextTransition = {
|
|
2176
|
+
key,
|
|
2177
|
+
parent: transition,
|
|
2178
|
+
enumerationOffset: propertyIndex - keyIndex,
|
|
2179
|
+
ascii0: null,
|
|
2180
|
+
ascii8: null,
|
|
2181
|
+
num8: null,
|
|
2182
|
+
string16: null,
|
|
2183
|
+
object16: null,
|
|
2184
|
+
num32: null,
|
|
2185
|
+
float64: null
|
|
2186
|
+
};
|
|
2187
|
+
}
|
|
2188
|
+
let newPosition;
|
|
2189
|
+
if (value) {
|
|
2190
|
+
/*if (typeof value === 'string') { // TODO: we could re-enable long strings
|
|
2191
|
+
if (position + value.length * 3 > safeEnd) {
|
|
2192
|
+
target = makeRoom(position + value.length * 3);
|
|
2193
|
+
position -= start;
|
|
2194
|
+
targetView = target.dataView;
|
|
2195
|
+
start = 0;
|
|
2196
|
+
}
|
|
2197
|
+
newPosition = position + target.utf8Write(value, position, 0xffffffff);
|
|
2198
|
+
} else { */
|
|
2199
|
+
let size;
|
|
2200
|
+
refOffset = refPosition - refsStartPosition;
|
|
2201
|
+
if (refOffset < 0xff00) {
|
|
2202
|
+
transition = nextTransition.object16;
|
|
2203
|
+
if (transition)
|
|
2204
|
+
size = 2;
|
|
2205
|
+
else if ((transition = nextTransition.object32))
|
|
2206
|
+
size = 4;
|
|
2207
|
+
else {
|
|
2208
|
+
transition = createTypeTransition(nextTransition, OBJECT_DATA, 2);
|
|
2209
|
+
size = 2;
|
|
2210
|
+
}
|
|
2211
|
+
} else {
|
|
2212
|
+
transition = nextTransition.object32 || createTypeTransition(nextTransition, OBJECT_DATA, 4);
|
|
2213
|
+
size = 4;
|
|
2214
|
+
}
|
|
2215
|
+
newPosition = pack(value, refPosition);
|
|
2216
|
+
//}
|
|
2217
|
+
if (typeof newPosition === 'object') {
|
|
2218
|
+
// re-allocated
|
|
2219
|
+
refPosition = newPosition.position;
|
|
2220
|
+
targetView = newPosition.targetView;
|
|
2221
|
+
target = newPosition.target;
|
|
2222
|
+
refsStartPosition -= start;
|
|
2223
|
+
position -= start;
|
|
2224
|
+
start = 0;
|
|
2225
|
+
} else
|
|
2226
|
+
refPosition = newPosition;
|
|
2227
|
+
if (size === 2) {
|
|
2228
|
+
targetView.setUint16(position, refOffset, true);
|
|
2229
|
+
position += 2;
|
|
2230
|
+
} else {
|
|
2231
|
+
targetView.setUint32(position, refOffset, true);
|
|
2232
|
+
position += 4;
|
|
2233
|
+
}
|
|
2049
2234
|
} else {
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2235
|
+
transition = nextTransition.object16 || createTypeTransition(nextTransition, OBJECT_DATA, 2);
|
|
2236
|
+
targetView.setInt16(position, value === null ? -10 : -9, true);
|
|
2237
|
+
position += 2;
|
|
2053
2238
|
}
|
|
2054
|
-
|
|
2055
|
-
if (typeof newPosition === 'object') {
|
|
2056
|
-
// re-allocated
|
|
2057
|
-
position = newPosition.position;
|
|
2058
|
-
targetView = newPosition.targetView;
|
|
2059
|
-
start = 0;
|
|
2060
|
-
} else
|
|
2061
|
-
position = newPosition;
|
|
2239
|
+
keyIndex++;
|
|
2062
2240
|
}
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2241
|
+
|
|
2242
|
+
|
|
2243
|
+
let recordId = transition[RECORD_SYMBOL];
|
|
2244
|
+
if (recordId == null) {
|
|
2245
|
+
recordId = packr.typedStructs.length;
|
|
2246
|
+
let structure = [];
|
|
2247
|
+
let nextTransition = transition;
|
|
2248
|
+
let key, type;
|
|
2249
|
+
while ((type = nextTransition.__type) !== undefined) {
|
|
2250
|
+
let size = nextTransition.__size;
|
|
2251
|
+
nextTransition = nextTransition.__parent;
|
|
2252
|
+
key = nextTransition.key;
|
|
2253
|
+
let property = [type, size, key];
|
|
2254
|
+
if (nextTransition.enumerationOffset)
|
|
2255
|
+
property.push(nextTransition.enumerationOffset);
|
|
2256
|
+
structure.push(property);
|
|
2257
|
+
nextTransition = nextTransition.parent;
|
|
2070
2258
|
}
|
|
2259
|
+
structure.reverse();
|
|
2260
|
+
transition[RECORD_SYMBOL] = recordId;
|
|
2261
|
+
packr.typedStructs[recordId] = structure;
|
|
2262
|
+
pack(null, 0, true); // special call to notify that structures have been updated
|
|
2263
|
+
}
|
|
2264
|
+
|
|
2265
|
+
|
|
2266
|
+
switch (headerSize) {
|
|
2267
|
+
case 1:
|
|
2268
|
+
if (recordId >= 0x10) return 0;
|
|
2269
|
+
target[start] = recordId + 0x20;
|
|
2270
|
+
break;
|
|
2271
|
+
case 2:
|
|
2272
|
+
if (recordId >= 0x100) return 0;
|
|
2273
|
+
target[start] = 0x38;
|
|
2274
|
+
target[start + 1] = recordId;
|
|
2275
|
+
break;
|
|
2276
|
+
case 3:
|
|
2277
|
+
if (recordId >= 0x10000) return 0;
|
|
2278
|
+
target[start] = 0x39;
|
|
2279
|
+
target.setUint16(start + 1, recordId, true);
|
|
2280
|
+
break;
|
|
2281
|
+
case 4:
|
|
2282
|
+
if (recordId >= 0x1000000) return 0;
|
|
2283
|
+
target.setUint32(start, (recordId << 8) + 0x3a, true);
|
|
2284
|
+
break;
|
|
2071
2285
|
}
|
|
2072
2286
|
|
|
2073
|
-
|
|
2287
|
+
if (position < refsStartPosition) {
|
|
2288
|
+
if (refsStartPosition === refPosition)
|
|
2289
|
+
return position; // no refs
|
|
2290
|
+
// adjust positioning
|
|
2291
|
+
target.copyWithin(position, refsStartPosition, refPosition);
|
|
2292
|
+
refPosition += position - refsStartPosition;
|
|
2293
|
+
typedStructs.lastStringStart = position - start;
|
|
2294
|
+
} else if (position > refsStartPosition) {
|
|
2295
|
+
if (refsStartPosition === refPosition)
|
|
2296
|
+
return position; // no refs
|
|
2297
|
+
typedStructs.lastStringStart = position - start;
|
|
2298
|
+
return writeStruct(object, target, start, structures, makeRoom, pack, packr);
|
|
2299
|
+
}
|
|
2300
|
+
return refPosition;
|
|
2301
|
+
}
|
|
2302
|
+
function anyType(transition, position, targetView, value) {
|
|
2303
|
+
let nextTransition;
|
|
2304
|
+
if ((nextTransition = transition.ascii8 || transition.num8)) {
|
|
2305
|
+
targetView.setInt8(position, value, true);
|
|
2306
|
+
updatedPosition = position + 1;
|
|
2307
|
+
return nextTransition;
|
|
2308
|
+
}
|
|
2309
|
+
if ((nextTransition = transition.string16 || transition.object16)) {
|
|
2310
|
+
targetView.setInt16(position, value, true);
|
|
2311
|
+
updatedPosition = position + 2;
|
|
2312
|
+
return nextTransition;
|
|
2313
|
+
}
|
|
2314
|
+
if (nextTransition = transition.num32) {
|
|
2315
|
+
targetView.setUint32(position, 0xe0000100 + value, true);
|
|
2316
|
+
updatedPosition = position + 4;
|
|
2317
|
+
return nextTransition;
|
|
2318
|
+
}
|
|
2319
|
+
// transition.float64
|
|
2320
|
+
if (nextTransition = transition.num64) {
|
|
2321
|
+
targetView.setFloat64(position, NaN, true);
|
|
2322
|
+
targetView.setInt8(position, value);
|
|
2323
|
+
updatedPosition = position + 8;
|
|
2324
|
+
return nextTransition;
|
|
2325
|
+
}
|
|
2326
|
+
updatedPosition = position;
|
|
2327
|
+
// TODO: can we do an "any" type where we defer the decision?
|
|
2328
|
+
return;
|
|
2329
|
+
}
|
|
2330
|
+
function createTypeTransition(transition, type, size) {
|
|
2331
|
+
let typeName = TYPE_NAMES[type] + (size << 3);
|
|
2332
|
+
let newTransition = transition[typeName] || (transition[typeName] = Object.create(null));
|
|
2333
|
+
newTransition.__type = type;
|
|
2334
|
+
newTransition.__size = size;
|
|
2335
|
+
newTransition.__parent = transition;
|
|
2336
|
+
return newTransition;
|
|
2337
|
+
}
|
|
2338
|
+
function onLoadedStructures$1(sharedData) {
|
|
2339
|
+
if (!(sharedData instanceof Map))
|
|
2340
|
+
return sharedData;
|
|
2341
|
+
let typed = sharedData.get('typed') || [];
|
|
2342
|
+
let named = sharedData.get('named');
|
|
2343
|
+
let transitions = Object.create(null);
|
|
2344
|
+
for (let i = 0, l = typed.length; i < l; i++) {
|
|
2345
|
+
let structure = typed[i];
|
|
2346
|
+
let transition = transitions;
|
|
2347
|
+
for (let [type, size, key] of structure) {
|
|
2348
|
+
let nextTransition = transition[key];
|
|
2349
|
+
if (!nextTransition) {
|
|
2350
|
+
transition[key] = nextTransition = {
|
|
2351
|
+
key,
|
|
2352
|
+
parent: transition,
|
|
2353
|
+
enumerationOffset: 0,
|
|
2354
|
+
ascii0: null,
|
|
2355
|
+
ascii8: null,
|
|
2356
|
+
num8: null,
|
|
2357
|
+
string16: null,
|
|
2358
|
+
object16: null,
|
|
2359
|
+
num32: null,
|
|
2360
|
+
float64: null
|
|
2361
|
+
};
|
|
2362
|
+
}
|
|
2363
|
+
transition = createTypeTransition(nextTransition, type, size);
|
|
2364
|
+
}
|
|
2365
|
+
transition[RECORD_SYMBOL] = i;
|
|
2366
|
+
}
|
|
2367
|
+
typed.transitions = transitions;
|
|
2368
|
+
this.typedStructs = typed;
|
|
2369
|
+
return named;
|
|
2074
2370
|
}
|
|
2075
2371
|
var sourceSymbol = Symbol('source');
|
|
2076
|
-
function readStruct$1(src, position, srcEnd,
|
|
2077
|
-
|
|
2372
|
+
function readStruct$1(src, position, srcEnd, unpackr) {
|
|
2373
|
+
// var stringLength = (src[position++] << 8) | src[position++];
|
|
2374
|
+
let recordId = src[position++] - 0x20;
|
|
2375
|
+
if (recordId >= 24) {
|
|
2376
|
+
switch(recordId) {
|
|
2377
|
+
case 24: recordId = src[position++]; break;
|
|
2378
|
+
// little endian:
|
|
2379
|
+
case 25: recordId = src[position++] + (src[position++] << 8); break;
|
|
2380
|
+
case 26: recordId = src[position++] + (src[position++] << 8) + (src[position++] << 16); break;
|
|
2381
|
+
case 27: recordId = src[position++] + (src[position++] << 8) + (src[position++] << 16) + (src[position++] << 24); break;
|
|
2382
|
+
}
|
|
2383
|
+
}
|
|
2384
|
+
let structure = unpackr.typedStructs?.[recordId];
|
|
2385
|
+
if (!structure) {
|
|
2386
|
+
// copy src buffer because getStructures will override it
|
|
2387
|
+
src = Uint8Array.prototype.slice.call(src, position, srcEnd);
|
|
2388
|
+
srcEnd -= position;
|
|
2389
|
+
position = 0;
|
|
2390
|
+
unpackr._mergeStructures(unpackr.getStructures());
|
|
2391
|
+
if (!unpackr.typedStructs)
|
|
2392
|
+
throw new Error('Could not find any shared typed structures');
|
|
2393
|
+
unpackr.lastTypedStructuresLength = unpackr.typedStructs.length;
|
|
2394
|
+
structure = unpackr.typedStructs[recordId];
|
|
2395
|
+
if (!structure)
|
|
2396
|
+
throw new Error('Could not find typed structure ' + recordId);
|
|
2397
|
+
}
|
|
2078
2398
|
var construct = structure.construct;
|
|
2079
2399
|
if (!construct) {
|
|
2080
2400
|
construct = structure.construct = function() {
|
|
@@ -2092,81 +2412,228 @@
|
|
|
2092
2412
|
},
|
|
2093
2413
|
// not enumerable or anything
|
|
2094
2414
|
});
|
|
2415
|
+
let currentOffset = 0;
|
|
2416
|
+
let lastRefProperty;
|
|
2417
|
+
let properties = [];
|
|
2095
2418
|
for (let i = 0, l = structure.length; i < l; i++) {
|
|
2096
|
-
let
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2419
|
+
let definition = structure[i];
|
|
2420
|
+
let [ type, size, key, enumerationOffset ] = definition;
|
|
2421
|
+
let property = {
|
|
2422
|
+
key,
|
|
2423
|
+
offset: currentOffset,
|
|
2424
|
+
};
|
|
2425
|
+
if (enumerationOffset)
|
|
2426
|
+
properties.splice(i + enumerationOffset, 0, property);
|
|
2427
|
+
else
|
|
2428
|
+
properties.push(property);
|
|
2429
|
+
let getRef;
|
|
2430
|
+
switch(size) { // TODO: Move into a separate function
|
|
2431
|
+
case 0: getRef = () => 0; break;
|
|
2432
|
+
case 1:
|
|
2433
|
+
getRef = (source, position) => {
|
|
2434
|
+
let ref = source.src[position + property.offset];
|
|
2435
|
+
return ref >= 0xf6 ? toConstant(ref) : ref;
|
|
2436
|
+
};
|
|
2437
|
+
break;
|
|
2438
|
+
case 2:
|
|
2439
|
+
getRef = (source, position) => {
|
|
2440
|
+
let src = source.src;
|
|
2441
|
+
let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
|
|
2442
|
+
let ref = dataView.getUint16(position + property.offset, true);
|
|
2443
|
+
return ref >= 0xff00 ? toConstant(ref & 0xff) : ref;
|
|
2444
|
+
};
|
|
2445
|
+
break;
|
|
2446
|
+
case 4:
|
|
2447
|
+
getRef = (source, position) => {
|
|
2448
|
+
let src = source.src;
|
|
2449
|
+
let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
|
|
2450
|
+
let ref = dataView.getUint32(position + property.offset, true);
|
|
2451
|
+
return ref >= 0xffffff00 ? toConstant(ref & 0xff) : ref;
|
|
2452
|
+
};
|
|
2453
|
+
break;
|
|
2454
|
+
}
|
|
2455
|
+
property.getRef = getRef;
|
|
2456
|
+
currentOffset += size;
|
|
2457
|
+
let get;
|
|
2458
|
+
switch(type) {
|
|
2459
|
+
case ASCII:
|
|
2460
|
+
if (lastRefProperty && !lastRefProperty.next)
|
|
2461
|
+
lastRefProperty.next = property;
|
|
2462
|
+
lastRefProperty = property;
|
|
2463
|
+
property.multiGetCount = 0;
|
|
2464
|
+
get = function() {
|
|
2465
|
+
let source = this[sourceSymbol];
|
|
2466
|
+
let src = source.src;
|
|
2467
|
+
let position = source.position;
|
|
2468
|
+
let refStart = currentOffset + position;
|
|
2469
|
+
let ref = getRef(source, position);
|
|
2470
|
+
if (typeof ref !== 'number') return ref;
|
|
2471
|
+
|
|
2472
|
+
let end, next = property.next;
|
|
2473
|
+
while(next) {
|
|
2474
|
+
end = next.getRef(source, position);
|
|
2475
|
+
if (typeof end === 'number')
|
|
2476
|
+
break;
|
|
2477
|
+
else
|
|
2478
|
+
end = null;
|
|
2479
|
+
next = next.next;
|
|
2480
|
+
}
|
|
2481
|
+
if (end == null)
|
|
2482
|
+
end = srcEnd - refStart;
|
|
2483
|
+
if (source.srcString) {
|
|
2484
|
+
return source.srcString.slice(ref, end);
|
|
2485
|
+
}
|
|
2486
|
+
/*if (property.multiGetCount > 0) {
|
|
2487
|
+
let asciiEnd;
|
|
2488
|
+
next = firstRefProperty;
|
|
2489
|
+
let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
|
|
2490
|
+
do {
|
|
2491
|
+
asciiEnd = dataView.getUint16(source.position + next.offset, true);
|
|
2492
|
+
if (asciiEnd < 0xff00)
|
|
2128
2493
|
break;
|
|
2494
|
+
else
|
|
2495
|
+
asciiEnd = null;
|
|
2496
|
+
} while((next = next.next));
|
|
2497
|
+
if (asciiEnd == null)
|
|
2498
|
+
asciiEnd = srcEnd - refStart
|
|
2499
|
+
source.srcString = src.toString('latin1', refStart, refStart + asciiEnd);
|
|
2500
|
+
return source.srcString.slice(ref, end);
|
|
2501
|
+
}
|
|
2502
|
+
if (source.prevStringGet) {
|
|
2503
|
+
source.prevStringGet.multiGetCount += 2;
|
|
2504
|
+
} else {
|
|
2505
|
+
source.prevStringGet = property;
|
|
2506
|
+
property.multiGetCount--;
|
|
2507
|
+
}*/
|
|
2508
|
+
return readString(src, ref + refStart, end - ref);
|
|
2509
|
+
//return src.toString('latin1', ref + refStart, end + refStart);
|
|
2510
|
+
};
|
|
2511
|
+
break;
|
|
2512
|
+
case UTF8: case OBJECT_DATA:
|
|
2513
|
+
if (lastRefProperty && !lastRefProperty.next)
|
|
2514
|
+
lastRefProperty.next = property;
|
|
2515
|
+
lastRefProperty = property;
|
|
2516
|
+
get = function() {
|
|
2517
|
+
let source = this[sourceSymbol];
|
|
2518
|
+
let position = source.position;
|
|
2519
|
+
let refStart = currentOffset + position;
|
|
2520
|
+
let ref = getRef(source, position);
|
|
2521
|
+
if (typeof ref !== 'number') return ref;
|
|
2522
|
+
let src = source.src;
|
|
2523
|
+
let end, next = property.next;
|
|
2524
|
+
while(next) {
|
|
2525
|
+
end = next.getRef(source, position);
|
|
2526
|
+
if (typeof end === 'number')
|
|
2527
|
+
break;
|
|
2528
|
+
else
|
|
2529
|
+
end = null;
|
|
2530
|
+
next = next.next;
|
|
2531
|
+
}
|
|
2532
|
+
if (end == null)
|
|
2533
|
+
end = srcEnd - refStart;
|
|
2534
|
+
if (type === UTF8) {
|
|
2535
|
+
return src.toString('utf8', ref + refStart, end + refStart);
|
|
2536
|
+
} else {
|
|
2537
|
+
return unpackr.unpack(src, { start: ref + refStart, end: end + refStart }); // could reuse this object
|
|
2538
|
+
}
|
|
2539
|
+
};
|
|
2540
|
+
break;
|
|
2541
|
+
case NUMBER:
|
|
2542
|
+
switch(size) {
|
|
2543
|
+
case 4:
|
|
2544
|
+
get = function () {
|
|
2545
|
+
let source = this[sourceSymbol];
|
|
2546
|
+
let src = source.src;
|
|
2547
|
+
let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
|
|
2548
|
+
let position = source.position + property.offset;
|
|
2549
|
+
let value = dataView.getInt32(position, true);
|
|
2550
|
+
if (value < 0x20000000) {
|
|
2551
|
+
if (value > -0x1f000000)
|
|
2552
|
+
return value;
|
|
2553
|
+
if (value > -0x20000000)
|
|
2554
|
+
return toConstant(value & 0xff);
|
|
2129
2555
|
}
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2556
|
+
let fValue = dataView.getFloat32(position, true);
|
|
2557
|
+
// this does rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
|
|
2558
|
+
let multiplier = mult10[((src[position + 3] & 0x7f) << 1) | (src[position + 2] >> 7)];
|
|
2559
|
+
return ((multiplier * fValue + (fValue > 0 ? 0.5 : -0.5)) >> 0) / multiplier;
|
|
2560
|
+
};
|
|
2561
|
+
break;
|
|
2562
|
+
case 8:
|
|
2563
|
+
get = function () {
|
|
2564
|
+
let source = this[sourceSymbol];
|
|
2565
|
+
let src = source.src;
|
|
2566
|
+
let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
|
|
2567
|
+
let value = dataView.getFloat64(source.position + property.offset, true);
|
|
2568
|
+
if (isNaN(value)) {
|
|
2569
|
+
let byte = src[source.position + property.offset];
|
|
2570
|
+
if (byte >= 0xf6)
|
|
2571
|
+
return toConstant(byte);
|
|
2572
|
+
}
|
|
2573
|
+
return value;
|
|
2574
|
+
};
|
|
2575
|
+
break;
|
|
2576
|
+
case 1:
|
|
2577
|
+
get = function () {
|
|
2578
|
+
let source = this[sourceSymbol];
|
|
2579
|
+
let src = source.src;
|
|
2580
|
+
let value = src[source.position + property.offset];
|
|
2581
|
+
return value < 0xf6 ? value : toConstant(value);
|
|
2582
|
+
};
|
|
2583
|
+
break;
|
|
2150
2584
|
}
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
});
|
|
2585
|
+
}
|
|
2586
|
+
property.get = get;
|
|
2154
2587
|
}
|
|
2588
|
+
for (let property of properties) // assign in enumeration order
|
|
2589
|
+
Object.defineProperty(prototype, property.key, { get: property.get, enumerable: true });
|
|
2155
2590
|
}
|
|
2156
2591
|
var instance = new construct();
|
|
2157
2592
|
instance[sourceSymbol] = {
|
|
2158
2593
|
src,
|
|
2159
|
-
uint32: src.uint32,
|
|
2160
2594
|
position,
|
|
2161
2595
|
srcString: '',
|
|
2162
|
-
srcEnd
|
|
2163
|
-
stringLength
|
|
2596
|
+
srcEnd
|
|
2164
2597
|
};
|
|
2165
2598
|
return instance;
|
|
2166
2599
|
}
|
|
2167
|
-
|
|
2600
|
+
function toConstant(code) {
|
|
2601
|
+
switch(code) {
|
|
2602
|
+
case 0xf6: return null;
|
|
2603
|
+
case 0xf7: return undefined;
|
|
2604
|
+
case 0xf8: return false;
|
|
2605
|
+
case 0xf9: return true;
|
|
2606
|
+
}
|
|
2607
|
+
throw new Error('Unknown constant');
|
|
2608
|
+
}
|
|
2609
|
+
function prepareStructures$1(structures, packr) {
|
|
2610
|
+
if (!packr.typedStructs)
|
|
2611
|
+
return structures;
|
|
2612
|
+
let structMap = new Map();
|
|
2613
|
+
structMap.set('named', structures);
|
|
2614
|
+
structMap.set('typed', packr.typedStructs);
|
|
2615
|
+
let lastTypedStructuresLength = packr.lastTypedStructuresLength || 0;
|
|
2616
|
+
structMap.isCompatible = existing => {
|
|
2617
|
+
if (existing instanceof Map) {
|
|
2618
|
+
let named = existing.get('named') || [];
|
|
2619
|
+
if (named.length !== (packr.lastNamedStructuresLength || 0))
|
|
2620
|
+
return false;
|
|
2621
|
+
let typed = existing.get('typed') || [];
|
|
2622
|
+
if (typed.length !== lastTypedStructuresLength)
|
|
2623
|
+
return false;
|
|
2624
|
+
} else if (existing instanceof Array) {
|
|
2625
|
+
if (existing.length !== (packr.lastNamedStructuresLength || 0))
|
|
2626
|
+
return false;
|
|
2627
|
+
}
|
|
2628
|
+
return true;
|
|
2629
|
+
};
|
|
2630
|
+
packr.lastTypedStructuresLength = packr.typedStructs?.length;
|
|
2631
|
+
return structMap;
|
|
2632
|
+
}
|
|
2633
|
+
|
|
2634
|
+
setReadStruct(readStruct$1, onLoadedStructures$1);
|
|
2168
2635
|
|
|
2169
|
-
|
|
2636
|
+
let allSampleData = [];
|
|
2170
2637
|
for (let i = 1; i < 6; i++) {
|
|
2171
2638
|
allSampleData.push(JSON.parse(fs.readFileSync(new URL(`./example${i > 1 ? i : ''}.json`, (document.currentScript && document.currentScript.src || new URL('test.js', document.baseURI).href)))));
|
|
2172
2639
|
}
|
|
@@ -2178,6 +2645,13 @@
|
|
|
2178
2645
|
return {}
|
|
2179
2646
|
}
|
|
2180
2647
|
}
|
|
2648
|
+
|
|
2649
|
+
let seed = 0;
|
|
2650
|
+
function random() {
|
|
2651
|
+
seed++;
|
|
2652
|
+
let a = seed * 15485863;
|
|
2653
|
+
return (a * a * a % 2038074743) / 2038074743;
|
|
2654
|
+
}
|
|
2181
2655
|
//if (typeof chai === 'undefined') { chai = require('chai') }
|
|
2182
2656
|
var assert = chai.assert;
|
|
2183
2657
|
//if (typeof msgpackr === 'undefined') { msgpackr = require('..') }
|
|
@@ -2276,6 +2750,36 @@
|
|
|
2276
2750
|
var deserialized = unpack(serialized);
|
|
2277
2751
|
assert.equal(deserialized, data);
|
|
2278
2752
|
});
|
|
2753
|
+
test('pack/unpack varying data with random access structures', function() {
|
|
2754
|
+
let structures = [];
|
|
2755
|
+
let packr = new Packr$1({ structures, useRecords: true, randomAccessStructure: true, freezeData: true, saveStructures(structures) {
|
|
2756
|
+
}, getStructures() {
|
|
2757
|
+
console.log('getStructures');
|
|
2758
|
+
} });
|
|
2759
|
+
for (let i = 0; i < 20; i++) {
|
|
2760
|
+
let data = {};
|
|
2761
|
+
let props = ['foo', 'bar', 'a', 'b', 'c','name', 'age', 'd'];
|
|
2762
|
+
function makeString() {
|
|
2763
|
+
let str = '';
|
|
2764
|
+
while (random() < 0.9) {
|
|
2765
|
+
str += random() < 0.8 ? 'hello world' : String.fromCharCode(300);
|
|
2766
|
+
}
|
|
2767
|
+
return str;
|
|
2768
|
+
}
|
|
2769
|
+
for (let i = 0; i < random() * 20; i++) {
|
|
2770
|
+
data[props[Math.floor(random() * 8)]] =
|
|
2771
|
+
random() < 0.3 ? Math.floor(random() * 400) / 2 :
|
|
2772
|
+
random() < 0.3 ? makeString() : random() < 0.3 ? true : random() < 0.3 ? sampleData : null;
|
|
2773
|
+
}
|
|
2774
|
+
var serialized = packr.pack(data);
|
|
2775
|
+
var deserialized = packr.unpack(serialized);
|
|
2776
|
+
for (let key in deserialized) {
|
|
2777
|
+
let a = deserialized[key];
|
|
2778
|
+
}
|
|
2779
|
+
assert.deepEqual(deserialized, data);
|
|
2780
|
+
}
|
|
2781
|
+
});
|
|
2782
|
+
|
|
2279
2783
|
for (let sampleData of allSampleData) {
|
|
2280
2784
|
let snippet = JSON.stringify(sampleData).slice(0, 20) + '...';
|
|
2281
2785
|
test('pack/unpack sample data ' + snippet, function(){
|
|
@@ -2290,11 +2794,18 @@
|
|
|
2290
2794
|
test('pack/unpack sample data with random access structures ' + snippet, function() {
|
|
2291
2795
|
var data = sampleData;
|
|
2292
2796
|
let structures = [];
|
|
2293
|
-
let packr = new Packr$1({ structures, useRecords: true, randomAccessStructure: true, freezeData: true
|
|
2797
|
+
let packr = new Packr$1({ structures, useRecords: true, randomAccessStructure: true, freezeData: true, saveStructures(structures) {
|
|
2798
|
+
}, getStructures() {
|
|
2799
|
+
console.log('getStructures');
|
|
2800
|
+
} });
|
|
2294
2801
|
for (let i = 0; i < 20; i++) {
|
|
2295
2802
|
var serialized = packr.pack(data);
|
|
2296
2803
|
var deserialized = packr.unpack(serialized);
|
|
2297
|
-
|
|
2804
|
+
var copied = {};
|
|
2805
|
+
for (let key in deserialized) {
|
|
2806
|
+
copied[key] = deserialized[key];
|
|
2807
|
+
}
|
|
2808
|
+
assert.deepEqual(copied, data);
|
|
2298
2809
|
}
|
|
2299
2810
|
});
|
|
2300
2811
|
test('pack/unpack sample data with bundled strings ' + snippet, function(){
|
|
@@ -2304,6 +2815,7 @@
|
|
|
2304
2815
|
var deserialized = packr.unpack(serialized);
|
|
2305
2816
|
assert.deepEqual(deserialized, data);
|
|
2306
2817
|
});
|
|
2818
|
+
break;
|
|
2307
2819
|
}
|
|
2308
2820
|
|
|
2309
2821
|
test('pack/unpack empty data with bundled strings', function(){
|
|
@@ -2886,5 +3398,5 @@
|
|
|
2886
3398
|
});
|
|
2887
3399
|
});
|
|
2888
3400
|
|
|
2889
|
-
}(msgpackr, chai, fs));
|
|
3401
|
+
}(msgpackr, chai, inspector, fs));
|
|
2890
3402
|
//# sourceMappingURL=test.js.map
|