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