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