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/node.cjs
CHANGED
|
@@ -33,7 +33,7 @@ const C1 = new C1Type();
|
|
|
33
33
|
C1.name = 'MessagePack 0xC1';
|
|
34
34
|
var sequentialMode = false;
|
|
35
35
|
var inlineObjectReadThreshold = 2;
|
|
36
|
-
var readStruct;
|
|
36
|
+
var readStruct, onLoadedStructures;
|
|
37
37
|
try {
|
|
38
38
|
new Function('');
|
|
39
39
|
} catch(error) {
|
|
@@ -63,16 +63,21 @@ class Unpackr {
|
|
|
63
63
|
}
|
|
64
64
|
Object.assign(this, options);
|
|
65
65
|
}
|
|
66
|
-
unpack(source,
|
|
66
|
+
unpack(source, options) {
|
|
67
67
|
if (src) {
|
|
68
68
|
// re-entrant execution, save the state and restore it after we do this unpack
|
|
69
69
|
return saveState(() => {
|
|
70
70
|
clearSource();
|
|
71
|
-
return this ? this.unpack(source,
|
|
71
|
+
return this ? this.unpack(source, options) : Unpackr.prototype.unpack.call(defaultOptions, source, options)
|
|
72
72
|
})
|
|
73
73
|
}
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
if (typeof options === 'object') {
|
|
75
|
+
srcEnd = options.end || source.length;
|
|
76
|
+
position = options.start || 0;
|
|
77
|
+
} else {
|
|
78
|
+
position = 0;
|
|
79
|
+
srcEnd = options > -1 ? options : source.length;
|
|
80
|
+
}
|
|
76
81
|
stringPosition = 0;
|
|
77
82
|
srcStringEnd = 0;
|
|
78
83
|
srcString = null;
|
|
@@ -95,7 +100,7 @@ class Unpackr {
|
|
|
95
100
|
currentUnpackr = this;
|
|
96
101
|
if (this.structures) {
|
|
97
102
|
currentStructures = this.structures;
|
|
98
|
-
return checkedRead()
|
|
103
|
+
return checkedRead(options)
|
|
99
104
|
} else if (!currentStructures || currentStructures.length > 0) {
|
|
100
105
|
currentStructures = [];
|
|
101
106
|
}
|
|
@@ -104,7 +109,7 @@ class Unpackr {
|
|
|
104
109
|
if (!currentStructures || currentStructures.length > 0)
|
|
105
110
|
currentStructures = [];
|
|
106
111
|
}
|
|
107
|
-
return checkedRead()
|
|
112
|
+
return checkedRead(options)
|
|
108
113
|
}
|
|
109
114
|
unpackMultiple(source, forEach) {
|
|
110
115
|
let values, lastPosition = 0;
|
|
@@ -139,7 +144,11 @@ class Unpackr {
|
|
|
139
144
|
}
|
|
140
145
|
}
|
|
141
146
|
_mergeStructures(loadedStructures, existingStructures) {
|
|
147
|
+
if (onLoadedStructures)
|
|
148
|
+
loadedStructures = onLoadedStructures.call(this, loadedStructures);
|
|
142
149
|
loadedStructures = loadedStructures || [];
|
|
150
|
+
if (Object.isFrozen(loadedStructures))
|
|
151
|
+
loadedStructures = loadedStructures.map(structure => structure.slice(0));
|
|
143
152
|
for (let i = 0, l = loadedStructures.length; i < l; i++) {
|
|
144
153
|
let structure = loadedStructures[i];
|
|
145
154
|
if (structure) {
|
|
@@ -166,7 +175,7 @@ class Unpackr {
|
|
|
166
175
|
return this.unpack(source, end)
|
|
167
176
|
}
|
|
168
177
|
}
|
|
169
|
-
function checkedRead() {
|
|
178
|
+
function checkedRead(options) {
|
|
170
179
|
try {
|
|
171
180
|
if (!currentUnpackr.trusted && !sequentialMode) {
|
|
172
181
|
let sharedLength = currentStructures.sharedLength || 0;
|
|
@@ -174,9 +183,10 @@ function checkedRead() {
|
|
|
174
183
|
currentStructures.length = sharedLength;
|
|
175
184
|
}
|
|
176
185
|
let result;
|
|
177
|
-
if (currentUnpackr.randomAccessStructure && src[position] < 0x40 && readStruct) {
|
|
178
|
-
|
|
179
|
-
|
|
186
|
+
if (currentUnpackr.randomAccessStructure && src[position] < 0x40 && src[position] >= 0x20 && readStruct) {
|
|
187
|
+
result = readStruct(src, position, srcEnd, currentUnpackr);
|
|
188
|
+
if (!(options && options.lazy) && result)
|
|
189
|
+
result = result.toJSON();
|
|
180
190
|
position = srcEnd;
|
|
181
191
|
} else
|
|
182
192
|
result = read();
|
|
@@ -612,6 +622,16 @@ function readStringJS(length) {
|
|
|
612
622
|
|
|
613
623
|
return result
|
|
614
624
|
}
|
|
625
|
+
function readString(source, start, length) {
|
|
626
|
+
let existingSrc = src;
|
|
627
|
+
src = source;
|
|
628
|
+
position = start;
|
|
629
|
+
try {
|
|
630
|
+
return readStringJS(length);
|
|
631
|
+
} finally {
|
|
632
|
+
src = existingSrc;
|
|
633
|
+
}
|
|
634
|
+
}
|
|
615
635
|
|
|
616
636
|
function readArray(length) {
|
|
617
637
|
let array = new Array(length);
|
|
@@ -832,7 +852,15 @@ function readBin(length) {
|
|
|
832
852
|
function readExt(length) {
|
|
833
853
|
let type = src[position++];
|
|
834
854
|
if (currentExtensions[type]) {
|
|
835
|
-
|
|
855
|
+
let end;
|
|
856
|
+
return currentExtensions[type](src.subarray(position, end = (position += length)), (readPosition) => {
|
|
857
|
+
position = readPosition;
|
|
858
|
+
try {
|
|
859
|
+
return read();
|
|
860
|
+
} finally {
|
|
861
|
+
position = end;
|
|
862
|
+
}
|
|
863
|
+
})
|
|
836
864
|
}
|
|
837
865
|
else
|
|
838
866
|
throw new Error('Unknown extension type ' + type)
|
|
@@ -1075,8 +1103,9 @@ function roundFloat32(float32Number) {
|
|
|
1075
1103
|
let multiplier = mult10[((u8Array[3] & 0x7f) << 1) | (u8Array[2] >> 7)];
|
|
1076
1104
|
return ((multiplier * float32Number + (float32Number > 0 ? 0.5 : -0.5)) >> 0) / multiplier
|
|
1077
1105
|
}
|
|
1078
|
-
function setReadStruct(
|
|
1079
|
-
readStruct =
|
|
1106
|
+
function setReadStruct(updatedReadStruct, loadedStructs) {
|
|
1107
|
+
readStruct = updatedReadStruct;
|
|
1108
|
+
onLoadedStructures = loadedStructs;
|
|
1080
1109
|
}
|
|
1081
1110
|
|
|
1082
1111
|
let textEncoder;
|
|
@@ -1106,7 +1135,6 @@ class Packr extends Unpackr {
|
|
|
1106
1135
|
let hasSharedUpdate;
|
|
1107
1136
|
let structures;
|
|
1108
1137
|
let referenceMap;
|
|
1109
|
-
let lastSharedStructuresLength = 0;
|
|
1110
1138
|
let encodeUtf8 = ByteArray.prototype.utf8Write ? function(string, position) {
|
|
1111
1139
|
return target.utf8Write(string, position, 0xffffffff)
|
|
1112
1140
|
} : (textEncoder && textEncoder.encodeInto) ?
|
|
@@ -1192,7 +1220,7 @@ class Packr extends Unpackr {
|
|
|
1192
1220
|
}
|
|
1193
1221
|
transition[RECORD_SYMBOL] = i + 0x40;
|
|
1194
1222
|
}
|
|
1195
|
-
|
|
1223
|
+
this.lastNamedStructuresLength = sharedLength;
|
|
1196
1224
|
}
|
|
1197
1225
|
if (!isSequential) {
|
|
1198
1226
|
structures.nextId = sharedLength + 0x40;
|
|
@@ -1228,7 +1256,7 @@ class Packr extends Unpackr {
|
|
|
1228
1256
|
if (structures) {
|
|
1229
1257
|
if (serializationsSinceTransitionRebuild < 10)
|
|
1230
1258
|
serializationsSinceTransitionRebuild++;
|
|
1231
|
-
let sharedLength = structures.sharedLength ||
|
|
1259
|
+
let sharedLength = structures.sharedLength || 0;
|
|
1232
1260
|
if (structures.length > sharedLength)
|
|
1233
1261
|
structures.length = sharedLength;
|
|
1234
1262
|
if (transitionsCount > 10000) {
|
|
@@ -1247,12 +1275,12 @@ class Packr extends Unpackr {
|
|
|
1247
1275
|
if (hasSharedUpdate && packr.saveStructures) {
|
|
1248
1276
|
// we can't rely on start/end with REUSE_BUFFER_MODE since they will (probably) change when we save
|
|
1249
1277
|
let returnBuffer = target.subarray(start, position$1);
|
|
1250
|
-
|
|
1278
|
+
let newSharedData = prepareStructures(structures, packr);
|
|
1279
|
+
if (packr.saveStructures(newSharedData, newSharedData.isCompatible) === false) {
|
|
1251
1280
|
// get updated structures and try again if the update failed
|
|
1252
|
-
packr._mergeStructures(packr.getStructures());
|
|
1253
1281
|
return packr.pack(value)
|
|
1254
1282
|
}
|
|
1255
|
-
|
|
1283
|
+
packr.lastNamedStructuresLength = sharedLength;
|
|
1256
1284
|
return returnBuffer
|
|
1257
1285
|
}
|
|
1258
1286
|
}
|
|
@@ -1370,7 +1398,7 @@ class Packr extends Unpackr {
|
|
|
1370
1398
|
} else if (type === 'number') {
|
|
1371
1399
|
if (value >>> 0 === value) {// positive integer, 32-bit or less
|
|
1372
1400
|
// positive uint
|
|
1373
|
-
if (value <
|
|
1401
|
+
if (value < 0x20 || (value < 0x80 && this.useRecords === false) || (value < 0x40 && !this.randomAccessStructure)) {
|
|
1374
1402
|
target[position$1++] = value;
|
|
1375
1403
|
} else if (value < 0x100) {
|
|
1376
1404
|
target[position$1++] = 0xcc;
|
|
@@ -1770,16 +1798,18 @@ class Packr extends Unpackr {
|
|
|
1770
1798
|
}
|
|
1771
1799
|
};
|
|
1772
1800
|
const writeStruct = (object, safePrototype) => {
|
|
1773
|
-
let newPosition = writeStructSlots(object, target, position$1, structures, makeRoom, (value, newPosition) => {
|
|
1801
|
+
let newPosition = writeStructSlots(object, target, position$1, structures, makeRoom, (value, newPosition, notifySharedUpdate) => {
|
|
1802
|
+
if (notifySharedUpdate)
|
|
1803
|
+
return hasSharedUpdate = true;
|
|
1774
1804
|
position$1 = newPosition;
|
|
1775
1805
|
if (start > 0) {
|
|
1776
1806
|
pack(value);
|
|
1777
1807
|
if (start == 0)
|
|
1778
|
-
return { position: position$1, targetView }; // indicate the buffer was re-allocated
|
|
1808
|
+
return { position: position$1, targetView, target }; // indicate the buffer was re-allocated
|
|
1779
1809
|
} else
|
|
1780
1810
|
pack(value);
|
|
1781
1811
|
return position$1;
|
|
1782
|
-
});
|
|
1812
|
+
}, this);
|
|
1783
1813
|
if (newPosition === 0) // bail and go to a msgpack object
|
|
1784
1814
|
return writeObject(object, true);
|
|
1785
1815
|
position$1 = newPosition;
|
|
@@ -1794,6 +1824,8 @@ class Packr extends Unpackr {
|
|
|
1794
1824
|
clearSharedData() {
|
|
1795
1825
|
if (this.structures)
|
|
1796
1826
|
this.structures = [];
|
|
1827
|
+
if (this.typedStructs)
|
|
1828
|
+
this.typedStructs = [];
|
|
1797
1829
|
}
|
|
1798
1830
|
}
|
|
1799
1831
|
|
|
@@ -2013,8 +2045,18 @@ function addExtension$1(extension) {
|
|
|
2013
2045
|
}
|
|
2014
2046
|
addExtension(extension);
|
|
2015
2047
|
}
|
|
2016
|
-
function
|
|
2017
|
-
|
|
2048
|
+
function prepareStructures(structures, packr) {
|
|
2049
|
+
structures.isCompatible = (existingStructures) => {
|
|
2050
|
+
let compatible = !existingStructures || ((packr.lastNamedStructuresLength || 0) === existingStructures.length);
|
|
2051
|
+
if (!compatible) // we want to merge these existing structures immediately since we already have it and we are in the right transaction
|
|
2052
|
+
packr._mergeStructures(existingStructures);
|
|
2053
|
+
return compatible;
|
|
2054
|
+
};
|
|
2055
|
+
return structures
|
|
2056
|
+
}
|
|
2057
|
+
function setWriteStructSlots(writeSlots, makeStructures) {
|
|
2058
|
+
writeStructSlots = writeSlots;
|
|
2059
|
+
prepareStructures = makeStructures;
|
|
2018
2060
|
}
|
|
2019
2061
|
|
|
2020
2062
|
let defaultPackr = new Packr({ useRecords: false });
|
|
@@ -2025,374 +2067,816 @@ const { NEVER, ALWAYS, DECIMAL_ROUND, DECIMAL_FIT } = FLOAT32_OPTIONS;
|
|
|
2025
2067
|
const REUSE_BUFFER_MODE = 512;
|
|
2026
2068
|
const RESET_BUFFER_MODE = 1024;
|
|
2027
2069
|
|
|
2028
|
-
//
|
|
2029
|
-
const
|
|
2070
|
+
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)
|
|
2071
|
+
const NUMBER = 0;
|
|
2072
|
+
const UTF8 = 2;
|
|
2073
|
+
const OBJECT_DATA = 1;
|
|
2074
|
+
const TYPE_NAMES = ['num', 'object', 'string', 'ascii'];
|
|
2030
2075
|
const float32Headers = [false, true, true, false, false, true, true, false];
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2076
|
+
let updatedPosition;
|
|
2077
|
+
const hasNodeBuffer$1 = typeof Buffer !== 'undefined';
|
|
2078
|
+
let textEncoder$1;
|
|
2079
|
+
try {
|
|
2080
|
+
textEncoder$1 = new TextEncoder();
|
|
2081
|
+
} catch (error) {}
|
|
2082
|
+
const encodeUtf8 = hasNodeBuffer$1 ? function(target, string, position) {
|
|
2083
|
+
return target.utf8Write(string, position, 0xffffffff)
|
|
2084
|
+
} : (textEncoder$1 && textEncoder$1.encodeInto) ?
|
|
2085
|
+
function(target, string, position) {
|
|
2086
|
+
return textEncoder$1.encodeInto(string, target.subarray(position)).written
|
|
2087
|
+
} : false;
|
|
2088
|
+
setWriteStructSlots(writeStruct, prepareStructures$1);
|
|
2089
|
+
function writeStruct(object, target, position, structures, makeRoom, pack, packr) {
|
|
2090
|
+
let typedStructs = packr.typedStructs || (packr.typedStructs = []);
|
|
2091
|
+
// note that we rely on pack.js to load stored structures before we get to this point
|
|
2038
2092
|
let targetView = target.dataView;
|
|
2039
|
-
let
|
|
2040
|
-
let stringData = '';
|
|
2093
|
+
let refsStartPosition = (typedStructs.lastStringStart || 100) + position;
|
|
2041
2094
|
let safeEnd = target.length - 10;
|
|
2095
|
+
let start = position;
|
|
2096
|
+
if (position > safeEnd) {
|
|
2097
|
+
let lastStart = start;
|
|
2098
|
+
target = makeRoom(position);
|
|
2099
|
+
targetView = target.dataView;
|
|
2100
|
+
position -= lastStart;
|
|
2101
|
+
refsStartPosition -= lastStart;
|
|
2102
|
+
start = 0;
|
|
2103
|
+
safeEnd = target.length - 10;
|
|
2104
|
+
}
|
|
2105
|
+
|
|
2106
|
+
let refOffset, refPosition = refsStartPosition;
|
|
2107
|
+
|
|
2108
|
+
let transition = typedStructs.transitions || (typedStructs.transitions = Object.create(null));
|
|
2109
|
+
let nextId = typedStructs.nextId || typedStructs.length;
|
|
2110
|
+
let headerSize =
|
|
2111
|
+
nextId < 0xf ? 1 :
|
|
2112
|
+
nextId < 0xf0 ? 2 :
|
|
2113
|
+
nextId < 0xf000 ? 3 :
|
|
2114
|
+
nextId < 0xf00000 ? 4 : 0;
|
|
2115
|
+
if (headerSize === 0)
|
|
2116
|
+
return 0;
|
|
2117
|
+
position += headerSize;
|
|
2118
|
+
let queuedReferences = [];
|
|
2119
|
+
let keyIndex = 0;
|
|
2042
2120
|
for (let key in object) {
|
|
2121
|
+
let value = object[key];
|
|
2043
2122
|
let nextTransition = transition[key];
|
|
2044
2123
|
if (!nextTransition) {
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2124
|
+
transition[key] = nextTransition = {
|
|
2125
|
+
key,
|
|
2126
|
+
parent: transition,
|
|
2127
|
+
enumerationOffset: 0,
|
|
2128
|
+
ascii0: null,
|
|
2129
|
+
ascii8: null,
|
|
2130
|
+
num8: null,
|
|
2131
|
+
string16: null,
|
|
2132
|
+
object16: null,
|
|
2133
|
+
num32: null,
|
|
2134
|
+
float64: null
|
|
2135
|
+
};
|
|
2048
2136
|
}
|
|
2049
2137
|
if (position > safeEnd) {
|
|
2050
|
-
let
|
|
2138
|
+
let lastStart = start;
|
|
2051
2139
|
target = makeRoom(position);
|
|
2052
|
-
|
|
2140
|
+
targetView = target.dataView;
|
|
2141
|
+
position -= lastStart;
|
|
2142
|
+
refsStartPosition -= lastStart;
|
|
2143
|
+
refPosition -= lastStart;
|
|
2053
2144
|
start = 0;
|
|
2054
2145
|
safeEnd = target.length - 10;
|
|
2055
2146
|
}
|
|
2056
|
-
transition = nextTransition;
|
|
2057
|
-
let value = object[key];
|
|
2058
2147
|
switch (typeof value) {
|
|
2059
2148
|
case 'number':
|
|
2060
|
-
|
|
2061
|
-
|
|
2149
|
+
let number = value;
|
|
2150
|
+
if (number >> 0 === number && number < 0x20000000 && number > -0x1f000000) {
|
|
2151
|
+
if (number < 0xf6 && number >= 0 && (nextTransition.num8 || number < 0x20 && !nextTransition.num32)) {
|
|
2152
|
+
transition = nextTransition.num8 || createTypeTransition(nextTransition, NUMBER, 1);
|
|
2153
|
+
target[position++] = number;
|
|
2154
|
+
} else {
|
|
2155
|
+
transition = nextTransition.num32 || createTypeTransition(nextTransition, NUMBER, 4);
|
|
2156
|
+
targetView.setUint32(position, number, true);
|
|
2157
|
+
position += 4;
|
|
2158
|
+
}
|
|
2062
2159
|
break;
|
|
2063
|
-
} else if (
|
|
2064
|
-
targetView.setFloat32(position,
|
|
2160
|
+
} else if (number < 0x100000000 && number >= -0x80000000) {
|
|
2161
|
+
targetView.setFloat32(position, number, true);
|
|
2065
2162
|
if (float32Headers[target[position + 3] >>> 5]) {
|
|
2066
2163
|
let xShifted;
|
|
2067
2164
|
// this checks for rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
|
|
2068
|
-
if (((xShifted =
|
|
2165
|
+
if (((xShifted = number * mult10[((target[position + 3] & 0x7f) << 1) | (target[position + 2] >> 7)]) >> 0) === xShifted) {
|
|
2166
|
+
transition = nextTransition.num32 || createTypeTransition(nextTransition, NUMBER, 4);
|
|
2069
2167
|
position += 4;
|
|
2070
|
-
|
|
2168
|
+
break;
|
|
2071
2169
|
}
|
|
2072
2170
|
}
|
|
2073
2171
|
}
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
position +=
|
|
2077
|
-
|
|
2172
|
+
transition = nextTransition.num64 || createTypeTransition(nextTransition, NUMBER, 8);
|
|
2173
|
+
targetView.setFloat64(position, number, true);
|
|
2174
|
+
position += 8;
|
|
2175
|
+
break;
|
|
2078
2176
|
case 'string':
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2177
|
+
let strLength = value.length;
|
|
2178
|
+
refOffset = refPosition - refsStartPosition;
|
|
2179
|
+
if ((strLength << 2) + position > safeEnd) {
|
|
2180
|
+
let lastStart = start;
|
|
2181
|
+
target = makeRoom(refPosition);
|
|
2182
|
+
targetView = target.dataView;
|
|
2183
|
+
position -= lastStart;
|
|
2184
|
+
refsStartPosition -= lastStart;
|
|
2185
|
+
refPosition -= lastStart;
|
|
2186
|
+
start = 0;
|
|
2187
|
+
safeEnd = target.length - 10;
|
|
2083
2188
|
}
|
|
2084
|
-
if (
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
}
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2189
|
+
if (strLength > ((0xff00 + refOffset) >> 2)) {
|
|
2190
|
+
queuedReferences.push(key, value, position - start);
|
|
2191
|
+
break;
|
|
2192
|
+
}
|
|
2193
|
+
let isNotAscii;
|
|
2194
|
+
let strStart = refPosition;
|
|
2195
|
+
if (strLength < 0x40) {
|
|
2196
|
+
let i, c1, c2;
|
|
2197
|
+
for (i = 0; i < strLength; i++) {
|
|
2198
|
+
c1 = value.charCodeAt(i);
|
|
2199
|
+
if (c1 < 0x80) {
|
|
2200
|
+
target[refPosition++] = c1;
|
|
2201
|
+
} else if (c1 < 0x800) {
|
|
2202
|
+
isNotAscii = true;
|
|
2203
|
+
target[refPosition++] = c1 >> 6 | 0xc0;
|
|
2204
|
+
target[refPosition++] = c1 & 0x3f | 0x80;
|
|
2205
|
+
} else if (
|
|
2206
|
+
(c1 & 0xfc00) === 0xd800 &&
|
|
2207
|
+
((c2 = value.charCodeAt(i + 1)) & 0xfc00) === 0xdc00
|
|
2208
|
+
) {
|
|
2209
|
+
isNotAscii = true;
|
|
2210
|
+
c1 = 0x10000 + ((c1 & 0x03ff) << 10) + (c2 & 0x03ff);
|
|
2211
|
+
i++;
|
|
2212
|
+
target[refPosition++] = c1 >> 18 | 0xf0;
|
|
2213
|
+
target[refPosition++] = c1 >> 12 & 0x3f | 0x80;
|
|
2214
|
+
target[refPosition++] = c1 >> 6 & 0x3f | 0x80;
|
|
2215
|
+
target[refPosition++] = c1 & 0x3f | 0x80;
|
|
2216
|
+
} else {
|
|
2217
|
+
isNotAscii = true;
|
|
2218
|
+
target[refPosition++] = c1 >> 12 | 0xe0;
|
|
2219
|
+
target[refPosition++] = c1 >> 6 & 0x3f | 0x80;
|
|
2220
|
+
target[refPosition++] = c1 & 0x3f | 0x80;
|
|
2221
|
+
}
|
|
2222
|
+
}
|
|
2223
|
+
} else {
|
|
2224
|
+
refPosition += encodeUtf8(target, value, refPosition);
|
|
2225
|
+
isNotAscii = refPosition - strStart > strLength;
|
|
2226
|
+
}
|
|
2227
|
+
if (refOffset < 0x100) {
|
|
2228
|
+
if (isNotAscii)
|
|
2229
|
+
transition = nextTransition.string8 || createTypeTransition(nextTransition, UTF8, 1);
|
|
2230
|
+
else
|
|
2231
|
+
transition = nextTransition.ascii8 || createTypeTransition(nextTransition, ASCII, 1);
|
|
2232
|
+
target[position++] = refOffset;
|
|
2233
|
+
} else {
|
|
2234
|
+
if (isNotAscii)
|
|
2235
|
+
transition = nextTransition.string16 || createTypeTransition(nextTransition, UTF8, 2);
|
|
2236
|
+
else
|
|
2237
|
+
transition = nextTransition.ascii16 || createTypeTransition(nextTransition, ASCII, 2);
|
|
2238
|
+
targetView.setUint16(position, refOffset, true);
|
|
2239
|
+
position += 2;
|
|
2095
2240
|
}
|
|
2096
2241
|
break;
|
|
2097
2242
|
case 'object':
|
|
2098
2243
|
if (value) {
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2244
|
+
//transition = nextTransition.object16 || createTypeTransition(nextTransition, OBJECT_DATA, 2);
|
|
2245
|
+
queuedReferences.push(key, value, keyIndex);
|
|
2246
|
+
break;
|
|
2102
2247
|
} else { // null
|
|
2103
|
-
|
|
2248
|
+
nextTransition = anyType(nextTransition, position, targetView, -10); // match CBOR with this
|
|
2249
|
+
if (nextTransition) {
|
|
2250
|
+
transition = nextTransition;
|
|
2251
|
+
position = updatedPosition;
|
|
2252
|
+
} else queuedReferences.push(key, value, keyIndex);
|
|
2104
2253
|
}
|
|
2105
2254
|
break;
|
|
2106
2255
|
case 'boolean':
|
|
2107
|
-
|
|
2256
|
+
transition = nextTransition.num8 || nextTransition.ascii8 || createTypeTransition(nextTransition, NUMBER, 1);
|
|
2257
|
+
target[position++] = value ? 0xf9 : 0xf8; // match CBOR with these
|
|
2108
2258
|
break;
|
|
2109
2259
|
case 'undefined':
|
|
2110
|
-
|
|
2260
|
+
nextTransition = anyType(nextTransition, position, targetView, -9); // match CBOR with this
|
|
2261
|
+
if (nextTransition) {
|
|
2262
|
+
transition = nextTransition;
|
|
2263
|
+
position = updatedPosition;
|
|
2264
|
+
} else queuedReferences.push(key, value, keyIndex);
|
|
2111
2265
|
break;
|
|
2112
2266
|
}
|
|
2113
|
-
|
|
2114
|
-
position += 4;
|
|
2115
|
-
}
|
|
2116
|
-
let recordId = transition[RECORD_SYMBOL];
|
|
2117
|
-
if (!(recordId < 1024)) {
|
|
2118
|
-
// for now just punt and go back to writeObject
|
|
2119
|
-
return 0;
|
|
2120
|
-
// newRecord(transition, transition.__keys__ || Object.keys(object), newTransitions, true)
|
|
2121
|
-
}
|
|
2122
|
-
let stringLength = stringData.length;
|
|
2123
|
-
if (stringData) {
|
|
2124
|
-
if (position + stringLength > safeEnd) {
|
|
2125
|
-
target = makeRoom(position + stringLength);
|
|
2126
|
-
}
|
|
2127
|
-
position += target.latin1Write(stringData, position, 0xffffffff);
|
|
2267
|
+
keyIndex++;
|
|
2128
2268
|
}
|
|
2129
|
-
|
|
2130
|
-
target[start + 1] = recordId & 0xff;
|
|
2131
|
-
target[start + 2] = stringLength >> 8;
|
|
2132
|
-
target[start + 3] = stringLength & 0xff;
|
|
2133
|
-
let queued32BitReferences;
|
|
2269
|
+
|
|
2134
2270
|
for (let i = 0, l = queuedReferences.length; i < l;) {
|
|
2271
|
+
let key = queuedReferences[i++];
|
|
2135
2272
|
let value = queuedReferences[i++];
|
|
2136
|
-
let
|
|
2137
|
-
let
|
|
2138
|
-
if (
|
|
2139
|
-
|
|
2273
|
+
let propertyIndex = queuedReferences[i++];
|
|
2274
|
+
let nextTransition = transition[key];
|
|
2275
|
+
if (!nextTransition) {
|
|
2276
|
+
transition[key] = nextTransition = {
|
|
2277
|
+
key,
|
|
2278
|
+
parent: transition,
|
|
2279
|
+
enumerationOffset: propertyIndex - keyIndex,
|
|
2280
|
+
ascii0: null,
|
|
2281
|
+
ascii8: null,
|
|
2282
|
+
num8: null,
|
|
2283
|
+
string16: null,
|
|
2284
|
+
object16: null,
|
|
2285
|
+
num32: null,
|
|
2286
|
+
float64: null
|
|
2287
|
+
};
|
|
2288
|
+
}
|
|
2289
|
+
let newPosition;
|
|
2290
|
+
if (value) {
|
|
2291
|
+
/*if (typeof value === 'string') { // TODO: we could re-enable long strings
|
|
2292
|
+
if (position + value.length * 3 > safeEnd) {
|
|
2293
|
+
target = makeRoom(position + value.length * 3);
|
|
2294
|
+
position -= start;
|
|
2295
|
+
targetView = target.dataView;
|
|
2296
|
+
start = 0;
|
|
2297
|
+
}
|
|
2298
|
+
newPosition = position + target.utf8Write(value, position, 0xffffffff);
|
|
2299
|
+
} else { */
|
|
2300
|
+
let size;
|
|
2301
|
+
refOffset = refPosition - refsStartPosition;
|
|
2302
|
+
if (refOffset < 0xff00) {
|
|
2303
|
+
transition = nextTransition.object16;
|
|
2304
|
+
if (transition)
|
|
2305
|
+
size = 2;
|
|
2306
|
+
else if ((transition = nextTransition.object32))
|
|
2307
|
+
size = 4;
|
|
2308
|
+
else {
|
|
2309
|
+
transition = createTypeTransition(nextTransition, OBJECT_DATA, 2);
|
|
2310
|
+
size = 2;
|
|
2311
|
+
}
|
|
2312
|
+
} else {
|
|
2313
|
+
transition = nextTransition.object32 || createTypeTransition(nextTransition, OBJECT_DATA, 4);
|
|
2314
|
+
size = 4;
|
|
2315
|
+
}
|
|
2316
|
+
newPosition = pack(value, refPosition);
|
|
2317
|
+
//}
|
|
2318
|
+
if (typeof newPosition === 'object') {
|
|
2319
|
+
// re-allocated
|
|
2320
|
+
refPosition = newPosition.position;
|
|
2321
|
+
targetView = newPosition.targetView;
|
|
2322
|
+
target = newPosition.target;
|
|
2323
|
+
refsStartPosition -= start;
|
|
2324
|
+
position -= start;
|
|
2325
|
+
start = 0;
|
|
2326
|
+
} else
|
|
2327
|
+
refPosition = newPosition;
|
|
2328
|
+
if (size === 2) {
|
|
2329
|
+
targetView.setUint16(position, refOffset, true);
|
|
2330
|
+
position += 2;
|
|
2331
|
+
} else {
|
|
2332
|
+
targetView.setUint32(position, refOffset, true);
|
|
2333
|
+
position += 4;
|
|
2334
|
+
}
|
|
2140
2335
|
} else {
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2336
|
+
transition = nextTransition.object16 || createTypeTransition(nextTransition, OBJECT_DATA, 2);
|
|
2337
|
+
targetView.setInt16(position, value === null ? -10 : -9, true);
|
|
2338
|
+
position += 2;
|
|
2144
2339
|
}
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2340
|
+
keyIndex++;
|
|
2341
|
+
}
|
|
2342
|
+
|
|
2343
|
+
|
|
2344
|
+
let recordId = transition[RECORD_SYMBOL];
|
|
2345
|
+
if (recordId == null) {
|
|
2346
|
+
recordId = packr.typedStructs.length;
|
|
2347
|
+
let structure = [];
|
|
2348
|
+
let nextTransition = transition;
|
|
2349
|
+
let key, type;
|
|
2350
|
+
while ((type = nextTransition.__type) !== undefined) {
|
|
2351
|
+
let size = nextTransition.__size;
|
|
2352
|
+
nextTransition = nextTransition.__parent;
|
|
2353
|
+
key = nextTransition.key;
|
|
2354
|
+
let property = [type, size, key];
|
|
2355
|
+
if (nextTransition.enumerationOffset)
|
|
2356
|
+
property.push(nextTransition.enumerationOffset);
|
|
2357
|
+
structure.push(property);
|
|
2358
|
+
nextTransition = nextTransition.parent;
|
|
2161
2359
|
}
|
|
2360
|
+
structure.reverse();
|
|
2361
|
+
transition[RECORD_SYMBOL] = recordId;
|
|
2362
|
+
packr.typedStructs[recordId] = structure;
|
|
2363
|
+
pack(null, 0, true); // special call to notify that structures have been updated
|
|
2162
2364
|
}
|
|
2163
2365
|
|
|
2164
|
-
|
|
2366
|
+
|
|
2367
|
+
switch (headerSize) {
|
|
2368
|
+
case 1:
|
|
2369
|
+
if (recordId >= 0x10) return 0;
|
|
2370
|
+
target[start] = recordId + 0x20;
|
|
2371
|
+
break;
|
|
2372
|
+
case 2:
|
|
2373
|
+
if (recordId >= 0x100) return 0;
|
|
2374
|
+
target[start] = 0x38;
|
|
2375
|
+
target[start + 1] = recordId;
|
|
2376
|
+
break;
|
|
2377
|
+
case 3:
|
|
2378
|
+
if (recordId >= 0x10000) return 0;
|
|
2379
|
+
target[start] = 0x39;
|
|
2380
|
+
target.setUint16(start + 1, recordId, true);
|
|
2381
|
+
break;
|
|
2382
|
+
case 4:
|
|
2383
|
+
if (recordId >= 0x1000000) return 0;
|
|
2384
|
+
target.setUint32(start, (recordId << 8) + 0x3a, true);
|
|
2385
|
+
break;
|
|
2386
|
+
}
|
|
2387
|
+
|
|
2388
|
+
if (position < refsStartPosition) {
|
|
2389
|
+
if (refsStartPosition === refPosition)
|
|
2390
|
+
return position; // no refs
|
|
2391
|
+
// adjust positioning
|
|
2392
|
+
target.copyWithin(position, refsStartPosition, refPosition);
|
|
2393
|
+
refPosition += position - refsStartPosition;
|
|
2394
|
+
typedStructs.lastStringStart = position - start;
|
|
2395
|
+
} else if (position > refsStartPosition) {
|
|
2396
|
+
if (refsStartPosition === refPosition)
|
|
2397
|
+
return position; // no refs
|
|
2398
|
+
typedStructs.lastStringStart = position - start;
|
|
2399
|
+
return writeStruct(object, target, start, structures, makeRoom, pack, packr);
|
|
2400
|
+
}
|
|
2401
|
+
return refPosition;
|
|
2402
|
+
}
|
|
2403
|
+
function anyType(transition, position, targetView, value) {
|
|
2404
|
+
let nextTransition;
|
|
2405
|
+
if ((nextTransition = transition.ascii8 || transition.num8)) {
|
|
2406
|
+
targetView.setInt8(position, value, true);
|
|
2407
|
+
updatedPosition = position + 1;
|
|
2408
|
+
return nextTransition;
|
|
2409
|
+
}
|
|
2410
|
+
if ((nextTransition = transition.string16 || transition.object16)) {
|
|
2411
|
+
targetView.setInt16(position, value, true);
|
|
2412
|
+
updatedPosition = position + 2;
|
|
2413
|
+
return nextTransition;
|
|
2414
|
+
}
|
|
2415
|
+
if (nextTransition = transition.num32) {
|
|
2416
|
+
targetView.setUint32(position, 0xe0000100 + value, true);
|
|
2417
|
+
updatedPosition = position + 4;
|
|
2418
|
+
return nextTransition;
|
|
2419
|
+
}
|
|
2420
|
+
// transition.float64
|
|
2421
|
+
if (nextTransition = transition.num64) {
|
|
2422
|
+
targetView.setFloat64(position, NaN, true);
|
|
2423
|
+
targetView.setInt8(position, value);
|
|
2424
|
+
updatedPosition = position + 8;
|
|
2425
|
+
return nextTransition;
|
|
2426
|
+
}
|
|
2427
|
+
updatedPosition = position;
|
|
2428
|
+
// TODO: can we do an "any" type where we defer the decision?
|
|
2429
|
+
return;
|
|
2430
|
+
}
|
|
2431
|
+
function createTypeTransition(transition, type, size) {
|
|
2432
|
+
let typeName = TYPE_NAMES[type] + (size << 3);
|
|
2433
|
+
let newTransition = transition[typeName] || (transition[typeName] = Object.create(null));
|
|
2434
|
+
newTransition.__type = type;
|
|
2435
|
+
newTransition.__size = size;
|
|
2436
|
+
newTransition.__parent = transition;
|
|
2437
|
+
return newTransition;
|
|
2438
|
+
}
|
|
2439
|
+
function onLoadedStructures$1(sharedData) {
|
|
2440
|
+
if (!(sharedData instanceof Map))
|
|
2441
|
+
return sharedData;
|
|
2442
|
+
let typed = sharedData.get('typed') || [];
|
|
2443
|
+
if (Object.isFrozen(typed))
|
|
2444
|
+
typed = typed.map(structure => structure.slice(0));
|
|
2445
|
+
let named = sharedData.get('named');
|
|
2446
|
+
let transitions = Object.create(null);
|
|
2447
|
+
for (let i = 0, l = typed.length; i < l; i++) {
|
|
2448
|
+
let structure = typed[i];
|
|
2449
|
+
let transition = transitions;
|
|
2450
|
+
for (let [type, size, key] of structure) {
|
|
2451
|
+
let nextTransition = transition[key];
|
|
2452
|
+
if (!nextTransition) {
|
|
2453
|
+
transition[key] = nextTransition = {
|
|
2454
|
+
key,
|
|
2455
|
+
parent: transition,
|
|
2456
|
+
enumerationOffset: 0,
|
|
2457
|
+
ascii0: null,
|
|
2458
|
+
ascii8: null,
|
|
2459
|
+
num8: null,
|
|
2460
|
+
string16: null,
|
|
2461
|
+
object16: null,
|
|
2462
|
+
num32: null,
|
|
2463
|
+
float64: null
|
|
2464
|
+
};
|
|
2465
|
+
}
|
|
2466
|
+
transition = createTypeTransition(nextTransition, type, size);
|
|
2467
|
+
}
|
|
2468
|
+
transition[RECORD_SYMBOL] = i;
|
|
2469
|
+
}
|
|
2470
|
+
typed.transitions = transitions;
|
|
2471
|
+
this.typedStructs = typed;
|
|
2472
|
+
this.lastTypedStructuresLength = typed.length;
|
|
2473
|
+
return named;
|
|
2165
2474
|
}
|
|
2166
2475
|
var sourceSymbol = Symbol('source');
|
|
2167
|
-
function readStruct$1(src, position, srcEnd,
|
|
2168
|
-
var stringLength = (src[position++] << 8) | src[position++];
|
|
2476
|
+
function readStruct$1(src, position, srcEnd, unpackr) {
|
|
2477
|
+
// var stringLength = (src[position++] << 8) | src[position++];
|
|
2478
|
+
let recordId = src[position++] - 0x20;
|
|
2479
|
+
if (recordId >= 24) {
|
|
2480
|
+
switch(recordId) {
|
|
2481
|
+
case 24: recordId = src[position++]; break;
|
|
2482
|
+
// little endian:
|
|
2483
|
+
case 25: recordId = src[position++] + (src[position++] << 8); break;
|
|
2484
|
+
case 26: recordId = src[position++] + (src[position++] << 8) + (src[position++] << 16); break;
|
|
2485
|
+
case 27: recordId = src[position++] + (src[position++] << 8) + (src[position++] << 16) + (src[position++] << 24); break;
|
|
2486
|
+
}
|
|
2487
|
+
}
|
|
2488
|
+
let structure = unpackr.typedStructs?.[recordId];
|
|
2489
|
+
if (!structure) {
|
|
2490
|
+
// copy src buffer because getStructures will override it
|
|
2491
|
+
src = Uint8Array.prototype.slice.call(src, position, srcEnd);
|
|
2492
|
+
srcEnd -= position;
|
|
2493
|
+
position = 0;
|
|
2494
|
+
unpackr._mergeStructures(unpackr.getStructures());
|
|
2495
|
+
if (!unpackr.typedStructs)
|
|
2496
|
+
throw new Error('Could not find any shared typed structures');
|
|
2497
|
+
unpackr.lastTypedStructuresLength = unpackr.typedStructs.length;
|
|
2498
|
+
structure = unpackr.typedStructs[recordId];
|
|
2499
|
+
if (!structure)
|
|
2500
|
+
throw new Error('Could not find typed structure ' + recordId);
|
|
2501
|
+
}
|
|
2169
2502
|
var construct = structure.construct;
|
|
2170
2503
|
if (!construct) {
|
|
2171
|
-
construct = structure.construct = function() {
|
|
2504
|
+
construct = structure.construct = function LazyObject() {
|
|
2172
2505
|
};
|
|
2173
2506
|
var prototype = construct.prototype;
|
|
2507
|
+
let properties = [];
|
|
2174
2508
|
Object.defineProperty(prototype, 'toJSON', {
|
|
2175
|
-
|
|
2509
|
+
value() {
|
|
2176
2510
|
// return an enumerable object with own properties to JSON stringify
|
|
2177
2511
|
let resolved = {};
|
|
2178
|
-
for (let i = 0, l =
|
|
2179
|
-
let key =
|
|
2512
|
+
for (let i = 0, l = properties.length; i < l; i++) {
|
|
2513
|
+
let key = properties[i].key;
|
|
2180
2514
|
resolved[key] = this[key];
|
|
2181
2515
|
}
|
|
2182
2516
|
return resolved;
|
|
2183
2517
|
},
|
|
2184
2518
|
// not enumerable or anything
|
|
2185
2519
|
});
|
|
2520
|
+
let currentOffset = 0;
|
|
2521
|
+
let lastRefProperty;
|
|
2186
2522
|
for (let i = 0, l = structure.length; i < l; i++) {
|
|
2187
|
-
let
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2523
|
+
let definition = structure[i];
|
|
2524
|
+
let [ type, size, key, enumerationOffset ] = definition;
|
|
2525
|
+
let property = {
|
|
2526
|
+
key,
|
|
2527
|
+
offset: currentOffset,
|
|
2528
|
+
};
|
|
2529
|
+
if (enumerationOffset)
|
|
2530
|
+
properties.splice(i + enumerationOffset, 0, property);
|
|
2531
|
+
else
|
|
2532
|
+
properties.push(property);
|
|
2533
|
+
let getRef;
|
|
2534
|
+
switch(size) { // TODO: Move into a separate function
|
|
2535
|
+
case 0: getRef = () => 0; break;
|
|
2536
|
+
case 1:
|
|
2537
|
+
getRef = (source, position) => {
|
|
2538
|
+
let ref = source.src[position + property.offset];
|
|
2539
|
+
return ref >= 0xf6 ? toConstant(ref) : ref;
|
|
2540
|
+
};
|
|
2541
|
+
break;
|
|
2542
|
+
case 2:
|
|
2543
|
+
getRef = (source, position) => {
|
|
2544
|
+
let src = source.src;
|
|
2545
|
+
let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
|
|
2546
|
+
let ref = dataView.getUint16(position + property.offset, true);
|
|
2547
|
+
return ref >= 0xff00 ? toConstant(ref & 0xff) : ref;
|
|
2548
|
+
};
|
|
2549
|
+
break;
|
|
2550
|
+
case 4:
|
|
2551
|
+
getRef = (source, position) => {
|
|
2552
|
+
let src = source.src;
|
|
2553
|
+
let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
|
|
2554
|
+
let ref = dataView.getUint32(position + property.offset, true);
|
|
2555
|
+
return ref >= 0xffffff00 ? toConstant(ref & 0xff) : ref;
|
|
2556
|
+
};
|
|
2557
|
+
break;
|
|
2558
|
+
}
|
|
2559
|
+
property.getRef = getRef;
|
|
2560
|
+
currentOffset += size;
|
|
2561
|
+
let get;
|
|
2562
|
+
switch(type) {
|
|
2563
|
+
case ASCII:
|
|
2564
|
+
if (lastRefProperty && !lastRefProperty.next)
|
|
2565
|
+
lastRefProperty.next = property;
|
|
2566
|
+
lastRefProperty = property;
|
|
2567
|
+
property.multiGetCount = 0;
|
|
2568
|
+
get = function() {
|
|
2569
|
+
let source = this[sourceSymbol];
|
|
2570
|
+
let src = source.src;
|
|
2571
|
+
let position = source.position;
|
|
2572
|
+
let refStart = currentOffset + position;
|
|
2573
|
+
let ref = getRef(source, position);
|
|
2574
|
+
if (typeof ref !== 'number') return ref;
|
|
2575
|
+
|
|
2576
|
+
let end, next = property.next;
|
|
2577
|
+
while(next) {
|
|
2578
|
+
end = next.getRef(source, position);
|
|
2579
|
+
if (typeof end === 'number')
|
|
2580
|
+
break;
|
|
2581
|
+
else
|
|
2582
|
+
end = null;
|
|
2583
|
+
next = next.next;
|
|
2584
|
+
}
|
|
2585
|
+
if (end == null)
|
|
2586
|
+
end = source.srcEnd - refStart;
|
|
2587
|
+
if (source.srcString) {
|
|
2588
|
+
return source.srcString.slice(ref, end);
|
|
2589
|
+
}
|
|
2590
|
+
/*if (property.multiGetCount > 0) {
|
|
2591
|
+
let asciiEnd;
|
|
2592
|
+
next = firstRefProperty;
|
|
2593
|
+
let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
|
|
2594
|
+
do {
|
|
2595
|
+
asciiEnd = dataView.getUint16(source.position + next.offset, true);
|
|
2596
|
+
if (asciiEnd < 0xff00)
|
|
2219
2597
|
break;
|
|
2598
|
+
else
|
|
2599
|
+
asciiEnd = null;
|
|
2600
|
+
} while((next = next.next));
|
|
2601
|
+
if (asciiEnd == null)
|
|
2602
|
+
asciiEnd = source.srcEnd - refStart
|
|
2603
|
+
source.srcString = src.toString('latin1', refStart, refStart + asciiEnd);
|
|
2604
|
+
return source.srcString.slice(ref, end);
|
|
2605
|
+
}
|
|
2606
|
+
if (source.prevStringGet) {
|
|
2607
|
+
source.prevStringGet.multiGetCount += 2;
|
|
2608
|
+
} else {
|
|
2609
|
+
source.prevStringGet = property;
|
|
2610
|
+
property.multiGetCount--;
|
|
2611
|
+
}*/
|
|
2612
|
+
return readString(src, ref + refStart, end - ref);
|
|
2613
|
+
//return src.toString('latin1', ref + refStart, end + refStart);
|
|
2614
|
+
};
|
|
2615
|
+
break;
|
|
2616
|
+
case UTF8: case OBJECT_DATA:
|
|
2617
|
+
if (lastRefProperty && !lastRefProperty.next)
|
|
2618
|
+
lastRefProperty.next = property;
|
|
2619
|
+
lastRefProperty = property;
|
|
2620
|
+
get = function() {
|
|
2621
|
+
let source = this[sourceSymbol];
|
|
2622
|
+
let position = source.position;
|
|
2623
|
+
let refStart = currentOffset + position;
|
|
2624
|
+
let ref = getRef(source, position);
|
|
2625
|
+
if (typeof ref !== 'number') return ref;
|
|
2626
|
+
let src = source.src;
|
|
2627
|
+
let end, next = property.next;
|
|
2628
|
+
while(next) {
|
|
2629
|
+
end = next.getRef(source, position);
|
|
2630
|
+
if (typeof end === 'number')
|
|
2631
|
+
break;
|
|
2632
|
+
else
|
|
2633
|
+
end = null;
|
|
2634
|
+
next = next.next;
|
|
2635
|
+
}
|
|
2636
|
+
if (end == null)
|
|
2637
|
+
end = source.srcEnd - refStart;
|
|
2638
|
+
if (type === UTF8) {
|
|
2639
|
+
return src.toString('utf8', ref + refStart, end + refStart);
|
|
2640
|
+
} else {
|
|
2641
|
+
return unpackr.unpack(src, { start: ref + refStart, end: end + refStart }); // could reuse this object
|
|
2642
|
+
}
|
|
2643
|
+
};
|
|
2644
|
+
break;
|
|
2645
|
+
case NUMBER:
|
|
2646
|
+
switch(size) {
|
|
2647
|
+
case 4:
|
|
2648
|
+
get = function () {
|
|
2649
|
+
let source = this[sourceSymbol];
|
|
2650
|
+
let src = source.src;
|
|
2651
|
+
let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
|
|
2652
|
+
let position = source.position + property.offset;
|
|
2653
|
+
let value = dataView.getInt32(position, true);
|
|
2654
|
+
if (value < 0x20000000) {
|
|
2655
|
+
if (value > -0x1f000000)
|
|
2656
|
+
return value;
|
|
2657
|
+
if (value > -0x20000000)
|
|
2658
|
+
return toConstant(value & 0xff);
|
|
2220
2659
|
}
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2660
|
+
let fValue = dataView.getFloat32(position, true);
|
|
2661
|
+
// this does rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
|
|
2662
|
+
let multiplier = mult10[((src[position + 3] & 0x7f) << 1) | (src[position + 2] >> 7)];
|
|
2663
|
+
return ((multiplier * fValue + (fValue > 0 ? 0.5 : -0.5)) >> 0) / multiplier;
|
|
2664
|
+
};
|
|
2665
|
+
break;
|
|
2666
|
+
case 8:
|
|
2667
|
+
get = function () {
|
|
2668
|
+
let source = this[sourceSymbol];
|
|
2669
|
+
let src = source.src;
|
|
2670
|
+
let dataView = src.dataView || (src.dataView = new DataView(src.buffer, src.byteOffset, src.byteLength));
|
|
2671
|
+
let value = dataView.getFloat64(source.position + property.offset, true);
|
|
2672
|
+
if (isNaN(value)) {
|
|
2673
|
+
let byte = src[source.position + property.offset];
|
|
2674
|
+
if (byte >= 0xf6)
|
|
2675
|
+
return toConstant(byte);
|
|
2676
|
+
}
|
|
2677
|
+
return value;
|
|
2678
|
+
};
|
|
2679
|
+
break;
|
|
2680
|
+
case 1:
|
|
2681
|
+
get = function () {
|
|
2682
|
+
let source = this[sourceSymbol];
|
|
2683
|
+
let src = source.src;
|
|
2684
|
+
let value = src[source.position + property.offset];
|
|
2685
|
+
return value < 0xf6 ? value : toConstant(value);
|
|
2686
|
+
};
|
|
2687
|
+
break;
|
|
2241
2688
|
}
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
});
|
|
2689
|
+
}
|
|
2690
|
+
property.get = get;
|
|
2245
2691
|
}
|
|
2692
|
+
for (let property of properties) // assign in enumeration order
|
|
2693
|
+
Object.defineProperty(prototype, property.key, { get: property.get, enumerable: true });
|
|
2246
2694
|
}
|
|
2247
2695
|
var instance = new construct();
|
|
2248
2696
|
instance[sourceSymbol] = {
|
|
2249
2697
|
src,
|
|
2250
|
-
uint32: src.uint32,
|
|
2251
2698
|
position,
|
|
2252
2699
|
srcString: '',
|
|
2253
|
-
srcEnd
|
|
2254
|
-
stringLength
|
|
2700
|
+
srcEnd
|
|
2255
2701
|
};
|
|
2256
2702
|
return instance;
|
|
2257
2703
|
}
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
options.sequential = true;
|
|
2267
|
-
this.packr = options.packr || new Packr(options);
|
|
2268
|
-
}
|
|
2269
|
-
_transform(value, encoding, callback) {
|
|
2270
|
-
this.push(this.packr.pack(value));
|
|
2271
|
-
callback();
|
|
2272
|
-
}
|
|
2273
|
-
}
|
|
2274
|
-
|
|
2275
|
-
class UnpackrStream extends stream.Transform {
|
|
2276
|
-
constructor(options) {
|
|
2277
|
-
if (!options)
|
|
2278
|
-
options = {};
|
|
2279
|
-
options.objectMode = true;
|
|
2280
|
-
super(options);
|
|
2281
|
-
options.structures = [];
|
|
2282
|
-
this.unpackr = options.unpackr || new Unpackr(options);
|
|
2283
|
-
}
|
|
2284
|
-
_transform(chunk, encoding, callback) {
|
|
2285
|
-
if (this.incompleteBuffer) {
|
|
2286
|
-
chunk = Buffer.concat([this.incompleteBuffer, chunk]);
|
|
2287
|
-
this.incompleteBuffer = null;
|
|
2288
|
-
}
|
|
2289
|
-
let values;
|
|
2290
|
-
try {
|
|
2291
|
-
values = this.unpackr.unpackMultiple(chunk);
|
|
2292
|
-
} catch(error) {
|
|
2293
|
-
if (error.incomplete) {
|
|
2294
|
-
this.incompleteBuffer = chunk.slice(error.lastPosition);
|
|
2295
|
-
values = error.values;
|
|
2296
|
-
}
|
|
2297
|
-
else
|
|
2298
|
-
throw error
|
|
2299
|
-
} finally {
|
|
2300
|
-
for (let value of values || []) {
|
|
2301
|
-
if (value === null)
|
|
2302
|
-
value = this.getNullValue();
|
|
2303
|
-
this.push(value);
|
|
2304
|
-
}
|
|
2305
|
-
}
|
|
2306
|
-
if (callback) callback();
|
|
2307
|
-
}
|
|
2308
|
-
getNullValue() {
|
|
2309
|
-
return Symbol.for(null)
|
|
2310
|
-
}
|
|
2704
|
+
function toConstant(code) {
|
|
2705
|
+
switch(code) {
|
|
2706
|
+
case 0xf6: return null;
|
|
2707
|
+
case 0xf7: return undefined;
|
|
2708
|
+
case 0xf8: return false;
|
|
2709
|
+
case 0xf9: return true;
|
|
2710
|
+
}
|
|
2711
|
+
throw new Error('Unknown constant');
|
|
2311
2712
|
}
|
|
2713
|
+
function prepareStructures$1(structures, packr) {
|
|
2714
|
+
if (packr.typedStructs) {
|
|
2715
|
+
let structMap = new Map();
|
|
2716
|
+
structMap.set('named', structures);
|
|
2717
|
+
structMap.set('typed', packr.typedStructs);
|
|
2718
|
+
structures = structMap;
|
|
2719
|
+
}
|
|
2720
|
+
let lastTypedStructuresLength = packr.lastTypedStructuresLength || 0;
|
|
2721
|
+
structures.isCompatible = existing => {
|
|
2722
|
+
let compatible = true;
|
|
2723
|
+
if (existing instanceof Map) {
|
|
2724
|
+
let named = existing.get('named') || [];
|
|
2725
|
+
if (named.length !== (packr.lastNamedStructuresLength || 0))
|
|
2726
|
+
compatible = false;
|
|
2727
|
+
let typed = existing.get('typed') || [];
|
|
2728
|
+
if (typed.length !== lastTypedStructuresLength)
|
|
2729
|
+
compatible = false;
|
|
2730
|
+
} else if (existing instanceof Array) {
|
|
2731
|
+
if (existing.length !== (packr.lastNamedStructuresLength || 0))
|
|
2732
|
+
compatible = false;
|
|
2733
|
+
}
|
|
2734
|
+
if (!compatible)
|
|
2735
|
+
packr._mergeStructures(existing);
|
|
2736
|
+
return compatible;
|
|
2737
|
+
};
|
|
2738
|
+
packr.lastTypedStructuresLength = packr.typedStructs?.length;
|
|
2739
|
+
return structures;
|
|
2740
|
+
}
|
|
2741
|
+
|
|
2742
|
+
setReadStruct(readStruct$1, onLoadedStructures$1);
|
|
2312
2743
|
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2744
|
+
class PackrStream extends stream.Transform {
|
|
2745
|
+
constructor(options) {
|
|
2746
|
+
if (!options)
|
|
2747
|
+
options = {};
|
|
2748
|
+
options.writableObjectMode = true;
|
|
2749
|
+
super(options);
|
|
2750
|
+
options.sequential = true;
|
|
2751
|
+
this.packr = options.packr || new Packr(options);
|
|
2752
|
+
}
|
|
2753
|
+
_transform(value, encoding, callback) {
|
|
2754
|
+
this.push(this.packr.pack(value));
|
|
2755
|
+
callback();
|
|
2756
|
+
}
|
|
2757
|
+
}
|
|
2758
|
+
|
|
2759
|
+
class UnpackrStream extends stream.Transform {
|
|
2760
|
+
constructor(options) {
|
|
2761
|
+
if (!options)
|
|
2762
|
+
options = {};
|
|
2763
|
+
options.objectMode = true;
|
|
2764
|
+
super(options);
|
|
2765
|
+
options.structures = [];
|
|
2766
|
+
this.unpackr = options.unpackr || new Unpackr(options);
|
|
2767
|
+
}
|
|
2768
|
+
_transform(chunk, encoding, callback) {
|
|
2769
|
+
if (this.incompleteBuffer) {
|
|
2770
|
+
chunk = Buffer.concat([this.incompleteBuffer, chunk]);
|
|
2771
|
+
this.incompleteBuffer = null;
|
|
2772
|
+
}
|
|
2773
|
+
let values;
|
|
2774
|
+
try {
|
|
2775
|
+
values = this.unpackr.unpackMultiple(chunk);
|
|
2776
|
+
} catch(error) {
|
|
2777
|
+
if (error.incomplete) {
|
|
2778
|
+
this.incompleteBuffer = chunk.slice(error.lastPosition);
|
|
2779
|
+
values = error.values;
|
|
2780
|
+
}
|
|
2781
|
+
else
|
|
2782
|
+
throw error
|
|
2783
|
+
} finally {
|
|
2784
|
+
for (let value of values || []) {
|
|
2785
|
+
if (value === null)
|
|
2786
|
+
value = this.getNullValue();
|
|
2787
|
+
this.push(value);
|
|
2788
|
+
}
|
|
2789
|
+
}
|
|
2790
|
+
if (callback) callback();
|
|
2791
|
+
}
|
|
2792
|
+
getNullValue() {
|
|
2793
|
+
return Symbol.for(null)
|
|
2794
|
+
}
|
|
2795
|
+
}
|
|
2796
|
+
|
|
2797
|
+
/**
|
|
2798
|
+
* Given an Iterable first argument, returns an Iterable where each value is packed as a Buffer
|
|
2799
|
+
* If the argument is only Async Iterable, the return value will be an Async Iterable.
|
|
2800
|
+
* @param {Iterable|Iterator|AsyncIterable|AsyncIterator} objectIterator - iterable source, like a Readable object stream, an array, Set, or custom object
|
|
2801
|
+
* @param {options} [options] - msgpackr pack options
|
|
2802
|
+
* @returns {IterableIterator|Promise.<AsyncIterableIterator>}
|
|
2803
|
+
*/
|
|
2804
|
+
function packIter (objectIterator, options = {}) {
|
|
2805
|
+
if (!objectIterator || typeof objectIterator !== 'object') {
|
|
2806
|
+
throw new Error('first argument must be an Iterable, Async Iterable, or a Promise for an Async Iterable')
|
|
2807
|
+
} else if (typeof objectIterator[Symbol.iterator] === 'function') {
|
|
2808
|
+
return packIterSync(objectIterator, options)
|
|
2809
|
+
} else if (typeof objectIterator.then === 'function' || typeof objectIterator[Symbol.asyncIterator] === 'function') {
|
|
2810
|
+
return packIterAsync(objectIterator, options)
|
|
2811
|
+
} else {
|
|
2812
|
+
throw new Error('first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a Promise')
|
|
2813
|
+
}
|
|
2814
|
+
}
|
|
2815
|
+
|
|
2816
|
+
function * packIterSync (objectIterator, options) {
|
|
2817
|
+
const packr = new Packr(options);
|
|
2818
|
+
for (const value of objectIterator) {
|
|
2819
|
+
yield packr.pack(value);
|
|
2820
|
+
}
|
|
2821
|
+
}
|
|
2822
|
+
|
|
2823
|
+
async function * packIterAsync (objectIterator, options) {
|
|
2824
|
+
const packr = new Packr(options);
|
|
2825
|
+
for await (const value of objectIterator) {
|
|
2826
|
+
yield packr.pack(value);
|
|
2827
|
+
}
|
|
2828
|
+
}
|
|
2829
|
+
|
|
2830
|
+
/**
|
|
2831
|
+
* Given an Iterable/Iterator input which yields buffers, returns an IterableIterator which yields sync decoded objects
|
|
2832
|
+
* Or, given an Async Iterable/Iterator which yields promises resolving in buffers, returns an AsyncIterableIterator.
|
|
2833
|
+
* @param {Iterable|Iterator|AsyncIterable|AsyncIterableIterator} bufferIterator
|
|
2834
|
+
* @param {object} [options] - unpackr options
|
|
2835
|
+
* @returns {IterableIterator|Promise.<AsyncIterableIterator}
|
|
2836
|
+
*/
|
|
2837
|
+
function unpackIter (bufferIterator, options = {}) {
|
|
2838
|
+
if (!bufferIterator || typeof bufferIterator !== 'object') {
|
|
2839
|
+
throw new Error('first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a promise')
|
|
2840
|
+
}
|
|
2841
|
+
|
|
2842
|
+
const unpackr = new Unpackr(options);
|
|
2843
|
+
let incomplete;
|
|
2844
|
+
const parser = (chunk) => {
|
|
2845
|
+
let yields;
|
|
2846
|
+
// if there's incomplete data from previous chunk, concatinate and try again
|
|
2847
|
+
if (incomplete) {
|
|
2848
|
+
chunk = Buffer.concat([incomplete, chunk]);
|
|
2849
|
+
incomplete = undefined;
|
|
2850
|
+
}
|
|
2851
|
+
|
|
2852
|
+
try {
|
|
2853
|
+
yields = unpackr.unpackMultiple(chunk);
|
|
2854
|
+
} catch (err) {
|
|
2855
|
+
if (err.incomplete) {
|
|
2856
|
+
incomplete = chunk.slice(err.lastPosition);
|
|
2857
|
+
yields = err.values;
|
|
2858
|
+
} else {
|
|
2859
|
+
throw err
|
|
2860
|
+
}
|
|
2861
|
+
}
|
|
2862
|
+
return yields
|
|
2863
|
+
};
|
|
2864
|
+
|
|
2865
|
+
if (typeof bufferIterator[Symbol.iterator] === 'function') {
|
|
2866
|
+
return (function * iter () {
|
|
2867
|
+
for (const value of bufferIterator) {
|
|
2868
|
+
yield * parser(value);
|
|
2869
|
+
}
|
|
2870
|
+
})()
|
|
2871
|
+
} else if (typeof bufferIterator[Symbol.asyncIterator] === 'function') {
|
|
2872
|
+
return (async function * iter () {
|
|
2873
|
+
for await (const value of bufferIterator) {
|
|
2874
|
+
yield * parser(value);
|
|
2875
|
+
}
|
|
2876
|
+
})()
|
|
2877
|
+
}
|
|
2878
|
+
}
|
|
2879
|
+
const decodeIter = unpackIter;
|
|
2396
2880
|
const encodeIter = packIter;
|
|
2397
2881
|
|
|
2398
2882
|
const useRecords = false;
|