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