cbor-x 1.3.3 → 1.4.0
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 +347 -346
- package/SECURITY.md +11 -11
- package/benchmark.md +73 -73
- package/browser.js +11 -11
- package/decode.d.ts +2 -46
- package/decode.js +9 -7
- package/dist/index.js +1122 -1112
- package/dist/index.min.js +86 -76
- package/dist/node.cjs +1190 -1180
- package/dist/test.js +17 -1
- package/encode.d.ts +1 -6
- package/encode.js +1041 -1033
- package/index.d.ts +61 -12
- package/index.js +3 -3
- package/iterators.js +85 -85
- package/node-index.js +24 -24
- package/package.json +6 -1
- package/rollup.config.js +45 -45
- package/stream.js +57 -57
- package/webpack.config.js +19 -19
- package/dist/index.js.map +0 -1
- package/dist/node-index.js +0 -93
package/dist/node.cjs
CHANGED
|
@@ -748,8 +748,6 @@ class Tag {
|
|
|
748
748
|
}
|
|
749
749
|
}
|
|
750
750
|
|
|
751
|
-
let glbl = typeof self == 'object' ? self : global;
|
|
752
|
-
|
|
753
751
|
currentExtensions[0] = (dateString) => {
|
|
754
752
|
// string date extension
|
|
755
753
|
return new Date(dateString)
|
|
@@ -816,7 +814,7 @@ currentExtensions[15] = (value) => {
|
|
|
816
814
|
return bundledStrings[1].slice(bundledStrings.position1, bundledStrings.position1 += value)
|
|
817
815
|
return new Tag(value, 15)
|
|
818
816
|
};
|
|
819
|
-
|
|
817
|
+
let glbl = { Error, RegExp };
|
|
820
818
|
currentExtensions[27] = (data) => { // http://cbor.schmorp.de/generic-object
|
|
821
819
|
return (glbl[data[0]] || Error)(data[1], data[2])
|
|
822
820
|
};
|
|
@@ -941,13 +939,17 @@ currentExtensionRanges.push((tag, input) => {
|
|
|
941
939
|
});
|
|
942
940
|
|
|
943
941
|
const isLittleEndianMachine = new Uint8Array(new Uint16Array([1]).buffer)[0] == 1;
|
|
944
|
-
const typedArrays = [
|
|
942
|
+
const typedArrays = [Uint8Array, Uint8ClampedArray, Uint16Array, Uint32Array,
|
|
943
|
+
typeof BigUint64Array == 'undefined' ? { name:'BigUint64Array' } : BigUint64Array, Int8Array, Int16Array, Int32Array,
|
|
944
|
+
typeof BigInt64Array == 'undefined' ? { name:'BigInt64Array' } : BigInt64Array, Float32Array, Float64Array];
|
|
945
945
|
const typedArrayTags = [64, 68, 69, 70, 71, 72, 77, 78, 79, 85, 86];
|
|
946
946
|
for (let i = 0; i < typedArrays.length; i++) {
|
|
947
947
|
registerTypedArray(typedArrays[i], typedArrayTags[i]);
|
|
948
948
|
}
|
|
949
|
-
function registerTypedArray(
|
|
950
|
-
let
|
|
949
|
+
function registerTypedArray(TypedArray, tag) {
|
|
950
|
+
let dvMethod = 'get' + TypedArray.name.slice(0, -5);
|
|
951
|
+
if (typeof TypedArray !== 'function')
|
|
952
|
+
TypedArray = null;
|
|
951
953
|
let bytesPerElement = TypedArray.BYTES_PER_ELEMENT;
|
|
952
954
|
for (let littleEndian = 0; littleEndian < 2; littleEndian++) {
|
|
953
955
|
if (!littleEndian && bytesPerElement == 1)
|
|
@@ -964,7 +966,7 @@ function registerTypedArray(typedArrayId, tag, littleEndian) {
|
|
|
964
966
|
let dv = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
965
967
|
let elements = buffer.length >> sizeShift;
|
|
966
968
|
let ta = new TypedArray(elements);
|
|
967
|
-
let method = dv[
|
|
969
|
+
let method = dv[dvMethod];
|
|
968
970
|
for (let i = 0; i < elements; i++) {
|
|
969
971
|
ta[i] = method.call(dv, i << sizeShift, littleEndian);
|
|
970
972
|
}
|
|
@@ -1092,1185 +1094,1193 @@ function roundFloat32(float32Number) {
|
|
|
1092
1094
|
return ((multiplier * float32Number + (float32Number > 0 ? 0.5 : -0.5)) >> 0) / multiplier
|
|
1093
1095
|
}
|
|
1094
1096
|
|
|
1095
|
-
let textEncoder;
|
|
1096
|
-
try {
|
|
1097
|
-
textEncoder = new TextEncoder();
|
|
1098
|
-
} catch (error) {}
|
|
1099
|
-
let extensions, extensionClasses;
|
|
1100
|
-
const hasNodeBuffer = typeof Buffer !== 'undefined';
|
|
1101
|
-
const ByteArrayAllocate = hasNodeBuffer ? Buffer.allocUnsafeSlow : Uint8Array;
|
|
1102
|
-
const ByteArray = hasNodeBuffer ? Buffer : Uint8Array;
|
|
1103
|
-
const MAX_STRUCTURES = 0x100;
|
|
1104
|
-
const MAX_BUFFER_SIZE = hasNodeBuffer ? 0x100000000 : 0x7fd00000;
|
|
1105
|
-
let target;
|
|
1106
|
-
let targetView;
|
|
1107
|
-
let position$1 = 0;
|
|
1108
|
-
let safeEnd;
|
|
1109
|
-
let bundledStrings$1 = null;
|
|
1110
|
-
const MAX_BUNDLE_SIZE = 0xf000;
|
|
1111
|
-
const hasNonLatin = /[\u0080-\uFFFF]/;
|
|
1112
|
-
const RECORD_SYMBOL = Symbol('record-id');
|
|
1113
|
-
class Encoder extends Decoder {
|
|
1114
|
-
constructor(options) {
|
|
1115
|
-
super(options);
|
|
1116
|
-
this.offset = 0;
|
|
1117
|
-
let start;
|
|
1118
|
-
let sharedStructures;
|
|
1119
|
-
let hasSharedUpdate;
|
|
1120
|
-
let structures;
|
|
1121
|
-
let referenceMap;
|
|
1122
|
-
options = options || {};
|
|
1123
|
-
let encodeUtf8 = ByteArray.prototype.utf8Write ? function(string, position, maxBytes) {
|
|
1124
|
-
return target.utf8Write(string, position, maxBytes)
|
|
1125
|
-
} : (textEncoder && textEncoder.encodeInto) ?
|
|
1126
|
-
function(string, position) {
|
|
1127
|
-
return textEncoder.encodeInto(string, target.subarray(position)).written
|
|
1128
|
-
} : false;
|
|
1129
|
-
|
|
1130
|
-
let encoder = this;
|
|
1131
|
-
let hasSharedStructures = options.structures || options.saveStructures;
|
|
1132
|
-
let maxSharedStructures = options.maxSharedStructures;
|
|
1133
|
-
if (maxSharedStructures == null)
|
|
1134
|
-
maxSharedStructures = hasSharedStructures ? 128 : 0;
|
|
1135
|
-
if (maxSharedStructures > 8190)
|
|
1136
|
-
throw new Error('Maximum maxSharedStructure is 8190')
|
|
1137
|
-
let isSequential = options.sequential;
|
|
1138
|
-
if (isSequential) {
|
|
1139
|
-
maxSharedStructures = 0;
|
|
1140
|
-
}
|
|
1141
|
-
if (!this.structures)
|
|
1142
|
-
this.structures = [];
|
|
1143
|
-
if (this.saveStructures)
|
|
1144
|
-
this.saveShared = this.saveStructures;
|
|
1145
|
-
let samplingPackedValues, packedObjectMap, sharedValues = options.sharedValues;
|
|
1146
|
-
let sharedPackedObjectMap;
|
|
1147
|
-
if (sharedValues) {
|
|
1148
|
-
sharedPackedObjectMap = Object.create(null);
|
|
1149
|
-
for (let i = 0, l = sharedValues.length; i < l; i++) {
|
|
1150
|
-
sharedPackedObjectMap[sharedValues[i]] = i;
|
|
1151
|
-
}
|
|
1152
|
-
}
|
|
1153
|
-
let recordIdsToRemove = [];
|
|
1154
|
-
let transitionsCount = 0;
|
|
1155
|
-
let serializationsSinceTransitionRebuild = 0;
|
|
1156
|
-
|
|
1157
|
-
this.mapEncode = function(value, encodeOptions) {
|
|
1158
|
-
// Experimental support for premapping keys using _keyMap instad of keyMap - not optiimised yet)
|
|
1159
|
-
if (this._keyMap && !this._mapped) {
|
|
1160
|
-
//console.log('encoding ', value)
|
|
1161
|
-
switch (value.constructor.name) {
|
|
1162
|
-
case 'Array':
|
|
1163
|
-
value = value.map(r => this.encodeKeys(r));
|
|
1164
|
-
break
|
|
1165
|
-
//case 'Map':
|
|
1166
|
-
// value = this.encodeKeys(value)
|
|
1167
|
-
// break
|
|
1168
|
-
}
|
|
1169
|
-
//this._mapped = true
|
|
1170
|
-
}
|
|
1171
|
-
return this.encode(value, encodeOptions)
|
|
1172
|
-
};
|
|
1173
|
-
|
|
1174
|
-
this.encode = function(value, encodeOptions) {
|
|
1175
|
-
if (!target) {
|
|
1176
|
-
target = new ByteArrayAllocate(8192);
|
|
1177
|
-
targetView = new DataView(target.buffer, 0, 8192);
|
|
1178
|
-
position$1 = 0;
|
|
1179
|
-
}
|
|
1180
|
-
safeEnd = target.length - 10;
|
|
1181
|
-
if (safeEnd - position$1 < 0x800) {
|
|
1182
|
-
// don't start too close to the end,
|
|
1183
|
-
target = new ByteArrayAllocate(target.length);
|
|
1184
|
-
targetView = new DataView(target.buffer, 0, target.length);
|
|
1185
|
-
safeEnd = target.length - 10;
|
|
1186
|
-
position$1 = 0;
|
|
1187
|
-
} else if (encodeOptions === REUSE_BUFFER_MODE)
|
|
1188
|
-
position$1 = (position$1 + 7) & 0x7ffffff8; // Word align to make any future copying of this buffer faster
|
|
1189
|
-
start = position$1;
|
|
1190
|
-
if (encoder.useSelfDescribedHeader) {
|
|
1191
|
-
targetView.setUint32(position$1, 0xd9d9f700); // tag two byte, then self-descriptive tag
|
|
1192
|
-
position$1 += 3;
|
|
1193
|
-
}
|
|
1194
|
-
referenceMap = encoder.structuredClone ? new Map() : null;
|
|
1195
|
-
if (encoder.bundleStrings && typeof value !== 'string') {
|
|
1196
|
-
bundledStrings$1 = [];
|
|
1197
|
-
bundledStrings$1.size = Infinity; // force a new bundle start on first string
|
|
1198
|
-
} else
|
|
1199
|
-
bundledStrings$1 = null;
|
|
1200
|
-
|
|
1201
|
-
sharedStructures = encoder.structures;
|
|
1202
|
-
if (sharedStructures) {
|
|
1203
|
-
if (sharedStructures.uninitialized) {
|
|
1204
|
-
let sharedData = encoder.getShared() || {};
|
|
1205
|
-
encoder.structures = sharedStructures = sharedData.structures || [];
|
|
1206
|
-
encoder.sharedVersion = sharedData.version;
|
|
1207
|
-
let sharedValues = encoder.sharedValues = sharedData.packedValues;
|
|
1208
|
-
if (sharedValues) {
|
|
1209
|
-
sharedPackedObjectMap = {};
|
|
1210
|
-
for (let i = 0, l = sharedValues.length; i < l; i++)
|
|
1211
|
-
sharedPackedObjectMap[sharedValues[i]] = i;
|
|
1212
|
-
}
|
|
1213
|
-
}
|
|
1214
|
-
let sharedStructuresLength = sharedStructures.length;
|
|
1215
|
-
if (sharedStructuresLength > maxSharedStructures && !isSequential)
|
|
1216
|
-
sharedStructuresLength = maxSharedStructures;
|
|
1217
|
-
if (!sharedStructures.transitions) {
|
|
1218
|
-
// rebuild our structure transitions
|
|
1219
|
-
sharedStructures.transitions = Object.create(null);
|
|
1220
|
-
for (let i = 0; i < sharedStructuresLength; i++) {
|
|
1221
|
-
let keys = sharedStructures[i];
|
|
1222
|
-
//console.log('shared struct keys:', keys)
|
|
1223
|
-
if (!keys)
|
|
1224
|
-
continue
|
|
1225
|
-
let nextTransition, transition = sharedStructures.transitions;
|
|
1226
|
-
for (let j = 0, l = keys.length; j < l; j++) {
|
|
1227
|
-
if (transition[RECORD_SYMBOL] === undefined)
|
|
1228
|
-
transition[RECORD_SYMBOL] = i;
|
|
1229
|
-
let key = keys[j];
|
|
1230
|
-
nextTransition = transition[key];
|
|
1231
|
-
if (!nextTransition) {
|
|
1232
|
-
nextTransition = transition[key] = Object.create(null);
|
|
1233
|
-
}
|
|
1234
|
-
transition = nextTransition;
|
|
1235
|
-
}
|
|
1236
|
-
transition[RECORD_SYMBOL] = i | 0x100000;
|
|
1237
|
-
}
|
|
1238
|
-
}
|
|
1239
|
-
if (!isSequential)
|
|
1240
|
-
sharedStructures.nextId = sharedStructuresLength;
|
|
1241
|
-
}
|
|
1242
|
-
if (hasSharedUpdate)
|
|
1243
|
-
hasSharedUpdate = false;
|
|
1244
|
-
structures = sharedStructures || [];
|
|
1245
|
-
packedObjectMap = sharedPackedObjectMap;
|
|
1246
|
-
if (options.pack) {
|
|
1247
|
-
let packedValues = new Map();
|
|
1248
|
-
packedValues.values = [];
|
|
1249
|
-
packedValues.encoder = encoder;
|
|
1250
|
-
packedValues.maxValues = options.maxPrivatePackedValues || (sharedPackedObjectMap ? 16 : Infinity);
|
|
1251
|
-
packedValues.objectMap = sharedPackedObjectMap || false;
|
|
1252
|
-
packedValues.samplingPackedValues = samplingPackedValues;
|
|
1253
|
-
findRepetitiveStrings(value, packedValues);
|
|
1254
|
-
if (packedValues.values.length > 0) {
|
|
1255
|
-
target[position$1++] = 0xd8; // one-byte tag
|
|
1256
|
-
target[position$1++] = 51; // tag 51 for packed shared structures https://www.potaroo.net/ietf/ids/draft-ietf-cbor-packed-03.txt
|
|
1257
|
-
writeArrayHeader(4);
|
|
1258
|
-
let valuesArray = packedValues.values;
|
|
1259
|
-
encode(valuesArray);
|
|
1260
|
-
writeArrayHeader(0); // prefixes
|
|
1261
|
-
writeArrayHeader(0); // suffixes
|
|
1262
|
-
packedObjectMap = Object.create(sharedPackedObjectMap || null);
|
|
1263
|
-
for (let i = 0, l = valuesArray.length; i < l; i++) {
|
|
1264
|
-
packedObjectMap[valuesArray[i]] = i;
|
|
1265
|
-
}
|
|
1266
|
-
}
|
|
1267
|
-
}
|
|
1268
|
-
try {
|
|
1269
|
-
encode(value);
|
|
1270
|
-
if (bundledStrings$1) {
|
|
1271
|
-
writeBundles(start, encode);
|
|
1272
|
-
}
|
|
1273
|
-
encoder.offset = position$1; // update the offset so next serialization doesn't write over our buffer, but can continue writing to same buffer sequentially
|
|
1274
|
-
if (referenceMap && referenceMap.idsToInsert) {
|
|
1275
|
-
position$1 += referenceMap.idsToInsert.length * 2;
|
|
1276
|
-
if (position$1 > safeEnd)
|
|
1277
|
-
makeRoom(position$1);
|
|
1278
|
-
encoder.offset = position$1;
|
|
1279
|
-
let serialized = insertIds(target.subarray(start, position$1), referenceMap.idsToInsert);
|
|
1280
|
-
referenceMap = null;
|
|
1281
|
-
return serialized
|
|
1282
|
-
}
|
|
1283
|
-
if (encodeOptions & REUSE_BUFFER_MODE) {
|
|
1284
|
-
target.start = start;
|
|
1285
|
-
target.end = position$1;
|
|
1286
|
-
return target
|
|
1287
|
-
}
|
|
1288
|
-
return target.subarray(start, position$1) // position can change if we call encode again in saveShared, so we get the buffer now
|
|
1289
|
-
} finally {
|
|
1290
|
-
if (sharedStructures) {
|
|
1291
|
-
if (serializationsSinceTransitionRebuild < 10)
|
|
1292
|
-
serializationsSinceTransitionRebuild++;
|
|
1293
|
-
if (sharedStructures.length > maxSharedStructures)
|
|
1294
|
-
sharedStructures.length = maxSharedStructures;
|
|
1295
|
-
if (transitionsCount > 10000) {
|
|
1296
|
-
// force a rebuild occasionally after a lot of transitions so it can get cleaned up
|
|
1297
|
-
sharedStructures.transitions = null;
|
|
1298
|
-
serializationsSinceTransitionRebuild = 0;
|
|
1299
|
-
transitionsCount = 0;
|
|
1300
|
-
if (recordIdsToRemove.length > 0)
|
|
1301
|
-
recordIdsToRemove = [];
|
|
1302
|
-
} else if (recordIdsToRemove.length > 0 && !isSequential) {
|
|
1303
|
-
for (let i = 0, l = recordIdsToRemove.length; i < l; i++) {
|
|
1304
|
-
recordIdsToRemove[i][RECORD_SYMBOL] = undefined;
|
|
1305
|
-
}
|
|
1306
|
-
recordIdsToRemove = [];
|
|
1307
|
-
//sharedStructures.nextId = maxSharedStructures
|
|
1308
|
-
}
|
|
1309
|
-
}
|
|
1310
|
-
if (hasSharedUpdate && encoder.saveShared) {
|
|
1311
|
-
if (encoder.structures.length > maxSharedStructures) {
|
|
1312
|
-
encoder.structures = encoder.structures.slice(0, maxSharedStructures);
|
|
1313
|
-
}
|
|
1314
|
-
// we can't rely on start/end with REUSE_BUFFER_MODE since they will (probably) change when we save
|
|
1315
|
-
let returnBuffer = target.subarray(start, position$1);
|
|
1316
|
-
if (encoder.updateSharedData() === false)
|
|
1317
|
-
return encoder.encode(value) // re-encode if it fails
|
|
1318
|
-
return returnBuffer
|
|
1319
|
-
}
|
|
1320
|
-
if (encodeOptions & RESET_BUFFER_MODE)
|
|
1321
|
-
position$1 = start;
|
|
1322
|
-
}
|
|
1323
|
-
};
|
|
1324
|
-
this.findCommonStringsToPack = () => {
|
|
1325
|
-
samplingPackedValues = new Map();
|
|
1326
|
-
if (!sharedPackedObjectMap)
|
|
1327
|
-
sharedPackedObjectMap = Object.create(null);
|
|
1328
|
-
return (options) => {
|
|
1329
|
-
let threshold = options && options.threshold || 4;
|
|
1330
|
-
let position = this.pack ? options.maxPrivatePackedValues || 16 : 0;
|
|
1331
|
-
if (!sharedValues)
|
|
1332
|
-
sharedValues = this.sharedValues = [];
|
|
1333
|
-
for (let [ key, status ] of samplingPackedValues) {
|
|
1334
|
-
if (status.count > threshold) {
|
|
1335
|
-
sharedPackedObjectMap[key] = position++;
|
|
1336
|
-
sharedValues.push(key);
|
|
1337
|
-
hasSharedUpdate = true;
|
|
1338
|
-
}
|
|
1339
|
-
}
|
|
1340
|
-
while (this.saveShared && this.updateSharedData() === false) {}
|
|
1341
|
-
samplingPackedValues = null;
|
|
1342
|
-
}
|
|
1343
|
-
};
|
|
1344
|
-
const encode = (value) => {
|
|
1345
|
-
if (position$1 > safeEnd)
|
|
1346
|
-
target = makeRoom(position$1);
|
|
1347
|
-
|
|
1348
|
-
var type = typeof value;
|
|
1349
|
-
var length;
|
|
1350
|
-
if (type === 'string') {
|
|
1351
|
-
if (packedObjectMap) {
|
|
1352
|
-
let packedPosition = packedObjectMap[value];
|
|
1353
|
-
if (packedPosition >= 0) {
|
|
1354
|
-
if (packedPosition < 16)
|
|
1355
|
-
target[position$1++] = packedPosition + 0xe0; // simple values, defined in https://www.potaroo.net/ietf/ids/draft-ietf-cbor-packed-03.txt
|
|
1356
|
-
else {
|
|
1357
|
-
target[position$1++] = 0xc6; // tag 6 defined in https://www.potaroo.net/ietf/ids/draft-ietf-cbor-packed-03.txt
|
|
1358
|
-
if (packedPosition & 1)
|
|
1359
|
-
encode((15 - packedPosition) >> 1);
|
|
1360
|
-
else
|
|
1361
|
-
encode((packedPosition - 16) >> 1);
|
|
1362
|
-
}
|
|
1363
|
-
return
|
|
1364
|
-
/* } else if (packedStatus.serializationId != serializationId) {
|
|
1365
|
-
packedStatus.serializationId = serializationId
|
|
1366
|
-
packedStatus.count = 1
|
|
1367
|
-
if (options.sharedPack) {
|
|
1368
|
-
let sharedCount = packedStatus.sharedCount = (packedStatus.sharedCount || 0) + 1
|
|
1369
|
-
if (shareCount > (options.sharedPack.threshold || 5)) {
|
|
1370
|
-
let sharedPosition = packedStatus.position = packedStatus.nextSharedPosition
|
|
1371
|
-
hasSharedUpdate = true
|
|
1372
|
-
if (sharedPosition < 16)
|
|
1373
|
-
target[position++] = sharedPosition + 0xc0
|
|
1374
|
-
|
|
1375
|
-
}
|
|
1376
|
-
}
|
|
1377
|
-
} // else any in-doc incrementation?*/
|
|
1378
|
-
} else if (samplingPackedValues && !options.pack) {
|
|
1379
|
-
let status = samplingPackedValues.get(value);
|
|
1380
|
-
if (status)
|
|
1381
|
-
status.count++;
|
|
1382
|
-
else
|
|
1383
|
-
samplingPackedValues.set(value, {
|
|
1384
|
-
count: 1,
|
|
1385
|
-
});
|
|
1386
|
-
}
|
|
1387
|
-
}
|
|
1388
|
-
let strLength = value.length;
|
|
1389
|
-
if (bundledStrings$1 && strLength >= 4 && strLength < 0x400) {
|
|
1390
|
-
if ((bundledStrings$1.size += strLength) > MAX_BUNDLE_SIZE) {
|
|
1391
|
-
let extStart;
|
|
1392
|
-
let maxBytes = (bundledStrings$1[0] ? bundledStrings$1[0].length * 3 + bundledStrings$1[1].length : 0) + 10;
|
|
1393
|
-
if (position$1 + maxBytes > safeEnd)
|
|
1394
|
-
target = makeRoom(position$1 + maxBytes);
|
|
1395
|
-
target[position$1++] = 0xd9; // tag 16-bit
|
|
1396
|
-
target[position$1++] = 0xdf; // tag 0xdff9
|
|
1397
|
-
target[position$1++] = 0xf9;
|
|
1398
|
-
// TODO: If we only have one bundle with any string data, only write one string bundle
|
|
1399
|
-
target[position$1++] = bundledStrings$1.position ? 0x84 : 0x82; // array of 4 or 2 elements depending on if we write bundles
|
|
1400
|
-
target[position$1++] = 0x1a; // 32-bit unsigned int
|
|
1401
|
-
extStart = position$1 - start;
|
|
1402
|
-
position$1 += 4; // reserve for writing bundle reference
|
|
1403
|
-
if (bundledStrings$1.position) {
|
|
1404
|
-
writeBundles(start, encode); // write the last bundles
|
|
1405
|
-
}
|
|
1406
|
-
bundledStrings$1 = ['', '']; // create new ones
|
|
1407
|
-
bundledStrings$1.size = 0;
|
|
1408
|
-
bundledStrings$1.position = extStart;
|
|
1409
|
-
}
|
|
1410
|
-
let twoByte = hasNonLatin.test(value);
|
|
1411
|
-
bundledStrings$1[twoByte ? 0 : 1] += value;
|
|
1412
|
-
target[position$1++] = twoByte ? 0xce : 0xcf;
|
|
1413
|
-
encode(strLength);
|
|
1414
|
-
return
|
|
1415
|
-
}
|
|
1416
|
-
let headerSize;
|
|
1417
|
-
// first we estimate the header size, so we can write to the correct location
|
|
1418
|
-
if (strLength < 0x20) {
|
|
1419
|
-
headerSize = 1;
|
|
1420
|
-
} else if (strLength < 0x100) {
|
|
1421
|
-
headerSize = 2;
|
|
1422
|
-
} else if (strLength < 0x10000) {
|
|
1423
|
-
headerSize = 3;
|
|
1424
|
-
} else {
|
|
1425
|
-
headerSize = 5;
|
|
1426
|
-
}
|
|
1427
|
-
let maxBytes = strLength * 3;
|
|
1428
|
-
if (position$1 + maxBytes > safeEnd)
|
|
1429
|
-
target = makeRoom(position$1 + maxBytes);
|
|
1430
|
-
|
|
1431
|
-
if (strLength < 0x40 || !encodeUtf8) {
|
|
1432
|
-
let i, c1, c2, strPosition = position$1 + headerSize;
|
|
1433
|
-
for (i = 0; i < strLength; i++) {
|
|
1434
|
-
c1 = value.charCodeAt(i);
|
|
1435
|
-
if (c1 < 0x80) {
|
|
1436
|
-
target[strPosition++] = c1;
|
|
1437
|
-
} else if (c1 < 0x800) {
|
|
1438
|
-
target[strPosition++] = c1 >> 6 | 0xc0;
|
|
1439
|
-
target[strPosition++] = c1 & 0x3f | 0x80;
|
|
1440
|
-
} else if (
|
|
1441
|
-
(c1 & 0xfc00) === 0xd800 &&
|
|
1442
|
-
((c2 = value.charCodeAt(i + 1)) & 0xfc00) === 0xdc00
|
|
1443
|
-
) {
|
|
1444
|
-
c1 = 0x10000 + ((c1 & 0x03ff) << 10) + (c2 & 0x03ff);
|
|
1445
|
-
i++;
|
|
1446
|
-
target[strPosition++] = c1 >> 18 | 0xf0;
|
|
1447
|
-
target[strPosition++] = c1 >> 12 & 0x3f | 0x80;
|
|
1448
|
-
target[strPosition++] = c1 >> 6 & 0x3f | 0x80;
|
|
1449
|
-
target[strPosition++] = c1 & 0x3f | 0x80;
|
|
1450
|
-
} else {
|
|
1451
|
-
target[strPosition++] = c1 >> 12 | 0xe0;
|
|
1452
|
-
target[strPosition++] = c1 >> 6 & 0x3f | 0x80;
|
|
1453
|
-
target[strPosition++] = c1 & 0x3f | 0x80;
|
|
1454
|
-
}
|
|
1455
|
-
}
|
|
1456
|
-
length = strPosition - position$1 - headerSize;
|
|
1457
|
-
} else {
|
|
1458
|
-
length = encodeUtf8(value, position$1 + headerSize, maxBytes);
|
|
1459
|
-
}
|
|
1460
|
-
|
|
1461
|
-
if (length < 0x18) {
|
|
1462
|
-
target[position$1++] = 0x60 | length;
|
|
1463
|
-
} else if (length < 0x100) {
|
|
1464
|
-
if (headerSize < 2) {
|
|
1465
|
-
target.copyWithin(position$1 + 2, position$1 + 1, position$1 + 1 + length);
|
|
1466
|
-
}
|
|
1467
|
-
target[position$1++] = 0x78;
|
|
1468
|
-
target[position$1++] = length;
|
|
1469
|
-
} else if (length < 0x10000) {
|
|
1470
|
-
if (headerSize < 3) {
|
|
1471
|
-
target.copyWithin(position$1 + 3, position$1 + 2, position$1 + 2 + length);
|
|
1472
|
-
}
|
|
1473
|
-
target[position$1++] = 0x79;
|
|
1474
|
-
target[position$1++] = length >> 8;
|
|
1475
|
-
target[position$1++] = length & 0xff;
|
|
1476
|
-
} else {
|
|
1477
|
-
if (headerSize < 5) {
|
|
1478
|
-
target.copyWithin(position$1 + 5, position$1 + 3, position$1 + 3 + length);
|
|
1479
|
-
}
|
|
1480
|
-
target[position$1++] = 0x7a;
|
|
1481
|
-
targetView.setUint32(position$1, length);
|
|
1482
|
-
position$1 += 4;
|
|
1483
|
-
}
|
|
1484
|
-
position$1 += length;
|
|
1485
|
-
} else if (type === 'number') {
|
|
1486
|
-
if (value >>> 0 === value) {// positive integer, 32-bit or less
|
|
1487
|
-
// positive uint
|
|
1488
|
-
if (value < 0x18) {
|
|
1489
|
-
target[position$1++] = value;
|
|
1490
|
-
} else if (value < 0x100) {
|
|
1491
|
-
target[position$1++] = 0x18;
|
|
1492
|
-
target[position$1++] = value;
|
|
1493
|
-
} else if (value < 0x10000) {
|
|
1494
|
-
target[position$1++] = 0x19;
|
|
1495
|
-
target[position$1++] = value >> 8;
|
|
1496
|
-
target[position$1++] = value & 0xff;
|
|
1497
|
-
} else {
|
|
1498
|
-
target[position$1++] = 0x1a;
|
|
1499
|
-
targetView.setUint32(position$1, value);
|
|
1500
|
-
position$1 += 4;
|
|
1501
|
-
}
|
|
1502
|
-
} else if (value >> 0 === value) { // negative integer
|
|
1503
|
-
if (value >= -0x18) {
|
|
1504
|
-
target[position$1++] = 0x1f - value;
|
|
1505
|
-
} else if (value >= -0x100) {
|
|
1506
|
-
target[position$1++] = 0x38;
|
|
1507
|
-
target[position$1++] = ~value;
|
|
1508
|
-
} else if (value >= -0x10000) {
|
|
1509
|
-
target[position$1++] = 0x39;
|
|
1510
|
-
targetView.setUint16(position$1, ~value);
|
|
1511
|
-
position$1 += 2;
|
|
1512
|
-
} else {
|
|
1513
|
-
target[position$1++] = 0x3a;
|
|
1514
|
-
targetView.setUint32(position$1, ~value);
|
|
1515
|
-
position$1 += 4;
|
|
1516
|
-
}
|
|
1517
|
-
} else {
|
|
1518
|
-
let useFloat32;
|
|
1519
|
-
if ((useFloat32 = this.useFloat32) > 0 && value < 0x100000000 && value >= -0x80000000) {
|
|
1520
|
-
target[position$1++] = 0xfa;
|
|
1521
|
-
targetView.setFloat32(position$1, value);
|
|
1522
|
-
let xShifted;
|
|
1523
|
-
if (useFloat32 < 4 ||
|
|
1524
|
-
// this checks for rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
|
|
1525
|
-
((xShifted = value * mult10[((target[position$1] & 0x7f) << 1) | (target[position$1 + 1] >> 7)]) >> 0) === xShifted) {
|
|
1526
|
-
position$1 += 4;
|
|
1527
|
-
return
|
|
1528
|
-
} else
|
|
1529
|
-
position$1--; // move back into position for writing a double
|
|
1530
|
-
}
|
|
1531
|
-
target[position$1++] = 0xfb;
|
|
1532
|
-
targetView.setFloat64(position$1, value);
|
|
1533
|
-
position$1 += 8;
|
|
1534
|
-
}
|
|
1535
|
-
} else if (type === 'object') {
|
|
1536
|
-
if (!value)
|
|
1537
|
-
target[position$1++] = 0xf6;
|
|
1538
|
-
else {
|
|
1539
|
-
if (referenceMap) {
|
|
1540
|
-
let referee = referenceMap.get(value);
|
|
1541
|
-
if (referee) {
|
|
1542
|
-
target[position$1++] = 0xd8;
|
|
1543
|
-
target[position$1++] = 29; // http://cbor.schmorp.de/value-sharing
|
|
1544
|
-
target[position$1++] = 0x19; // 16-bit uint
|
|
1545
|
-
if (!referee.references) {
|
|
1546
|
-
let idsToInsert = referenceMap.idsToInsert || (referenceMap.idsToInsert = []);
|
|
1547
|
-
referee.references = [];
|
|
1548
|
-
idsToInsert.push(referee);
|
|
1549
|
-
}
|
|
1550
|
-
referee.references.push(position$1 - start);
|
|
1551
|
-
position$1 += 2; // TODO: also support 32-bit
|
|
1552
|
-
return
|
|
1553
|
-
} else
|
|
1554
|
-
referenceMap.set(value, { offset: position$1 - start });
|
|
1555
|
-
}
|
|
1556
|
-
let constructor = value.constructor;
|
|
1557
|
-
if (constructor === Object) {
|
|
1558
|
-
writeObject(value, true);
|
|
1559
|
-
} else if (constructor === Array) {
|
|
1560
|
-
length = value.length;
|
|
1561
|
-
if (length < 0x18) {
|
|
1562
|
-
target[position$1++] = 0x80 | length;
|
|
1563
|
-
} else {
|
|
1564
|
-
writeArrayHeader(length);
|
|
1565
|
-
}
|
|
1566
|
-
for (let i = 0; i < length; i++) {
|
|
1567
|
-
encode(value[i]);
|
|
1568
|
-
}
|
|
1569
|
-
} else if (constructor === Map) {
|
|
1570
|
-
if (this.mapsAsObjects ? this.useTag259ForMaps !== false : this.useTag259ForMaps) {
|
|
1571
|
-
// use Tag 259 (https://github.com/shanewholloway/js-cbor-codec/blob/master/docs/CBOR-259-spec--explicit-maps.md) for maps if the user wants it that way
|
|
1572
|
-
target[position$1++] = 0xd9;
|
|
1573
|
-
target[position$1++] = 1;
|
|
1574
|
-
target[position$1++] = 3;
|
|
1575
|
-
}
|
|
1576
|
-
length = value.size;
|
|
1577
|
-
if (length < 0x18) {
|
|
1578
|
-
target[position$1++] = 0xa0 | length;
|
|
1579
|
-
} else if (length < 0x100) {
|
|
1580
|
-
target[position$1++] = 0xb8;
|
|
1581
|
-
target[position$1++] = length;
|
|
1582
|
-
} else if (length < 0x10000) {
|
|
1583
|
-
target[position$1++] = 0xb9;
|
|
1584
|
-
target[position$1++] = length >> 8;
|
|
1585
|
-
target[position$1++] = length & 0xff;
|
|
1586
|
-
} else {
|
|
1587
|
-
target[position$1++] = 0xba;
|
|
1588
|
-
targetView.setUint32(position$1, length);
|
|
1589
|
-
position$1 += 4;
|
|
1590
|
-
}
|
|
1591
|
-
if (encoder.keyMap) {
|
|
1592
|
-
for (let [ key, entryValue ] of value) {
|
|
1593
|
-
encode(encoder.encodeKey(key));
|
|
1594
|
-
encode(entryValue);
|
|
1595
|
-
}
|
|
1596
|
-
} else {
|
|
1597
|
-
for (let [ key, entryValue ] of value) {
|
|
1598
|
-
encode(key);
|
|
1599
|
-
encode(entryValue);
|
|
1600
|
-
}
|
|
1601
|
-
}
|
|
1602
|
-
} else {
|
|
1603
|
-
for (let i = 0, l = extensions.length; i < l; i++) {
|
|
1604
|
-
let extensionClass = extensionClasses[i];
|
|
1605
|
-
if (value instanceof extensionClass) {
|
|
1606
|
-
let extension = extensions[i];
|
|
1607
|
-
let tag = extension.tag;
|
|
1608
|
-
if (tag == undefined)
|
|
1609
|
-
tag = extension.getTag && extension.getTag(value);
|
|
1610
|
-
if (tag < 0x18) {
|
|
1611
|
-
target[position$1++] = 0xc0 | tag;
|
|
1612
|
-
} else if (tag < 0x100) {
|
|
1613
|
-
target[position$1++] = 0xd8;
|
|
1614
|
-
target[position$1++] = tag;
|
|
1615
|
-
} else if (tag < 0x10000) {
|
|
1616
|
-
target[position$1++] = 0xd9;
|
|
1617
|
-
target[position$1++] = tag >> 8;
|
|
1618
|
-
target[position$1++] = tag & 0xff;
|
|
1619
|
-
} else if (tag > -1) {
|
|
1620
|
-
target[position$1++] = 0xda;
|
|
1621
|
-
targetView.setUint32(position$1, tag);
|
|
1622
|
-
position$1 += 4;
|
|
1623
|
-
} // else undefined, don't write tag
|
|
1624
|
-
extension.encode.call(this, value, encode, makeRoom);
|
|
1625
|
-
return
|
|
1626
|
-
}
|
|
1627
|
-
}
|
|
1628
|
-
if (value[Symbol.iterator]) {
|
|
1629
|
-
target[position$1++] = 0x9f; // indefinite length array
|
|
1630
|
-
for (let entry of value) {
|
|
1631
|
-
encode(entry);
|
|
1632
|
-
}
|
|
1633
|
-
target[position$1++] = 0xff; // stop-code
|
|
1634
|
-
return
|
|
1635
|
-
}
|
|
1636
|
-
// no extension found, write as object
|
|
1637
|
-
writeObject(value, !value.hasOwnProperty); // if it doesn't have hasOwnProperty, don't do hasOwnProperty checks
|
|
1638
|
-
}
|
|
1639
|
-
}
|
|
1640
|
-
} else if (type === 'boolean') {
|
|
1641
|
-
target[position$1++] = value ? 0xf5 : 0xf4;
|
|
1642
|
-
} else if (type === 'bigint') {
|
|
1643
|
-
if (value < (BigInt(1)<<BigInt(64)) && value >= 0) {
|
|
1644
|
-
// use an unsigned int as long as it fits
|
|
1645
|
-
target[position$1++] = 0x1b;
|
|
1646
|
-
targetView.setBigUint64(position$1, value);
|
|
1647
|
-
} else if (value > -(BigInt(1)<<BigInt(64)) && value < 0) {
|
|
1648
|
-
// if we can fit an unsigned int, use that
|
|
1649
|
-
target[position$1++] = 0x3b;
|
|
1650
|
-
targetView.setBigUint64(position$1, -value - BigInt(1));
|
|
1651
|
-
} else {
|
|
1652
|
-
// overflow
|
|
1653
|
-
if (this.largeBigIntToFloat) {
|
|
1654
|
-
target[position$1++] = 0xfb;
|
|
1655
|
-
targetView.setFloat64(position$1, Number(value));
|
|
1656
|
-
} else {
|
|
1657
|
-
throw new RangeError(value + ' was too large to fit in CBOR 64-bit integer format, set largeBigIntToFloat to convert to float-64')
|
|
1658
|
-
}
|
|
1659
|
-
}
|
|
1660
|
-
position$1 += 8;
|
|
1661
|
-
} else if (type === 'undefined') {
|
|
1662
|
-
target[position$1++] = 0xf7;
|
|
1663
|
-
} else {
|
|
1664
|
-
throw new Error('Unknown type: ' + type)
|
|
1665
|
-
}
|
|
1666
|
-
};
|
|
1667
|
-
|
|
1668
|
-
const writeObject = this.useRecords === false ? this.variableMapSize ? (object) => {
|
|
1669
|
-
// this method is slightly slower, but generates "preferred serialization" (optimally small for smaller objects)
|
|
1670
|
-
let keys = Object.keys(object);
|
|
1671
|
-
let vals = Object.values(object);
|
|
1672
|
-
let length = keys.length;
|
|
1673
|
-
if (length < 0x18) {
|
|
1674
|
-
target[position$1++] = 0xa0 | length;
|
|
1675
|
-
} else if (length < 0x100) {
|
|
1676
|
-
target[position$1++] = 0xb8;
|
|
1677
|
-
target[position$1++] = length;
|
|
1678
|
-
} else if (length < 0x10000) {
|
|
1679
|
-
target[position$1++] = 0xb9;
|
|
1680
|
-
target[position$1++] = length >> 8;
|
|
1681
|
-
target[position$1++] = length & 0xff;
|
|
1682
|
-
} else {
|
|
1683
|
-
target[position$1++] = 0xba;
|
|
1684
|
-
targetView.setUint32(position$1, length);
|
|
1685
|
-
position$1 += 4;
|
|
1686
|
-
}
|
|
1687
|
-
if (encoder.keyMap) {
|
|
1688
|
-
for (let i = 0; i < length; i++) {
|
|
1689
|
-
encode(encodeKey(keys[i]));
|
|
1690
|
-
encode(vals[i]);
|
|
1691
|
-
}
|
|
1692
|
-
} else {
|
|
1693
|
-
for (let i = 0; i < length; i++) {
|
|
1694
|
-
encode(keys[i]);
|
|
1695
|
-
encode(vals[i]);
|
|
1696
|
-
}
|
|
1697
|
-
}
|
|
1698
|
-
} :
|
|
1699
|
-
(object, safePrototype) => {
|
|
1700
|
-
target[position$1++] = 0xb9; // always use map 16, so we can preallocate and set the length afterwards
|
|
1701
|
-
let objectOffset = position$1 - start;
|
|
1702
|
-
position$1 += 2;
|
|
1703
|
-
let size = 0;
|
|
1704
|
-
if (encoder.keyMap) {
|
|
1705
|
-
for (let key in object) if (safePrototype || object.hasOwnProperty(key)) {
|
|
1706
|
-
encode(encoder.encodeKey(key));
|
|
1707
|
-
encode(object[key]);
|
|
1708
|
-
size++;
|
|
1709
|
-
}
|
|
1710
|
-
} else {
|
|
1711
|
-
for (let key in object) if (safePrototype || object.hasOwnProperty(key)) {
|
|
1712
|
-
encode(key);
|
|
1713
|
-
encode(object[key]);
|
|
1714
|
-
size++;
|
|
1715
|
-
}
|
|
1716
|
-
}
|
|
1717
|
-
target[objectOffset++ + start] = size >> 8;
|
|
1718
|
-
target[objectOffset + start] = size & 0xff;
|
|
1719
|
-
} :
|
|
1720
|
-
(object, safePrototype) => {
|
|
1721
|
-
let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
|
|
1722
|
-
let newTransitions = 0;
|
|
1723
|
-
let length = 0;
|
|
1724
|
-
let parentRecordId;
|
|
1725
|
-
let keys;
|
|
1726
|
-
if (this.keyMap) {
|
|
1727
|
-
keys = Object.keys(object).map(k => this.encodeKey(k));
|
|
1728
|
-
length = keys.length;
|
|
1729
|
-
for (let i = 0; i < length; i++) {
|
|
1730
|
-
let key = keys[i];
|
|
1731
|
-
nextTransition = transition[key];
|
|
1732
|
-
if (!nextTransition) {
|
|
1733
|
-
nextTransition = transition[key] = Object.create(null);
|
|
1734
|
-
newTransitions++;
|
|
1735
|
-
}
|
|
1736
|
-
transition = nextTransition;
|
|
1737
|
-
}
|
|
1738
|
-
} else {
|
|
1739
|
-
for (let key in object) if (safePrototype || object.hasOwnProperty(key)) {
|
|
1740
|
-
nextTransition = transition[key];
|
|
1741
|
-
if (!nextTransition) {
|
|
1742
|
-
if (transition[RECORD_SYMBOL] & 0x100000) {// this indicates it is a brancheable/extendable terminal node, so we will use this record id and extend it
|
|
1743
|
-
parentRecordId = transition[RECORD_SYMBOL] & 0xffff;
|
|
1744
|
-
}
|
|
1745
|
-
nextTransition = transition[key] = Object.create(null);
|
|
1746
|
-
newTransitions++;
|
|
1747
|
-
}
|
|
1748
|
-
transition = nextTransition;
|
|
1749
|
-
length++;
|
|
1750
|
-
}
|
|
1751
|
-
}
|
|
1752
|
-
let recordId = transition[RECORD_SYMBOL];
|
|
1753
|
-
if (recordId !== undefined) {
|
|
1754
|
-
recordId &= 0xffff;
|
|
1755
|
-
target[position$1++] = 0xd9;
|
|
1756
|
-
target[position$1++] = (recordId >> 8) | 0xe0;
|
|
1757
|
-
target[position$1++] = recordId & 0xff;
|
|
1758
|
-
} else {
|
|
1759
|
-
if (!keys)
|
|
1760
|
-
keys = transition.__keys__ || (transition.__keys__ = Object.keys(object));
|
|
1761
|
-
if (parentRecordId === undefined) {
|
|
1762
|
-
recordId = structures.nextId++;
|
|
1763
|
-
if (!recordId) {
|
|
1764
|
-
recordId = 0;
|
|
1765
|
-
structures.nextId = 1;
|
|
1766
|
-
}
|
|
1767
|
-
if (recordId >= MAX_STRUCTURES) {// cycle back around
|
|
1768
|
-
structures.nextId = (recordId = maxSharedStructures) + 1;
|
|
1769
|
-
}
|
|
1770
|
-
} else {
|
|
1771
|
-
recordId = parentRecordId;
|
|
1772
|
-
}
|
|
1773
|
-
structures[recordId] = keys;
|
|
1774
|
-
if (recordId < maxSharedStructures) {
|
|
1775
|
-
target[position$1++] = 0xd9;
|
|
1776
|
-
target[position$1++] = (recordId >> 8) | 0xe0;
|
|
1777
|
-
target[position$1++] = recordId & 0xff;
|
|
1778
|
-
transition = structures.transitions;
|
|
1779
|
-
for (let i = 0; i < length; i++) {
|
|
1780
|
-
if (transition[RECORD_SYMBOL] === undefined || (transition[RECORD_SYMBOL] & 0x100000))
|
|
1781
|
-
transition[RECORD_SYMBOL] = recordId;
|
|
1782
|
-
transition = transition[keys[i]];
|
|
1783
|
-
}
|
|
1784
|
-
transition[RECORD_SYMBOL] = recordId | 0x100000; // indicates it is a extendable terminal
|
|
1785
|
-
hasSharedUpdate = true;
|
|
1786
|
-
} else {
|
|
1787
|
-
transition[RECORD_SYMBOL] = recordId;
|
|
1788
|
-
targetView.setUint32(position$1, 0xd9dfff00); // tag two byte, then record definition id
|
|
1789
|
-
position$1 += 3;
|
|
1790
|
-
if (newTransitions)
|
|
1791
|
-
transitionsCount += serializationsSinceTransitionRebuild * newTransitions;
|
|
1792
|
-
// record the removal of the id, we can maintain our shared structure
|
|
1793
|
-
if (recordIdsToRemove.length >= MAX_STRUCTURES - maxSharedStructures)
|
|
1794
|
-
recordIdsToRemove.shift()[RECORD_SYMBOL] = undefined; // we are cycling back through, and have to remove old ones
|
|
1795
|
-
recordIdsToRemove.push(transition);
|
|
1796
|
-
writeArrayHeader(length + 2);
|
|
1797
|
-
encode(0xe000 + recordId);
|
|
1798
|
-
encode(keys);
|
|
1799
|
-
for (let v of Object.values(object)) encode(v);
|
|
1800
|
-
return
|
|
1801
|
-
}
|
|
1802
|
-
}
|
|
1803
|
-
if (length < 0x18) { // write the array header
|
|
1804
|
-
target[position$1++] = 0x80 | length;
|
|
1805
|
-
} else {
|
|
1806
|
-
writeArrayHeader(length);
|
|
1807
|
-
}
|
|
1808
|
-
for (let key in object)
|
|
1809
|
-
if (safePrototype || object.hasOwnProperty(key))
|
|
1810
|
-
encode(object[key]);
|
|
1811
|
-
};
|
|
1812
|
-
const makeRoom = (end) => {
|
|
1813
|
-
let newSize;
|
|
1814
|
-
if (end > 0x1000000) {
|
|
1815
|
-
// special handling for really large buffers
|
|
1816
|
-
if ((end - start) > MAX_BUFFER_SIZE)
|
|
1817
|
-
throw new Error('Encoded buffer would be larger than maximum buffer size')
|
|
1818
|
-
newSize = Math.min(MAX_BUFFER_SIZE,
|
|
1819
|
-
Math.round(Math.max((end - start) * (end > 0x4000000 ? 1.25 : 2), 0x400000) / 0x1000) * 0x1000);
|
|
1820
|
-
} else // faster handling for smaller buffers
|
|
1821
|
-
newSize = ((Math.max((end - start) << 2, target.length - 1) >> 12) + 1) << 12;
|
|
1822
|
-
let newBuffer = new ByteArrayAllocate(newSize);
|
|
1823
|
-
targetView = new DataView(newBuffer.buffer, 0, newSize);
|
|
1824
|
-
if (target.copy)
|
|
1825
|
-
target.copy(newBuffer, 0, start, end);
|
|
1826
|
-
else
|
|
1827
|
-
newBuffer.set(target.slice(start, end));
|
|
1828
|
-
position$1 -= start;
|
|
1829
|
-
start = 0;
|
|
1830
|
-
safeEnd = newBuffer.length - 10;
|
|
1831
|
-
return target = newBuffer
|
|
1832
|
-
};
|
|
1833
|
-
}
|
|
1834
|
-
useBuffer(buffer) {
|
|
1835
|
-
// this means we are finished using our own buffer and we can write over it safely
|
|
1836
|
-
target = buffer;
|
|
1837
|
-
targetView = new DataView(target.buffer, target.byteOffset, target.byteLength);
|
|
1838
|
-
position$1 = 0;
|
|
1839
|
-
}
|
|
1840
|
-
clearSharedData() {
|
|
1841
|
-
if (this.structures)
|
|
1842
|
-
this.structures = [];
|
|
1843
|
-
if (this.sharedValues)
|
|
1844
|
-
this.sharedValues = undefined;
|
|
1845
|
-
}
|
|
1846
|
-
updateSharedData() {
|
|
1847
|
-
let lastVersion = this.sharedVersion || 0;
|
|
1848
|
-
this.sharedVersion = lastVersion + 1;
|
|
1849
|
-
let structuresCopy = this.structures.slice(0);
|
|
1850
|
-
let sharedData = new SharedData(structuresCopy, this.sharedValues, this.sharedVersion);
|
|
1851
|
-
let saveResults = this.saveShared(sharedData,
|
|
1852
|
-
existingShared => (existingShared && existingShared.version || 0) == lastVersion);
|
|
1853
|
-
if (saveResults === false) {
|
|
1854
|
-
// get updated structures and try again if the update failed
|
|
1855
|
-
sharedData = this.getShared() || {};
|
|
1856
|
-
this.structures = sharedData.structures || [];
|
|
1857
|
-
this.sharedValues = sharedData.packedValues;
|
|
1858
|
-
this.sharedVersion = sharedData.version;
|
|
1859
|
-
this.structures.nextId = this.structures.length;
|
|
1860
|
-
} else {
|
|
1861
|
-
// restore structures
|
|
1862
|
-
structuresCopy.forEach((structure, i) => this.structures[i] = structure);
|
|
1863
|
-
}
|
|
1864
|
-
// saveShared may fail to write and reload, or may have reloaded to check compatibility and overwrite saved data, either way load the correct shared data
|
|
1865
|
-
return saveResults
|
|
1866
|
-
}
|
|
1867
|
-
}
|
|
1868
|
-
class SharedData {
|
|
1869
|
-
constructor(structures, values, version) {
|
|
1870
|
-
this.structures = structures;
|
|
1871
|
-
this.packedValues = values;
|
|
1872
|
-
this.version = version;
|
|
1873
|
-
}
|
|
1874
|
-
}
|
|
1875
|
-
|
|
1876
|
-
function writeArrayHeader(length) {
|
|
1877
|
-
if (length < 0x18)
|
|
1878
|
-
target[position$1++] = 0x80 | length;
|
|
1879
|
-
else if (length < 0x100) {
|
|
1880
|
-
target[position$1++] = 0x98;
|
|
1881
|
-
target[position$1++] = length;
|
|
1882
|
-
} else if (length < 0x10000) {
|
|
1883
|
-
target[position$1++] = 0x99;
|
|
1884
|
-
target[position$1++] = length >> 8;
|
|
1885
|
-
target[position$1++] = length & 0xff;
|
|
1886
|
-
} else {
|
|
1887
|
-
target[position$1++] = 0x9a;
|
|
1888
|
-
targetView.setUint32(position$1, length);
|
|
1889
|
-
position$1 += 4;
|
|
1890
|
-
}
|
|
1891
|
-
}
|
|
1892
|
-
|
|
1893
|
-
function findRepetitiveStrings(value, packedValues) {
|
|
1894
|
-
switch(typeof value) {
|
|
1895
|
-
case 'string':
|
|
1896
|
-
if (value.length > 3) {
|
|
1897
|
-
if (packedValues.objectMap[value] > -1 || packedValues.values.length >= packedValues.maxValues)
|
|
1898
|
-
return
|
|
1899
|
-
let packedStatus = packedValues.get(value);
|
|
1900
|
-
if (packedStatus) {
|
|
1901
|
-
if (++packedStatus.count == 2) {
|
|
1902
|
-
packedValues.values.push(value);
|
|
1903
|
-
}
|
|
1904
|
-
} else {
|
|
1905
|
-
packedValues.set(value, {
|
|
1906
|
-
count: 1,
|
|
1907
|
-
});
|
|
1908
|
-
if (packedValues.samplingPackedValues) {
|
|
1909
|
-
let status = packedValues.samplingPackedValues.get(value);
|
|
1910
|
-
if (status)
|
|
1911
|
-
status.count++;
|
|
1912
|
-
else
|
|
1913
|
-
packedValues.samplingPackedValues.set(value, {
|
|
1914
|
-
count: 1,
|
|
1915
|
-
});
|
|
1916
|
-
}
|
|
1917
|
-
}
|
|
1918
|
-
}
|
|
1919
|
-
break
|
|
1920
|
-
case 'object':
|
|
1921
|
-
if (value) {
|
|
1922
|
-
if (value instanceof Array) {
|
|
1923
|
-
for (let i = 0, l = value.length; i < l; i++) {
|
|
1924
|
-
findRepetitiveStrings(value[i], packedValues);
|
|
1925
|
-
}
|
|
1926
|
-
|
|
1927
|
-
} else {
|
|
1928
|
-
let includeKeys = !packedValues.encoder.useRecords;
|
|
1929
|
-
for (var key in value) {
|
|
1930
|
-
if (value.hasOwnProperty(key)) {
|
|
1931
|
-
if (includeKeys)
|
|
1932
|
-
findRepetitiveStrings(key, packedValues);
|
|
1933
|
-
findRepetitiveStrings(value[key], packedValues);
|
|
1934
|
-
}
|
|
1935
|
-
}
|
|
1936
|
-
}
|
|
1937
|
-
}
|
|
1938
|
-
break
|
|
1939
|
-
case 'function': console.log(value);
|
|
1940
|
-
}
|
|
1941
|
-
}
|
|
1942
|
-
const isLittleEndianMachine$1 = new Uint8Array(new Uint16Array([1]).buffer)[0] == 1;
|
|
1943
|
-
extensionClasses = [ Date, Set, Error, RegExp, Tag, ArrayBuffer,
|
|
1944
|
-
Uint8Array, Uint8ClampedArray, Uint16Array, Uint32Array,
|
|
1945
|
-
typeof BigUint64Array == 'undefined' ? function() {} : BigUint64Array, Int8Array, Int16Array, Int32Array,
|
|
1946
|
-
typeof BigInt64Array == 'undefined' ? function() {} : BigInt64Array,
|
|
1947
|
-
Float32Array, Float64Array, SharedData];
|
|
1948
|
-
|
|
1949
|
-
//Object.getPrototypeOf(Uint8Array.prototype).constructor /*TypedArray*/
|
|
1950
|
-
extensions = [{
|
|
1951
|
-
tag: 1,
|
|
1952
|
-
encode(date, encode) {
|
|
1953
|
-
let seconds = date.getTime() / 1000;
|
|
1954
|
-
if ((this.useTimestamp32 || date.getMilliseconds() === 0) && seconds >= 0 && seconds < 0x100000000) {
|
|
1955
|
-
// Timestamp 32
|
|
1956
|
-
target[position$1++] = 0x1a;
|
|
1957
|
-
targetView.setUint32(position$1, seconds);
|
|
1958
|
-
position$1 += 4;
|
|
1959
|
-
} else {
|
|
1960
|
-
// Timestamp float64
|
|
1961
|
-
target[position$1++] = 0xfb;
|
|
1962
|
-
targetView.setFloat64(position$1, seconds);
|
|
1963
|
-
position$1 += 8;
|
|
1964
|
-
}
|
|
1965
|
-
}
|
|
1966
|
-
}, {
|
|
1967
|
-
tag: 258, // https://github.com/input-output-hk/cbor-sets-spec/blob/master/CBOR_SETS.md
|
|
1968
|
-
encode(set, encode) {
|
|
1969
|
-
let array = Array.from(set);
|
|
1970
|
-
encode(array);
|
|
1971
|
-
}
|
|
1972
|
-
}, {
|
|
1973
|
-
tag: 27, // http://cbor.schmorp.de/generic-object
|
|
1974
|
-
encode(error, encode) {
|
|
1975
|
-
encode([ error.name, error.message ]);
|
|
1976
|
-
}
|
|
1977
|
-
}, {
|
|
1978
|
-
tag: 27, // http://cbor.schmorp.de/generic-object
|
|
1979
|
-
encode(regex, encode) {
|
|
1980
|
-
encode([ 'RegExp', regex.source, regex.flags ]);
|
|
1981
|
-
}
|
|
1982
|
-
}, {
|
|
1983
|
-
getTag(tag) {
|
|
1984
|
-
return tag.tag
|
|
1985
|
-
},
|
|
1986
|
-
encode(tag, encode) {
|
|
1987
|
-
encode(tag.value);
|
|
1988
|
-
}
|
|
1989
|
-
}, {
|
|
1990
|
-
encode(arrayBuffer, encode, makeRoom) {
|
|
1991
|
-
writeBuffer(arrayBuffer, makeRoom);
|
|
1992
|
-
}
|
|
1993
|
-
}, {
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
typedArrayEncoder(
|
|
2005
|
-
typedArrayEncoder(
|
|
2006
|
-
typedArrayEncoder(
|
|
2007
|
-
typedArrayEncoder(
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
}
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
target[position$1++] =
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
target[position$1++] =
|
|
2063
|
-
|
|
2064
|
-
position$1
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
}
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
let
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
function
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
1097
|
+
let textEncoder;
|
|
1098
|
+
try {
|
|
1099
|
+
textEncoder = new TextEncoder();
|
|
1100
|
+
} catch (error) {}
|
|
1101
|
+
let extensions, extensionClasses;
|
|
1102
|
+
const hasNodeBuffer = typeof Buffer !== 'undefined';
|
|
1103
|
+
const ByteArrayAllocate = hasNodeBuffer ? Buffer.allocUnsafeSlow : Uint8Array;
|
|
1104
|
+
const ByteArray = hasNodeBuffer ? Buffer : Uint8Array;
|
|
1105
|
+
const MAX_STRUCTURES = 0x100;
|
|
1106
|
+
const MAX_BUFFER_SIZE = hasNodeBuffer ? 0x100000000 : 0x7fd00000;
|
|
1107
|
+
let target;
|
|
1108
|
+
let targetView;
|
|
1109
|
+
let position$1 = 0;
|
|
1110
|
+
let safeEnd;
|
|
1111
|
+
let bundledStrings$1 = null;
|
|
1112
|
+
const MAX_BUNDLE_SIZE = 0xf000;
|
|
1113
|
+
const hasNonLatin = /[\u0080-\uFFFF]/;
|
|
1114
|
+
const RECORD_SYMBOL = Symbol('record-id');
|
|
1115
|
+
class Encoder extends Decoder {
|
|
1116
|
+
constructor(options) {
|
|
1117
|
+
super(options);
|
|
1118
|
+
this.offset = 0;
|
|
1119
|
+
let start;
|
|
1120
|
+
let sharedStructures;
|
|
1121
|
+
let hasSharedUpdate;
|
|
1122
|
+
let structures;
|
|
1123
|
+
let referenceMap;
|
|
1124
|
+
options = options || {};
|
|
1125
|
+
let encodeUtf8 = ByteArray.prototype.utf8Write ? function(string, position, maxBytes) {
|
|
1126
|
+
return target.utf8Write(string, position, maxBytes)
|
|
1127
|
+
} : (textEncoder && textEncoder.encodeInto) ?
|
|
1128
|
+
function(string, position) {
|
|
1129
|
+
return textEncoder.encodeInto(string, target.subarray(position)).written
|
|
1130
|
+
} : false;
|
|
1131
|
+
|
|
1132
|
+
let encoder = this;
|
|
1133
|
+
let hasSharedStructures = options.structures || options.saveStructures;
|
|
1134
|
+
let maxSharedStructures = options.maxSharedStructures;
|
|
1135
|
+
if (maxSharedStructures == null)
|
|
1136
|
+
maxSharedStructures = hasSharedStructures ? 128 : 0;
|
|
1137
|
+
if (maxSharedStructures > 8190)
|
|
1138
|
+
throw new Error('Maximum maxSharedStructure is 8190')
|
|
1139
|
+
let isSequential = options.sequential;
|
|
1140
|
+
if (isSequential) {
|
|
1141
|
+
maxSharedStructures = 0;
|
|
1142
|
+
}
|
|
1143
|
+
if (!this.structures)
|
|
1144
|
+
this.structures = [];
|
|
1145
|
+
if (this.saveStructures)
|
|
1146
|
+
this.saveShared = this.saveStructures;
|
|
1147
|
+
let samplingPackedValues, packedObjectMap, sharedValues = options.sharedValues;
|
|
1148
|
+
let sharedPackedObjectMap;
|
|
1149
|
+
if (sharedValues) {
|
|
1150
|
+
sharedPackedObjectMap = Object.create(null);
|
|
1151
|
+
for (let i = 0, l = sharedValues.length; i < l; i++) {
|
|
1152
|
+
sharedPackedObjectMap[sharedValues[i]] = i;
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
let recordIdsToRemove = [];
|
|
1156
|
+
let transitionsCount = 0;
|
|
1157
|
+
let serializationsSinceTransitionRebuild = 0;
|
|
1158
|
+
|
|
1159
|
+
this.mapEncode = function(value, encodeOptions) {
|
|
1160
|
+
// Experimental support for premapping keys using _keyMap instad of keyMap - not optiimised yet)
|
|
1161
|
+
if (this._keyMap && !this._mapped) {
|
|
1162
|
+
//console.log('encoding ', value)
|
|
1163
|
+
switch (value.constructor.name) {
|
|
1164
|
+
case 'Array':
|
|
1165
|
+
value = value.map(r => this.encodeKeys(r));
|
|
1166
|
+
break
|
|
1167
|
+
//case 'Map':
|
|
1168
|
+
// value = this.encodeKeys(value)
|
|
1169
|
+
// break
|
|
1170
|
+
}
|
|
1171
|
+
//this._mapped = true
|
|
1172
|
+
}
|
|
1173
|
+
return this.encode(value, encodeOptions)
|
|
1174
|
+
};
|
|
1175
|
+
|
|
1176
|
+
this.encode = function(value, encodeOptions) {
|
|
1177
|
+
if (!target) {
|
|
1178
|
+
target = new ByteArrayAllocate(8192);
|
|
1179
|
+
targetView = new DataView(target.buffer, 0, 8192);
|
|
1180
|
+
position$1 = 0;
|
|
1181
|
+
}
|
|
1182
|
+
safeEnd = target.length - 10;
|
|
1183
|
+
if (safeEnd - position$1 < 0x800) {
|
|
1184
|
+
// don't start too close to the end,
|
|
1185
|
+
target = new ByteArrayAllocate(target.length);
|
|
1186
|
+
targetView = new DataView(target.buffer, 0, target.length);
|
|
1187
|
+
safeEnd = target.length - 10;
|
|
1188
|
+
position$1 = 0;
|
|
1189
|
+
} else if (encodeOptions === REUSE_BUFFER_MODE)
|
|
1190
|
+
position$1 = (position$1 + 7) & 0x7ffffff8; // Word align to make any future copying of this buffer faster
|
|
1191
|
+
start = position$1;
|
|
1192
|
+
if (encoder.useSelfDescribedHeader) {
|
|
1193
|
+
targetView.setUint32(position$1, 0xd9d9f700); // tag two byte, then self-descriptive tag
|
|
1194
|
+
position$1 += 3;
|
|
1195
|
+
}
|
|
1196
|
+
referenceMap = encoder.structuredClone ? new Map() : null;
|
|
1197
|
+
if (encoder.bundleStrings && typeof value !== 'string') {
|
|
1198
|
+
bundledStrings$1 = [];
|
|
1199
|
+
bundledStrings$1.size = Infinity; // force a new bundle start on first string
|
|
1200
|
+
} else
|
|
1201
|
+
bundledStrings$1 = null;
|
|
1202
|
+
|
|
1203
|
+
sharedStructures = encoder.structures;
|
|
1204
|
+
if (sharedStructures) {
|
|
1205
|
+
if (sharedStructures.uninitialized) {
|
|
1206
|
+
let sharedData = encoder.getShared() || {};
|
|
1207
|
+
encoder.structures = sharedStructures = sharedData.structures || [];
|
|
1208
|
+
encoder.sharedVersion = sharedData.version;
|
|
1209
|
+
let sharedValues = encoder.sharedValues = sharedData.packedValues;
|
|
1210
|
+
if (sharedValues) {
|
|
1211
|
+
sharedPackedObjectMap = {};
|
|
1212
|
+
for (let i = 0, l = sharedValues.length; i < l; i++)
|
|
1213
|
+
sharedPackedObjectMap[sharedValues[i]] = i;
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
let sharedStructuresLength = sharedStructures.length;
|
|
1217
|
+
if (sharedStructuresLength > maxSharedStructures && !isSequential)
|
|
1218
|
+
sharedStructuresLength = maxSharedStructures;
|
|
1219
|
+
if (!sharedStructures.transitions) {
|
|
1220
|
+
// rebuild our structure transitions
|
|
1221
|
+
sharedStructures.transitions = Object.create(null);
|
|
1222
|
+
for (let i = 0; i < sharedStructuresLength; i++) {
|
|
1223
|
+
let keys = sharedStructures[i];
|
|
1224
|
+
//console.log('shared struct keys:', keys)
|
|
1225
|
+
if (!keys)
|
|
1226
|
+
continue
|
|
1227
|
+
let nextTransition, transition = sharedStructures.transitions;
|
|
1228
|
+
for (let j = 0, l = keys.length; j < l; j++) {
|
|
1229
|
+
if (transition[RECORD_SYMBOL] === undefined)
|
|
1230
|
+
transition[RECORD_SYMBOL] = i;
|
|
1231
|
+
let key = keys[j];
|
|
1232
|
+
nextTransition = transition[key];
|
|
1233
|
+
if (!nextTransition) {
|
|
1234
|
+
nextTransition = transition[key] = Object.create(null);
|
|
1235
|
+
}
|
|
1236
|
+
transition = nextTransition;
|
|
1237
|
+
}
|
|
1238
|
+
transition[RECORD_SYMBOL] = i | 0x100000;
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
if (!isSequential)
|
|
1242
|
+
sharedStructures.nextId = sharedStructuresLength;
|
|
1243
|
+
}
|
|
1244
|
+
if (hasSharedUpdate)
|
|
1245
|
+
hasSharedUpdate = false;
|
|
1246
|
+
structures = sharedStructures || [];
|
|
1247
|
+
packedObjectMap = sharedPackedObjectMap;
|
|
1248
|
+
if (options.pack) {
|
|
1249
|
+
let packedValues = new Map();
|
|
1250
|
+
packedValues.values = [];
|
|
1251
|
+
packedValues.encoder = encoder;
|
|
1252
|
+
packedValues.maxValues = options.maxPrivatePackedValues || (sharedPackedObjectMap ? 16 : Infinity);
|
|
1253
|
+
packedValues.objectMap = sharedPackedObjectMap || false;
|
|
1254
|
+
packedValues.samplingPackedValues = samplingPackedValues;
|
|
1255
|
+
findRepetitiveStrings(value, packedValues);
|
|
1256
|
+
if (packedValues.values.length > 0) {
|
|
1257
|
+
target[position$1++] = 0xd8; // one-byte tag
|
|
1258
|
+
target[position$1++] = 51; // tag 51 for packed shared structures https://www.potaroo.net/ietf/ids/draft-ietf-cbor-packed-03.txt
|
|
1259
|
+
writeArrayHeader(4);
|
|
1260
|
+
let valuesArray = packedValues.values;
|
|
1261
|
+
encode(valuesArray);
|
|
1262
|
+
writeArrayHeader(0); // prefixes
|
|
1263
|
+
writeArrayHeader(0); // suffixes
|
|
1264
|
+
packedObjectMap = Object.create(sharedPackedObjectMap || null);
|
|
1265
|
+
for (let i = 0, l = valuesArray.length; i < l; i++) {
|
|
1266
|
+
packedObjectMap[valuesArray[i]] = i;
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
try {
|
|
1271
|
+
encode(value);
|
|
1272
|
+
if (bundledStrings$1) {
|
|
1273
|
+
writeBundles(start, encode);
|
|
1274
|
+
}
|
|
1275
|
+
encoder.offset = position$1; // update the offset so next serialization doesn't write over our buffer, but can continue writing to same buffer sequentially
|
|
1276
|
+
if (referenceMap && referenceMap.idsToInsert) {
|
|
1277
|
+
position$1 += referenceMap.idsToInsert.length * 2;
|
|
1278
|
+
if (position$1 > safeEnd)
|
|
1279
|
+
makeRoom(position$1);
|
|
1280
|
+
encoder.offset = position$1;
|
|
1281
|
+
let serialized = insertIds(target.subarray(start, position$1), referenceMap.idsToInsert);
|
|
1282
|
+
referenceMap = null;
|
|
1283
|
+
return serialized
|
|
1284
|
+
}
|
|
1285
|
+
if (encodeOptions & REUSE_BUFFER_MODE) {
|
|
1286
|
+
target.start = start;
|
|
1287
|
+
target.end = position$1;
|
|
1288
|
+
return target
|
|
1289
|
+
}
|
|
1290
|
+
return target.subarray(start, position$1) // position can change if we call encode again in saveShared, so we get the buffer now
|
|
1291
|
+
} finally {
|
|
1292
|
+
if (sharedStructures) {
|
|
1293
|
+
if (serializationsSinceTransitionRebuild < 10)
|
|
1294
|
+
serializationsSinceTransitionRebuild++;
|
|
1295
|
+
if (sharedStructures.length > maxSharedStructures)
|
|
1296
|
+
sharedStructures.length = maxSharedStructures;
|
|
1297
|
+
if (transitionsCount > 10000) {
|
|
1298
|
+
// force a rebuild occasionally after a lot of transitions so it can get cleaned up
|
|
1299
|
+
sharedStructures.transitions = null;
|
|
1300
|
+
serializationsSinceTransitionRebuild = 0;
|
|
1301
|
+
transitionsCount = 0;
|
|
1302
|
+
if (recordIdsToRemove.length > 0)
|
|
1303
|
+
recordIdsToRemove = [];
|
|
1304
|
+
} else if (recordIdsToRemove.length > 0 && !isSequential) {
|
|
1305
|
+
for (let i = 0, l = recordIdsToRemove.length; i < l; i++) {
|
|
1306
|
+
recordIdsToRemove[i][RECORD_SYMBOL] = undefined;
|
|
1307
|
+
}
|
|
1308
|
+
recordIdsToRemove = [];
|
|
1309
|
+
//sharedStructures.nextId = maxSharedStructures
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
if (hasSharedUpdate && encoder.saveShared) {
|
|
1313
|
+
if (encoder.structures.length > maxSharedStructures) {
|
|
1314
|
+
encoder.structures = encoder.structures.slice(0, maxSharedStructures);
|
|
1315
|
+
}
|
|
1316
|
+
// we can't rely on start/end with REUSE_BUFFER_MODE since they will (probably) change when we save
|
|
1317
|
+
let returnBuffer = target.subarray(start, position$1);
|
|
1318
|
+
if (encoder.updateSharedData() === false)
|
|
1319
|
+
return encoder.encode(value) // re-encode if it fails
|
|
1320
|
+
return returnBuffer
|
|
1321
|
+
}
|
|
1322
|
+
if (encodeOptions & RESET_BUFFER_MODE)
|
|
1323
|
+
position$1 = start;
|
|
1324
|
+
}
|
|
1325
|
+
};
|
|
1326
|
+
this.findCommonStringsToPack = () => {
|
|
1327
|
+
samplingPackedValues = new Map();
|
|
1328
|
+
if (!sharedPackedObjectMap)
|
|
1329
|
+
sharedPackedObjectMap = Object.create(null);
|
|
1330
|
+
return (options) => {
|
|
1331
|
+
let threshold = options && options.threshold || 4;
|
|
1332
|
+
let position = this.pack ? options.maxPrivatePackedValues || 16 : 0;
|
|
1333
|
+
if (!sharedValues)
|
|
1334
|
+
sharedValues = this.sharedValues = [];
|
|
1335
|
+
for (let [ key, status ] of samplingPackedValues) {
|
|
1336
|
+
if (status.count > threshold) {
|
|
1337
|
+
sharedPackedObjectMap[key] = position++;
|
|
1338
|
+
sharedValues.push(key);
|
|
1339
|
+
hasSharedUpdate = true;
|
|
1340
|
+
}
|
|
1341
|
+
}
|
|
1342
|
+
while (this.saveShared && this.updateSharedData() === false) {}
|
|
1343
|
+
samplingPackedValues = null;
|
|
1344
|
+
}
|
|
1345
|
+
};
|
|
1346
|
+
const encode = (value) => {
|
|
1347
|
+
if (position$1 > safeEnd)
|
|
1348
|
+
target = makeRoom(position$1);
|
|
1349
|
+
|
|
1350
|
+
var type = typeof value;
|
|
1351
|
+
var length;
|
|
1352
|
+
if (type === 'string') {
|
|
1353
|
+
if (packedObjectMap) {
|
|
1354
|
+
let packedPosition = packedObjectMap[value];
|
|
1355
|
+
if (packedPosition >= 0) {
|
|
1356
|
+
if (packedPosition < 16)
|
|
1357
|
+
target[position$1++] = packedPosition + 0xe0; // simple values, defined in https://www.potaroo.net/ietf/ids/draft-ietf-cbor-packed-03.txt
|
|
1358
|
+
else {
|
|
1359
|
+
target[position$1++] = 0xc6; // tag 6 defined in https://www.potaroo.net/ietf/ids/draft-ietf-cbor-packed-03.txt
|
|
1360
|
+
if (packedPosition & 1)
|
|
1361
|
+
encode((15 - packedPosition) >> 1);
|
|
1362
|
+
else
|
|
1363
|
+
encode((packedPosition - 16) >> 1);
|
|
1364
|
+
}
|
|
1365
|
+
return
|
|
1366
|
+
/* } else if (packedStatus.serializationId != serializationId) {
|
|
1367
|
+
packedStatus.serializationId = serializationId
|
|
1368
|
+
packedStatus.count = 1
|
|
1369
|
+
if (options.sharedPack) {
|
|
1370
|
+
let sharedCount = packedStatus.sharedCount = (packedStatus.sharedCount || 0) + 1
|
|
1371
|
+
if (shareCount > (options.sharedPack.threshold || 5)) {
|
|
1372
|
+
let sharedPosition = packedStatus.position = packedStatus.nextSharedPosition
|
|
1373
|
+
hasSharedUpdate = true
|
|
1374
|
+
if (sharedPosition < 16)
|
|
1375
|
+
target[position++] = sharedPosition + 0xc0
|
|
1376
|
+
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1379
|
+
} // else any in-doc incrementation?*/
|
|
1380
|
+
} else if (samplingPackedValues && !options.pack) {
|
|
1381
|
+
let status = samplingPackedValues.get(value);
|
|
1382
|
+
if (status)
|
|
1383
|
+
status.count++;
|
|
1384
|
+
else
|
|
1385
|
+
samplingPackedValues.set(value, {
|
|
1386
|
+
count: 1,
|
|
1387
|
+
});
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
let strLength = value.length;
|
|
1391
|
+
if (bundledStrings$1 && strLength >= 4 && strLength < 0x400) {
|
|
1392
|
+
if ((bundledStrings$1.size += strLength) > MAX_BUNDLE_SIZE) {
|
|
1393
|
+
let extStart;
|
|
1394
|
+
let maxBytes = (bundledStrings$1[0] ? bundledStrings$1[0].length * 3 + bundledStrings$1[1].length : 0) + 10;
|
|
1395
|
+
if (position$1 + maxBytes > safeEnd)
|
|
1396
|
+
target = makeRoom(position$1 + maxBytes);
|
|
1397
|
+
target[position$1++] = 0xd9; // tag 16-bit
|
|
1398
|
+
target[position$1++] = 0xdf; // tag 0xdff9
|
|
1399
|
+
target[position$1++] = 0xf9;
|
|
1400
|
+
// TODO: If we only have one bundle with any string data, only write one string bundle
|
|
1401
|
+
target[position$1++] = bundledStrings$1.position ? 0x84 : 0x82; // array of 4 or 2 elements depending on if we write bundles
|
|
1402
|
+
target[position$1++] = 0x1a; // 32-bit unsigned int
|
|
1403
|
+
extStart = position$1 - start;
|
|
1404
|
+
position$1 += 4; // reserve for writing bundle reference
|
|
1405
|
+
if (bundledStrings$1.position) {
|
|
1406
|
+
writeBundles(start, encode); // write the last bundles
|
|
1407
|
+
}
|
|
1408
|
+
bundledStrings$1 = ['', '']; // create new ones
|
|
1409
|
+
bundledStrings$1.size = 0;
|
|
1410
|
+
bundledStrings$1.position = extStart;
|
|
1411
|
+
}
|
|
1412
|
+
let twoByte = hasNonLatin.test(value);
|
|
1413
|
+
bundledStrings$1[twoByte ? 0 : 1] += value;
|
|
1414
|
+
target[position$1++] = twoByte ? 0xce : 0xcf;
|
|
1415
|
+
encode(strLength);
|
|
1416
|
+
return
|
|
1417
|
+
}
|
|
1418
|
+
let headerSize;
|
|
1419
|
+
// first we estimate the header size, so we can write to the correct location
|
|
1420
|
+
if (strLength < 0x20) {
|
|
1421
|
+
headerSize = 1;
|
|
1422
|
+
} else if (strLength < 0x100) {
|
|
1423
|
+
headerSize = 2;
|
|
1424
|
+
} else if (strLength < 0x10000) {
|
|
1425
|
+
headerSize = 3;
|
|
1426
|
+
} else {
|
|
1427
|
+
headerSize = 5;
|
|
1428
|
+
}
|
|
1429
|
+
let maxBytes = strLength * 3;
|
|
1430
|
+
if (position$1 + maxBytes > safeEnd)
|
|
1431
|
+
target = makeRoom(position$1 + maxBytes);
|
|
1432
|
+
|
|
1433
|
+
if (strLength < 0x40 || !encodeUtf8) {
|
|
1434
|
+
let i, c1, c2, strPosition = position$1 + headerSize;
|
|
1435
|
+
for (i = 0; i < strLength; i++) {
|
|
1436
|
+
c1 = value.charCodeAt(i);
|
|
1437
|
+
if (c1 < 0x80) {
|
|
1438
|
+
target[strPosition++] = c1;
|
|
1439
|
+
} else if (c1 < 0x800) {
|
|
1440
|
+
target[strPosition++] = c1 >> 6 | 0xc0;
|
|
1441
|
+
target[strPosition++] = c1 & 0x3f | 0x80;
|
|
1442
|
+
} else if (
|
|
1443
|
+
(c1 & 0xfc00) === 0xd800 &&
|
|
1444
|
+
((c2 = value.charCodeAt(i + 1)) & 0xfc00) === 0xdc00
|
|
1445
|
+
) {
|
|
1446
|
+
c1 = 0x10000 + ((c1 & 0x03ff) << 10) + (c2 & 0x03ff);
|
|
1447
|
+
i++;
|
|
1448
|
+
target[strPosition++] = c1 >> 18 | 0xf0;
|
|
1449
|
+
target[strPosition++] = c1 >> 12 & 0x3f | 0x80;
|
|
1450
|
+
target[strPosition++] = c1 >> 6 & 0x3f | 0x80;
|
|
1451
|
+
target[strPosition++] = c1 & 0x3f | 0x80;
|
|
1452
|
+
} else {
|
|
1453
|
+
target[strPosition++] = c1 >> 12 | 0xe0;
|
|
1454
|
+
target[strPosition++] = c1 >> 6 & 0x3f | 0x80;
|
|
1455
|
+
target[strPosition++] = c1 & 0x3f | 0x80;
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
length = strPosition - position$1 - headerSize;
|
|
1459
|
+
} else {
|
|
1460
|
+
length = encodeUtf8(value, position$1 + headerSize, maxBytes);
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1463
|
+
if (length < 0x18) {
|
|
1464
|
+
target[position$1++] = 0x60 | length;
|
|
1465
|
+
} else if (length < 0x100) {
|
|
1466
|
+
if (headerSize < 2) {
|
|
1467
|
+
target.copyWithin(position$1 + 2, position$1 + 1, position$1 + 1 + length);
|
|
1468
|
+
}
|
|
1469
|
+
target[position$1++] = 0x78;
|
|
1470
|
+
target[position$1++] = length;
|
|
1471
|
+
} else if (length < 0x10000) {
|
|
1472
|
+
if (headerSize < 3) {
|
|
1473
|
+
target.copyWithin(position$1 + 3, position$1 + 2, position$1 + 2 + length);
|
|
1474
|
+
}
|
|
1475
|
+
target[position$1++] = 0x79;
|
|
1476
|
+
target[position$1++] = length >> 8;
|
|
1477
|
+
target[position$1++] = length & 0xff;
|
|
1478
|
+
} else {
|
|
1479
|
+
if (headerSize < 5) {
|
|
1480
|
+
target.copyWithin(position$1 + 5, position$1 + 3, position$1 + 3 + length);
|
|
1481
|
+
}
|
|
1482
|
+
target[position$1++] = 0x7a;
|
|
1483
|
+
targetView.setUint32(position$1, length);
|
|
1484
|
+
position$1 += 4;
|
|
1485
|
+
}
|
|
1486
|
+
position$1 += length;
|
|
1487
|
+
} else if (type === 'number') {
|
|
1488
|
+
if (value >>> 0 === value) {// positive integer, 32-bit or less
|
|
1489
|
+
// positive uint
|
|
1490
|
+
if (value < 0x18) {
|
|
1491
|
+
target[position$1++] = value;
|
|
1492
|
+
} else if (value < 0x100) {
|
|
1493
|
+
target[position$1++] = 0x18;
|
|
1494
|
+
target[position$1++] = value;
|
|
1495
|
+
} else if (value < 0x10000) {
|
|
1496
|
+
target[position$1++] = 0x19;
|
|
1497
|
+
target[position$1++] = value >> 8;
|
|
1498
|
+
target[position$1++] = value & 0xff;
|
|
1499
|
+
} else {
|
|
1500
|
+
target[position$1++] = 0x1a;
|
|
1501
|
+
targetView.setUint32(position$1, value);
|
|
1502
|
+
position$1 += 4;
|
|
1503
|
+
}
|
|
1504
|
+
} else if (value >> 0 === value) { // negative integer
|
|
1505
|
+
if (value >= -0x18) {
|
|
1506
|
+
target[position$1++] = 0x1f - value;
|
|
1507
|
+
} else if (value >= -0x100) {
|
|
1508
|
+
target[position$1++] = 0x38;
|
|
1509
|
+
target[position$1++] = ~value;
|
|
1510
|
+
} else if (value >= -0x10000) {
|
|
1511
|
+
target[position$1++] = 0x39;
|
|
1512
|
+
targetView.setUint16(position$1, ~value);
|
|
1513
|
+
position$1 += 2;
|
|
1514
|
+
} else {
|
|
1515
|
+
target[position$1++] = 0x3a;
|
|
1516
|
+
targetView.setUint32(position$1, ~value);
|
|
1517
|
+
position$1 += 4;
|
|
1518
|
+
}
|
|
1519
|
+
} else {
|
|
1520
|
+
let useFloat32;
|
|
1521
|
+
if ((useFloat32 = this.useFloat32) > 0 && value < 0x100000000 && value >= -0x80000000) {
|
|
1522
|
+
target[position$1++] = 0xfa;
|
|
1523
|
+
targetView.setFloat32(position$1, value);
|
|
1524
|
+
let xShifted;
|
|
1525
|
+
if (useFloat32 < 4 ||
|
|
1526
|
+
// this checks for rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
|
|
1527
|
+
((xShifted = value * mult10[((target[position$1] & 0x7f) << 1) | (target[position$1 + 1] >> 7)]) >> 0) === xShifted) {
|
|
1528
|
+
position$1 += 4;
|
|
1529
|
+
return
|
|
1530
|
+
} else
|
|
1531
|
+
position$1--; // move back into position for writing a double
|
|
1532
|
+
}
|
|
1533
|
+
target[position$1++] = 0xfb;
|
|
1534
|
+
targetView.setFloat64(position$1, value);
|
|
1535
|
+
position$1 += 8;
|
|
1536
|
+
}
|
|
1537
|
+
} else if (type === 'object') {
|
|
1538
|
+
if (!value)
|
|
1539
|
+
target[position$1++] = 0xf6;
|
|
1540
|
+
else {
|
|
1541
|
+
if (referenceMap) {
|
|
1542
|
+
let referee = referenceMap.get(value);
|
|
1543
|
+
if (referee) {
|
|
1544
|
+
target[position$1++] = 0xd8;
|
|
1545
|
+
target[position$1++] = 29; // http://cbor.schmorp.de/value-sharing
|
|
1546
|
+
target[position$1++] = 0x19; // 16-bit uint
|
|
1547
|
+
if (!referee.references) {
|
|
1548
|
+
let idsToInsert = referenceMap.idsToInsert || (referenceMap.idsToInsert = []);
|
|
1549
|
+
referee.references = [];
|
|
1550
|
+
idsToInsert.push(referee);
|
|
1551
|
+
}
|
|
1552
|
+
referee.references.push(position$1 - start);
|
|
1553
|
+
position$1 += 2; // TODO: also support 32-bit
|
|
1554
|
+
return
|
|
1555
|
+
} else
|
|
1556
|
+
referenceMap.set(value, { offset: position$1 - start });
|
|
1557
|
+
}
|
|
1558
|
+
let constructor = value.constructor;
|
|
1559
|
+
if (constructor === Object) {
|
|
1560
|
+
writeObject(value, true);
|
|
1561
|
+
} else if (constructor === Array) {
|
|
1562
|
+
length = value.length;
|
|
1563
|
+
if (length < 0x18) {
|
|
1564
|
+
target[position$1++] = 0x80 | length;
|
|
1565
|
+
} else {
|
|
1566
|
+
writeArrayHeader(length);
|
|
1567
|
+
}
|
|
1568
|
+
for (let i = 0; i < length; i++) {
|
|
1569
|
+
encode(value[i]);
|
|
1570
|
+
}
|
|
1571
|
+
} else if (constructor === Map) {
|
|
1572
|
+
if (this.mapsAsObjects ? this.useTag259ForMaps !== false : this.useTag259ForMaps) {
|
|
1573
|
+
// use Tag 259 (https://github.com/shanewholloway/js-cbor-codec/blob/master/docs/CBOR-259-spec--explicit-maps.md) for maps if the user wants it that way
|
|
1574
|
+
target[position$1++] = 0xd9;
|
|
1575
|
+
target[position$1++] = 1;
|
|
1576
|
+
target[position$1++] = 3;
|
|
1577
|
+
}
|
|
1578
|
+
length = value.size;
|
|
1579
|
+
if (length < 0x18) {
|
|
1580
|
+
target[position$1++] = 0xa0 | length;
|
|
1581
|
+
} else if (length < 0x100) {
|
|
1582
|
+
target[position$1++] = 0xb8;
|
|
1583
|
+
target[position$1++] = length;
|
|
1584
|
+
} else if (length < 0x10000) {
|
|
1585
|
+
target[position$1++] = 0xb9;
|
|
1586
|
+
target[position$1++] = length >> 8;
|
|
1587
|
+
target[position$1++] = length & 0xff;
|
|
1588
|
+
} else {
|
|
1589
|
+
target[position$1++] = 0xba;
|
|
1590
|
+
targetView.setUint32(position$1, length);
|
|
1591
|
+
position$1 += 4;
|
|
1592
|
+
}
|
|
1593
|
+
if (encoder.keyMap) {
|
|
1594
|
+
for (let [ key, entryValue ] of value) {
|
|
1595
|
+
encode(encoder.encodeKey(key));
|
|
1596
|
+
encode(entryValue);
|
|
1597
|
+
}
|
|
1598
|
+
} else {
|
|
1599
|
+
for (let [ key, entryValue ] of value) {
|
|
1600
|
+
encode(key);
|
|
1601
|
+
encode(entryValue);
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1604
|
+
} else {
|
|
1605
|
+
for (let i = 0, l = extensions.length; i < l; i++) {
|
|
1606
|
+
let extensionClass = extensionClasses[i];
|
|
1607
|
+
if (value instanceof extensionClass) {
|
|
1608
|
+
let extension = extensions[i];
|
|
1609
|
+
let tag = extension.tag;
|
|
1610
|
+
if (tag == undefined)
|
|
1611
|
+
tag = extension.getTag && extension.getTag.call(this, value);
|
|
1612
|
+
if (tag < 0x18) {
|
|
1613
|
+
target[position$1++] = 0xc0 | tag;
|
|
1614
|
+
} else if (tag < 0x100) {
|
|
1615
|
+
target[position$1++] = 0xd8;
|
|
1616
|
+
target[position$1++] = tag;
|
|
1617
|
+
} else if (tag < 0x10000) {
|
|
1618
|
+
target[position$1++] = 0xd9;
|
|
1619
|
+
target[position$1++] = tag >> 8;
|
|
1620
|
+
target[position$1++] = tag & 0xff;
|
|
1621
|
+
} else if (tag > -1) {
|
|
1622
|
+
target[position$1++] = 0xda;
|
|
1623
|
+
targetView.setUint32(position$1, tag);
|
|
1624
|
+
position$1 += 4;
|
|
1625
|
+
} // else undefined, don't write tag
|
|
1626
|
+
extension.encode.call(this, value, encode, makeRoom);
|
|
1627
|
+
return
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1630
|
+
if (value[Symbol.iterator]) {
|
|
1631
|
+
target[position$1++] = 0x9f; // indefinite length array
|
|
1632
|
+
for (let entry of value) {
|
|
1633
|
+
encode(entry);
|
|
1634
|
+
}
|
|
1635
|
+
target[position$1++] = 0xff; // stop-code
|
|
1636
|
+
return
|
|
1637
|
+
}
|
|
1638
|
+
// no extension found, write as object
|
|
1639
|
+
writeObject(value, !value.hasOwnProperty); // if it doesn't have hasOwnProperty, don't do hasOwnProperty checks
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1642
|
+
} else if (type === 'boolean') {
|
|
1643
|
+
target[position$1++] = value ? 0xf5 : 0xf4;
|
|
1644
|
+
} else if (type === 'bigint') {
|
|
1645
|
+
if (value < (BigInt(1)<<BigInt(64)) && value >= 0) {
|
|
1646
|
+
// use an unsigned int as long as it fits
|
|
1647
|
+
target[position$1++] = 0x1b;
|
|
1648
|
+
targetView.setBigUint64(position$1, value);
|
|
1649
|
+
} else if (value > -(BigInt(1)<<BigInt(64)) && value < 0) {
|
|
1650
|
+
// if we can fit an unsigned int, use that
|
|
1651
|
+
target[position$1++] = 0x3b;
|
|
1652
|
+
targetView.setBigUint64(position$1, -value - BigInt(1));
|
|
1653
|
+
} else {
|
|
1654
|
+
// overflow
|
|
1655
|
+
if (this.largeBigIntToFloat) {
|
|
1656
|
+
target[position$1++] = 0xfb;
|
|
1657
|
+
targetView.setFloat64(position$1, Number(value));
|
|
1658
|
+
} else {
|
|
1659
|
+
throw new RangeError(value + ' was too large to fit in CBOR 64-bit integer format, set largeBigIntToFloat to convert to float-64')
|
|
1660
|
+
}
|
|
1661
|
+
}
|
|
1662
|
+
position$1 += 8;
|
|
1663
|
+
} else if (type === 'undefined') {
|
|
1664
|
+
target[position$1++] = 0xf7;
|
|
1665
|
+
} else {
|
|
1666
|
+
throw new Error('Unknown type: ' + type)
|
|
1667
|
+
}
|
|
1668
|
+
};
|
|
1669
|
+
|
|
1670
|
+
const writeObject = this.useRecords === false ? this.variableMapSize ? (object) => {
|
|
1671
|
+
// this method is slightly slower, but generates "preferred serialization" (optimally small for smaller objects)
|
|
1672
|
+
let keys = Object.keys(object);
|
|
1673
|
+
let vals = Object.values(object);
|
|
1674
|
+
let length = keys.length;
|
|
1675
|
+
if (length < 0x18) {
|
|
1676
|
+
target[position$1++] = 0xa0 | length;
|
|
1677
|
+
} else if (length < 0x100) {
|
|
1678
|
+
target[position$1++] = 0xb8;
|
|
1679
|
+
target[position$1++] = length;
|
|
1680
|
+
} else if (length < 0x10000) {
|
|
1681
|
+
target[position$1++] = 0xb9;
|
|
1682
|
+
target[position$1++] = length >> 8;
|
|
1683
|
+
target[position$1++] = length & 0xff;
|
|
1684
|
+
} else {
|
|
1685
|
+
target[position$1++] = 0xba;
|
|
1686
|
+
targetView.setUint32(position$1, length);
|
|
1687
|
+
position$1 += 4;
|
|
1688
|
+
}
|
|
1689
|
+
if (encoder.keyMap) {
|
|
1690
|
+
for (let i = 0; i < length; i++) {
|
|
1691
|
+
encode(encodeKey(keys[i]));
|
|
1692
|
+
encode(vals[i]);
|
|
1693
|
+
}
|
|
1694
|
+
} else {
|
|
1695
|
+
for (let i = 0; i < length; i++) {
|
|
1696
|
+
encode(keys[i]);
|
|
1697
|
+
encode(vals[i]);
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
} :
|
|
1701
|
+
(object, safePrototype) => {
|
|
1702
|
+
target[position$1++] = 0xb9; // always use map 16, so we can preallocate and set the length afterwards
|
|
1703
|
+
let objectOffset = position$1 - start;
|
|
1704
|
+
position$1 += 2;
|
|
1705
|
+
let size = 0;
|
|
1706
|
+
if (encoder.keyMap) {
|
|
1707
|
+
for (let key in object) if (safePrototype || object.hasOwnProperty(key)) {
|
|
1708
|
+
encode(encoder.encodeKey(key));
|
|
1709
|
+
encode(object[key]);
|
|
1710
|
+
size++;
|
|
1711
|
+
}
|
|
1712
|
+
} else {
|
|
1713
|
+
for (let key in object) if (safePrototype || object.hasOwnProperty(key)) {
|
|
1714
|
+
encode(key);
|
|
1715
|
+
encode(object[key]);
|
|
1716
|
+
size++;
|
|
1717
|
+
}
|
|
1718
|
+
}
|
|
1719
|
+
target[objectOffset++ + start] = size >> 8;
|
|
1720
|
+
target[objectOffset + start] = size & 0xff;
|
|
1721
|
+
} :
|
|
1722
|
+
(object, safePrototype) => {
|
|
1723
|
+
let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
|
|
1724
|
+
let newTransitions = 0;
|
|
1725
|
+
let length = 0;
|
|
1726
|
+
let parentRecordId;
|
|
1727
|
+
let keys;
|
|
1728
|
+
if (this.keyMap) {
|
|
1729
|
+
keys = Object.keys(object).map(k => this.encodeKey(k));
|
|
1730
|
+
length = keys.length;
|
|
1731
|
+
for (let i = 0; i < length; i++) {
|
|
1732
|
+
let key = keys[i];
|
|
1733
|
+
nextTransition = transition[key];
|
|
1734
|
+
if (!nextTransition) {
|
|
1735
|
+
nextTransition = transition[key] = Object.create(null);
|
|
1736
|
+
newTransitions++;
|
|
1737
|
+
}
|
|
1738
|
+
transition = nextTransition;
|
|
1739
|
+
}
|
|
1740
|
+
} else {
|
|
1741
|
+
for (let key in object) if (safePrototype || object.hasOwnProperty(key)) {
|
|
1742
|
+
nextTransition = transition[key];
|
|
1743
|
+
if (!nextTransition) {
|
|
1744
|
+
if (transition[RECORD_SYMBOL] & 0x100000) {// this indicates it is a brancheable/extendable terminal node, so we will use this record id and extend it
|
|
1745
|
+
parentRecordId = transition[RECORD_SYMBOL] & 0xffff;
|
|
1746
|
+
}
|
|
1747
|
+
nextTransition = transition[key] = Object.create(null);
|
|
1748
|
+
newTransitions++;
|
|
1749
|
+
}
|
|
1750
|
+
transition = nextTransition;
|
|
1751
|
+
length++;
|
|
1752
|
+
}
|
|
1753
|
+
}
|
|
1754
|
+
let recordId = transition[RECORD_SYMBOL];
|
|
1755
|
+
if (recordId !== undefined) {
|
|
1756
|
+
recordId &= 0xffff;
|
|
1757
|
+
target[position$1++] = 0xd9;
|
|
1758
|
+
target[position$1++] = (recordId >> 8) | 0xe0;
|
|
1759
|
+
target[position$1++] = recordId & 0xff;
|
|
1760
|
+
} else {
|
|
1761
|
+
if (!keys)
|
|
1762
|
+
keys = transition.__keys__ || (transition.__keys__ = Object.keys(object));
|
|
1763
|
+
if (parentRecordId === undefined) {
|
|
1764
|
+
recordId = structures.nextId++;
|
|
1765
|
+
if (!recordId) {
|
|
1766
|
+
recordId = 0;
|
|
1767
|
+
structures.nextId = 1;
|
|
1768
|
+
}
|
|
1769
|
+
if (recordId >= MAX_STRUCTURES) {// cycle back around
|
|
1770
|
+
structures.nextId = (recordId = maxSharedStructures) + 1;
|
|
1771
|
+
}
|
|
1772
|
+
} else {
|
|
1773
|
+
recordId = parentRecordId;
|
|
1774
|
+
}
|
|
1775
|
+
structures[recordId] = keys;
|
|
1776
|
+
if (recordId < maxSharedStructures) {
|
|
1777
|
+
target[position$1++] = 0xd9;
|
|
1778
|
+
target[position$1++] = (recordId >> 8) | 0xe0;
|
|
1779
|
+
target[position$1++] = recordId & 0xff;
|
|
1780
|
+
transition = structures.transitions;
|
|
1781
|
+
for (let i = 0; i < length; i++) {
|
|
1782
|
+
if (transition[RECORD_SYMBOL] === undefined || (transition[RECORD_SYMBOL] & 0x100000))
|
|
1783
|
+
transition[RECORD_SYMBOL] = recordId;
|
|
1784
|
+
transition = transition[keys[i]];
|
|
1785
|
+
}
|
|
1786
|
+
transition[RECORD_SYMBOL] = recordId | 0x100000; // indicates it is a extendable terminal
|
|
1787
|
+
hasSharedUpdate = true;
|
|
1788
|
+
} else {
|
|
1789
|
+
transition[RECORD_SYMBOL] = recordId;
|
|
1790
|
+
targetView.setUint32(position$1, 0xd9dfff00); // tag two byte, then record definition id
|
|
1791
|
+
position$1 += 3;
|
|
1792
|
+
if (newTransitions)
|
|
1793
|
+
transitionsCount += serializationsSinceTransitionRebuild * newTransitions;
|
|
1794
|
+
// record the removal of the id, we can maintain our shared structure
|
|
1795
|
+
if (recordIdsToRemove.length >= MAX_STRUCTURES - maxSharedStructures)
|
|
1796
|
+
recordIdsToRemove.shift()[RECORD_SYMBOL] = undefined; // we are cycling back through, and have to remove old ones
|
|
1797
|
+
recordIdsToRemove.push(transition);
|
|
1798
|
+
writeArrayHeader(length + 2);
|
|
1799
|
+
encode(0xe000 + recordId);
|
|
1800
|
+
encode(keys);
|
|
1801
|
+
for (let v of Object.values(object)) encode(v);
|
|
1802
|
+
return
|
|
1803
|
+
}
|
|
1804
|
+
}
|
|
1805
|
+
if (length < 0x18) { // write the array header
|
|
1806
|
+
target[position$1++] = 0x80 | length;
|
|
1807
|
+
} else {
|
|
1808
|
+
writeArrayHeader(length);
|
|
1809
|
+
}
|
|
1810
|
+
for (let key in object)
|
|
1811
|
+
if (safePrototype || object.hasOwnProperty(key))
|
|
1812
|
+
encode(object[key]);
|
|
1813
|
+
};
|
|
1814
|
+
const makeRoom = (end) => {
|
|
1815
|
+
let newSize;
|
|
1816
|
+
if (end > 0x1000000) {
|
|
1817
|
+
// special handling for really large buffers
|
|
1818
|
+
if ((end - start) > MAX_BUFFER_SIZE)
|
|
1819
|
+
throw new Error('Encoded buffer would be larger than maximum buffer size')
|
|
1820
|
+
newSize = Math.min(MAX_BUFFER_SIZE,
|
|
1821
|
+
Math.round(Math.max((end - start) * (end > 0x4000000 ? 1.25 : 2), 0x400000) / 0x1000) * 0x1000);
|
|
1822
|
+
} else // faster handling for smaller buffers
|
|
1823
|
+
newSize = ((Math.max((end - start) << 2, target.length - 1) >> 12) + 1) << 12;
|
|
1824
|
+
let newBuffer = new ByteArrayAllocate(newSize);
|
|
1825
|
+
targetView = new DataView(newBuffer.buffer, 0, newSize);
|
|
1826
|
+
if (target.copy)
|
|
1827
|
+
target.copy(newBuffer, 0, start, end);
|
|
1828
|
+
else
|
|
1829
|
+
newBuffer.set(target.slice(start, end));
|
|
1830
|
+
position$1 -= start;
|
|
1831
|
+
start = 0;
|
|
1832
|
+
safeEnd = newBuffer.length - 10;
|
|
1833
|
+
return target = newBuffer
|
|
1834
|
+
};
|
|
1835
|
+
}
|
|
1836
|
+
useBuffer(buffer) {
|
|
1837
|
+
// this means we are finished using our own buffer and we can write over it safely
|
|
1838
|
+
target = buffer;
|
|
1839
|
+
targetView = new DataView(target.buffer, target.byteOffset, target.byteLength);
|
|
1840
|
+
position$1 = 0;
|
|
1841
|
+
}
|
|
1842
|
+
clearSharedData() {
|
|
1843
|
+
if (this.structures)
|
|
1844
|
+
this.structures = [];
|
|
1845
|
+
if (this.sharedValues)
|
|
1846
|
+
this.sharedValues = undefined;
|
|
1847
|
+
}
|
|
1848
|
+
updateSharedData() {
|
|
1849
|
+
let lastVersion = this.sharedVersion || 0;
|
|
1850
|
+
this.sharedVersion = lastVersion + 1;
|
|
1851
|
+
let structuresCopy = this.structures.slice(0);
|
|
1852
|
+
let sharedData = new SharedData(structuresCopy, this.sharedValues, this.sharedVersion);
|
|
1853
|
+
let saveResults = this.saveShared(sharedData,
|
|
1854
|
+
existingShared => (existingShared && existingShared.version || 0) == lastVersion);
|
|
1855
|
+
if (saveResults === false) {
|
|
1856
|
+
// get updated structures and try again if the update failed
|
|
1857
|
+
sharedData = this.getShared() || {};
|
|
1858
|
+
this.structures = sharedData.structures || [];
|
|
1859
|
+
this.sharedValues = sharedData.packedValues;
|
|
1860
|
+
this.sharedVersion = sharedData.version;
|
|
1861
|
+
this.structures.nextId = this.structures.length;
|
|
1862
|
+
} else {
|
|
1863
|
+
// restore structures
|
|
1864
|
+
structuresCopy.forEach((structure, i) => this.structures[i] = structure);
|
|
1865
|
+
}
|
|
1866
|
+
// saveShared may fail to write and reload, or may have reloaded to check compatibility and overwrite saved data, either way load the correct shared data
|
|
1867
|
+
return saveResults
|
|
1868
|
+
}
|
|
1869
|
+
}
|
|
1870
|
+
class SharedData {
|
|
1871
|
+
constructor(structures, values, version) {
|
|
1872
|
+
this.structures = structures;
|
|
1873
|
+
this.packedValues = values;
|
|
1874
|
+
this.version = version;
|
|
1875
|
+
}
|
|
1876
|
+
}
|
|
1877
|
+
|
|
1878
|
+
function writeArrayHeader(length) {
|
|
1879
|
+
if (length < 0x18)
|
|
1880
|
+
target[position$1++] = 0x80 | length;
|
|
1881
|
+
else if (length < 0x100) {
|
|
1882
|
+
target[position$1++] = 0x98;
|
|
1883
|
+
target[position$1++] = length;
|
|
1884
|
+
} else if (length < 0x10000) {
|
|
1885
|
+
target[position$1++] = 0x99;
|
|
1886
|
+
target[position$1++] = length >> 8;
|
|
1887
|
+
target[position$1++] = length & 0xff;
|
|
1888
|
+
} else {
|
|
1889
|
+
target[position$1++] = 0x9a;
|
|
1890
|
+
targetView.setUint32(position$1, length);
|
|
1891
|
+
position$1 += 4;
|
|
1892
|
+
}
|
|
1893
|
+
}
|
|
1894
|
+
|
|
1895
|
+
function findRepetitiveStrings(value, packedValues) {
|
|
1896
|
+
switch(typeof value) {
|
|
1897
|
+
case 'string':
|
|
1898
|
+
if (value.length > 3) {
|
|
1899
|
+
if (packedValues.objectMap[value] > -1 || packedValues.values.length >= packedValues.maxValues)
|
|
1900
|
+
return
|
|
1901
|
+
let packedStatus = packedValues.get(value);
|
|
1902
|
+
if (packedStatus) {
|
|
1903
|
+
if (++packedStatus.count == 2) {
|
|
1904
|
+
packedValues.values.push(value);
|
|
1905
|
+
}
|
|
1906
|
+
} else {
|
|
1907
|
+
packedValues.set(value, {
|
|
1908
|
+
count: 1,
|
|
1909
|
+
});
|
|
1910
|
+
if (packedValues.samplingPackedValues) {
|
|
1911
|
+
let status = packedValues.samplingPackedValues.get(value);
|
|
1912
|
+
if (status)
|
|
1913
|
+
status.count++;
|
|
1914
|
+
else
|
|
1915
|
+
packedValues.samplingPackedValues.set(value, {
|
|
1916
|
+
count: 1,
|
|
1917
|
+
});
|
|
1918
|
+
}
|
|
1919
|
+
}
|
|
1920
|
+
}
|
|
1921
|
+
break
|
|
1922
|
+
case 'object':
|
|
1923
|
+
if (value) {
|
|
1924
|
+
if (value instanceof Array) {
|
|
1925
|
+
for (let i = 0, l = value.length; i < l; i++) {
|
|
1926
|
+
findRepetitiveStrings(value[i], packedValues);
|
|
1927
|
+
}
|
|
1928
|
+
|
|
1929
|
+
} else {
|
|
1930
|
+
let includeKeys = !packedValues.encoder.useRecords;
|
|
1931
|
+
for (var key in value) {
|
|
1932
|
+
if (value.hasOwnProperty(key)) {
|
|
1933
|
+
if (includeKeys)
|
|
1934
|
+
findRepetitiveStrings(key, packedValues);
|
|
1935
|
+
findRepetitiveStrings(value[key], packedValues);
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
}
|
|
1939
|
+
}
|
|
1940
|
+
break
|
|
1941
|
+
case 'function': console.log(value);
|
|
1942
|
+
}
|
|
1943
|
+
}
|
|
1944
|
+
const isLittleEndianMachine$1 = new Uint8Array(new Uint16Array([1]).buffer)[0] == 1;
|
|
1945
|
+
extensionClasses = [ Date, Set, Error, RegExp, Tag, ArrayBuffer,
|
|
1946
|
+
Uint8Array, Uint8ClampedArray, Uint16Array, Uint32Array,
|
|
1947
|
+
typeof BigUint64Array == 'undefined' ? function() {} : BigUint64Array, Int8Array, Int16Array, Int32Array,
|
|
1948
|
+
typeof BigInt64Array == 'undefined' ? function() {} : BigInt64Array,
|
|
1949
|
+
Float32Array, Float64Array, SharedData ];
|
|
1950
|
+
|
|
1951
|
+
//Object.getPrototypeOf(Uint8Array.prototype).constructor /*TypedArray*/
|
|
1952
|
+
extensions = [{ // Date
|
|
1953
|
+
tag: 1,
|
|
1954
|
+
encode(date, encode) {
|
|
1955
|
+
let seconds = date.getTime() / 1000;
|
|
1956
|
+
if ((this.useTimestamp32 || date.getMilliseconds() === 0) && seconds >= 0 && seconds < 0x100000000) {
|
|
1957
|
+
// Timestamp 32
|
|
1958
|
+
target[position$1++] = 0x1a;
|
|
1959
|
+
targetView.setUint32(position$1, seconds);
|
|
1960
|
+
position$1 += 4;
|
|
1961
|
+
} else {
|
|
1962
|
+
// Timestamp float64
|
|
1963
|
+
target[position$1++] = 0xfb;
|
|
1964
|
+
targetView.setFloat64(position$1, seconds);
|
|
1965
|
+
position$1 += 8;
|
|
1966
|
+
}
|
|
1967
|
+
}
|
|
1968
|
+
}, { // Set
|
|
1969
|
+
tag: 258, // https://github.com/input-output-hk/cbor-sets-spec/blob/master/CBOR_SETS.md
|
|
1970
|
+
encode(set, encode) {
|
|
1971
|
+
let array = Array.from(set);
|
|
1972
|
+
encode(array);
|
|
1973
|
+
}
|
|
1974
|
+
}, { // Error
|
|
1975
|
+
tag: 27, // http://cbor.schmorp.de/generic-object
|
|
1976
|
+
encode(error, encode) {
|
|
1977
|
+
encode([ error.name, error.message ]);
|
|
1978
|
+
}
|
|
1979
|
+
}, { // RegExp
|
|
1980
|
+
tag: 27, // http://cbor.schmorp.de/generic-object
|
|
1981
|
+
encode(regex, encode) {
|
|
1982
|
+
encode([ 'RegExp', regex.source, regex.flags ]);
|
|
1983
|
+
}
|
|
1984
|
+
}, { // Tag
|
|
1985
|
+
getTag(tag) {
|
|
1986
|
+
return tag.tag
|
|
1987
|
+
},
|
|
1988
|
+
encode(tag, encode) {
|
|
1989
|
+
encode(tag.value);
|
|
1990
|
+
}
|
|
1991
|
+
}, { // ArrayBuffer
|
|
1992
|
+
encode(arrayBuffer, encode, makeRoom) {
|
|
1993
|
+
writeBuffer(arrayBuffer, makeRoom);
|
|
1994
|
+
}
|
|
1995
|
+
}, { // Uint8Array
|
|
1996
|
+
getTag(typedArray) {
|
|
1997
|
+
if (typedArray.constructor === Uint8Array) {
|
|
1998
|
+
if (this.tagUint8Array || hasNodeBuffer && this.tagUint8Array !== false)
|
|
1999
|
+
return 64;
|
|
2000
|
+
} // else no tag
|
|
2001
|
+
},
|
|
2002
|
+
encode(typedArray, encode, makeRoom) {
|
|
2003
|
+
writeBuffer(typedArray, makeRoom);
|
|
2004
|
+
}
|
|
2005
|
+
},
|
|
2006
|
+
typedArrayEncoder(68, 1),
|
|
2007
|
+
typedArrayEncoder(69, 2),
|
|
2008
|
+
typedArrayEncoder(70, 4),
|
|
2009
|
+
typedArrayEncoder(71, 8),
|
|
2010
|
+
typedArrayEncoder(72, 1),
|
|
2011
|
+
typedArrayEncoder(77, 2),
|
|
2012
|
+
typedArrayEncoder(78, 4),
|
|
2013
|
+
typedArrayEncoder(79, 8),
|
|
2014
|
+
typedArrayEncoder(85, 4),
|
|
2015
|
+
typedArrayEncoder(86, 8),
|
|
2016
|
+
{
|
|
2017
|
+
encode(sharedData, encode) { // write SharedData
|
|
2018
|
+
let packedValues = sharedData.packedValues || [];
|
|
2019
|
+
let sharedStructures = sharedData.structures || [];
|
|
2020
|
+
if (packedValues.values.length > 0) {
|
|
2021
|
+
target[position$1++] = 0xd8; // one-byte tag
|
|
2022
|
+
target[position$1++] = 51; // tag 51 for packed shared structures https://www.potaroo.net/ietf/ids/draft-ietf-cbor-packed-03.txt
|
|
2023
|
+
writeArrayHeader(4);
|
|
2024
|
+
let valuesArray = packedValues.values;
|
|
2025
|
+
encode(valuesArray);
|
|
2026
|
+
writeArrayHeader(0); // prefixes
|
|
2027
|
+
writeArrayHeader(0); // suffixes
|
|
2028
|
+
packedObjectMap = Object.create(sharedPackedObjectMap || null);
|
|
2029
|
+
for (let i = 0, l = valuesArray.length; i < l; i++) {
|
|
2030
|
+
packedObjectMap[valuesArray[i]] = i;
|
|
2031
|
+
}
|
|
2032
|
+
}
|
|
2033
|
+
if (sharedStructures) {
|
|
2034
|
+
targetView.setUint32(position$1, 0xd9dffe00);
|
|
2035
|
+
position$1 += 3;
|
|
2036
|
+
let definitions = sharedStructures.slice(0);
|
|
2037
|
+
definitions.unshift(0xe000);
|
|
2038
|
+
definitions.push(new Tag(sharedData.version, 0x53687264));
|
|
2039
|
+
encode(definitions);
|
|
2040
|
+
} else
|
|
2041
|
+
encode(new Tag(sharedData.version, 0x53687264));
|
|
2042
|
+
}
|
|
2043
|
+
}];
|
|
2044
|
+
function typedArrayEncoder(tag, size) {
|
|
2045
|
+
if (!isLittleEndianMachine$1 && size > 1)
|
|
2046
|
+
tag -= 4; // the big endian equivalents are 4 less
|
|
2047
|
+
return {
|
|
2048
|
+
tag: tag,
|
|
2049
|
+
encode: function writeExtBuffer(typedArray, encode) {
|
|
2050
|
+
let length = typedArray.byteLength;
|
|
2051
|
+
let offset = typedArray.byteOffset || 0;
|
|
2052
|
+
let buffer = typedArray.buffer || typedArray;
|
|
2053
|
+
encode(hasNodeBuffer ? Buffer.from(buffer, offset, length) :
|
|
2054
|
+
new Uint8Array(buffer, offset, length));
|
|
2055
|
+
}
|
|
2056
|
+
}
|
|
2057
|
+
}
|
|
2058
|
+
function writeBuffer(buffer, makeRoom) {
|
|
2059
|
+
let length = buffer.byteLength;
|
|
2060
|
+
if (length < 0x18) {
|
|
2061
|
+
target[position$1++] = 0x40 + length;
|
|
2062
|
+
} else if (length < 0x100) {
|
|
2063
|
+
target[position$1++] = 0x58;
|
|
2064
|
+
target[position$1++] = length;
|
|
2065
|
+
} else if (length < 0x10000) {
|
|
2066
|
+
target[position$1++] = 0x59;
|
|
2067
|
+
target[position$1++] = length >> 8;
|
|
2068
|
+
target[position$1++] = length & 0xff;
|
|
2069
|
+
} else {
|
|
2070
|
+
target[position$1++] = 0x5a;
|
|
2071
|
+
targetView.setUint32(position$1, length);
|
|
2072
|
+
position$1 += 4;
|
|
2073
|
+
}
|
|
2074
|
+
if (position$1 + length >= target.length) {
|
|
2075
|
+
makeRoom(position$1 + length);
|
|
2076
|
+
}
|
|
2077
|
+
// if it is already a typed array (has an ArrayBuffer), use that, but if it is an ArrayBuffer itself,
|
|
2078
|
+
// must wrap it to set it.
|
|
2079
|
+
target.set(buffer.buffer ? buffer : new Uint8Array(buffer), position$1);
|
|
2080
|
+
position$1 += length;
|
|
2081
|
+
}
|
|
2082
|
+
|
|
2083
|
+
function insertIds(serialized, idsToInsert) {
|
|
2084
|
+
// insert the ids that need to be referenced for structured clones
|
|
2085
|
+
let nextId;
|
|
2086
|
+
let distanceToMove = idsToInsert.length * 2;
|
|
2087
|
+
let lastEnd = serialized.length - distanceToMove;
|
|
2088
|
+
idsToInsert.sort((a, b) => a.offset > b.offset ? 1 : -1);
|
|
2089
|
+
for (let id = 0; id < idsToInsert.length; id++) {
|
|
2090
|
+
let referee = idsToInsert[id];
|
|
2091
|
+
referee.id = id;
|
|
2092
|
+
for (let position of referee.references) {
|
|
2093
|
+
serialized[position++] = id >> 8;
|
|
2094
|
+
serialized[position] = id & 0xff;
|
|
2095
|
+
}
|
|
2096
|
+
}
|
|
2097
|
+
while (nextId = idsToInsert.pop()) {
|
|
2098
|
+
let offset = nextId.offset;
|
|
2099
|
+
serialized.copyWithin(offset + distanceToMove, offset, lastEnd);
|
|
2100
|
+
distanceToMove -= 2;
|
|
2101
|
+
let position = offset + distanceToMove;
|
|
2102
|
+
serialized[position++] = 0xd8;
|
|
2103
|
+
serialized[position++] = 28; // http://cbor.schmorp.de/value-sharing
|
|
2104
|
+
lastEnd = offset;
|
|
2105
|
+
}
|
|
2106
|
+
return serialized
|
|
2107
|
+
}
|
|
2108
|
+
function writeBundles(start, encode) {
|
|
2109
|
+
targetView.setUint32(bundledStrings$1.position + start, position$1 - bundledStrings$1.position - start + 1); // the offset to bundle
|
|
2110
|
+
let writeStrings = bundledStrings$1;
|
|
2111
|
+
bundledStrings$1 = null;
|
|
2112
|
+
encode(writeStrings[0]);
|
|
2113
|
+
encode(writeStrings[1]);
|
|
2114
|
+
}
|
|
2115
|
+
|
|
2116
|
+
function addExtension$1(extension) {
|
|
2117
|
+
if (extension.Class) {
|
|
2118
|
+
if (!extension.encode)
|
|
2119
|
+
throw new Error('Extension has no encode function')
|
|
2120
|
+
extensionClasses.unshift(extension.Class);
|
|
2121
|
+
extensions.unshift(extension);
|
|
2122
|
+
}
|
|
2123
|
+
addExtension(extension);
|
|
2124
|
+
}
|
|
2125
|
+
let defaultEncoder = new Encoder({ useRecords: false });
|
|
2126
|
+
const encode = defaultEncoder.encode;
|
|
2127
|
+
const { NEVER, ALWAYS, DECIMAL_ROUND, DECIMAL_FIT } = FLOAT32_OPTIONS;
|
|
2128
|
+
const REUSE_BUFFER_MODE = 512;
|
|
2119
2129
|
const RESET_BUFFER_MODE = 1024;
|
|
2120
2130
|
|
|
2121
|
-
class EncoderStream extends stream.Transform {
|
|
2122
|
-
constructor(options) {
|
|
2123
|
-
if (!options)
|
|
2124
|
-
options = {};
|
|
2125
|
-
options.writableObjectMode = true;
|
|
2126
|
-
super(options);
|
|
2127
|
-
options.sequential = true;
|
|
2128
|
-
this.encoder = options.encoder || new Encoder(options);
|
|
2129
|
-
}
|
|
2130
|
-
_transform(value, encoding, callback) {
|
|
2131
|
-
this.push(this.encoder.encode(value));
|
|
2132
|
-
callback();
|
|
2133
|
-
}
|
|
2134
|
-
}
|
|
2135
|
-
|
|
2136
|
-
class DecoderStream extends stream.Transform {
|
|
2137
|
-
constructor(options) {
|
|
2138
|
-
if (!options)
|
|
2139
|
-
options = {};
|
|
2140
|
-
options.objectMode = true;
|
|
2141
|
-
super(options);
|
|
2142
|
-
options.structures = [];
|
|
2143
|
-
this.decoder = options.decoder || new Decoder(options);
|
|
2144
|
-
}
|
|
2145
|
-
_transform(chunk, encoding, callback) {
|
|
2146
|
-
if (this.incompleteBuffer) {
|
|
2147
|
-
chunk = Buffer.concat([this.incompleteBuffer, chunk]);
|
|
2148
|
-
this.incompleteBuffer = null;
|
|
2149
|
-
}
|
|
2150
|
-
let values;
|
|
2151
|
-
try {
|
|
2152
|
-
values = this.decoder.decodeMultiple(chunk);
|
|
2153
|
-
} catch(error) {
|
|
2154
|
-
if (error.incomplete) {
|
|
2155
|
-
this.incompleteBuffer = chunk.slice(error.lastPosition);
|
|
2156
|
-
values = error.values;
|
|
2157
|
-
}
|
|
2158
|
-
else
|
|
2159
|
-
throw error
|
|
2160
|
-
} finally {
|
|
2161
|
-
for (let value of values || []) {
|
|
2162
|
-
if (value === null)
|
|
2163
|
-
value = this.getNullValue();
|
|
2164
|
-
this.push(value);
|
|
2165
|
-
}
|
|
2166
|
-
}
|
|
2167
|
-
if (callback) callback();
|
|
2168
|
-
}
|
|
2169
|
-
getNullValue() {
|
|
2170
|
-
return Symbol.for(null)
|
|
2171
|
-
}
|
|
2131
|
+
class EncoderStream extends stream.Transform {
|
|
2132
|
+
constructor(options) {
|
|
2133
|
+
if (!options)
|
|
2134
|
+
options = {};
|
|
2135
|
+
options.writableObjectMode = true;
|
|
2136
|
+
super(options);
|
|
2137
|
+
options.sequential = true;
|
|
2138
|
+
this.encoder = options.encoder || new Encoder(options);
|
|
2139
|
+
}
|
|
2140
|
+
_transform(value, encoding, callback) {
|
|
2141
|
+
this.push(this.encoder.encode(value));
|
|
2142
|
+
callback();
|
|
2143
|
+
}
|
|
2172
2144
|
}
|
|
2173
2145
|
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
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
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
return (function * iter () {
|
|
2244
|
-
for (const value of bufferIterator) {
|
|
2245
|
-
yield * parser(value);
|
|
2246
|
-
}
|
|
2247
|
-
})()
|
|
2248
|
-
} else if (typeof bufferIterator[Symbol.asyncIterator] === 'function') {
|
|
2249
|
-
return (async function * iter () {
|
|
2250
|
-
for await (const value of bufferIterator) {
|
|
2251
|
-
yield * parser(value);
|
|
2252
|
-
}
|
|
2253
|
-
})()
|
|
2254
|
-
}
|
|
2146
|
+
class DecoderStream extends stream.Transform {
|
|
2147
|
+
constructor(options) {
|
|
2148
|
+
if (!options)
|
|
2149
|
+
options = {};
|
|
2150
|
+
options.objectMode = true;
|
|
2151
|
+
super(options);
|
|
2152
|
+
options.structures = [];
|
|
2153
|
+
this.decoder = options.decoder || new Decoder(options);
|
|
2154
|
+
}
|
|
2155
|
+
_transform(chunk, encoding, callback) {
|
|
2156
|
+
if (this.incompleteBuffer) {
|
|
2157
|
+
chunk = Buffer.concat([this.incompleteBuffer, chunk]);
|
|
2158
|
+
this.incompleteBuffer = null;
|
|
2159
|
+
}
|
|
2160
|
+
let values;
|
|
2161
|
+
try {
|
|
2162
|
+
values = this.decoder.decodeMultiple(chunk);
|
|
2163
|
+
} catch(error) {
|
|
2164
|
+
if (error.incomplete) {
|
|
2165
|
+
this.incompleteBuffer = chunk.slice(error.lastPosition);
|
|
2166
|
+
values = error.values;
|
|
2167
|
+
}
|
|
2168
|
+
else
|
|
2169
|
+
throw error
|
|
2170
|
+
} finally {
|
|
2171
|
+
for (let value of values || []) {
|
|
2172
|
+
if (value === null)
|
|
2173
|
+
value = this.getNullValue();
|
|
2174
|
+
this.push(value);
|
|
2175
|
+
}
|
|
2176
|
+
}
|
|
2177
|
+
if (callback) callback();
|
|
2178
|
+
}
|
|
2179
|
+
getNullValue() {
|
|
2180
|
+
return Symbol.for(null)
|
|
2181
|
+
}
|
|
2182
|
+
}
|
|
2183
|
+
|
|
2184
|
+
/**
|
|
2185
|
+
* Given an Iterable first argument, returns an Iterable where each value is encoded as a Buffer
|
|
2186
|
+
* If the argument is only Async Iterable, the return value will be an Async Iterable.
|
|
2187
|
+
* @param {Iterable|Iterator|AsyncIterable|AsyncIterator} objectIterator - iterable source, like a Readable object stream, an array, Set, or custom object
|
|
2188
|
+
* @param {options} [options] - cbor-x Encoder options
|
|
2189
|
+
* @returns {IterableIterator|Promise.<AsyncIterableIterator>}
|
|
2190
|
+
*/
|
|
2191
|
+
function encodeIter (objectIterator, options = {}) {
|
|
2192
|
+
if (!objectIterator || typeof objectIterator !== 'object') {
|
|
2193
|
+
throw new Error('first argument must be an Iterable, Async Iterable, or a Promise for an Async Iterable')
|
|
2194
|
+
} else if (typeof objectIterator[Symbol.iterator] === 'function') {
|
|
2195
|
+
return encodeIterSync(objectIterator, options)
|
|
2196
|
+
} else if (typeof objectIterator.then === 'function' || typeof objectIterator[Symbol.asyncIterator] === 'function') {
|
|
2197
|
+
return encodeIterAsync(objectIterator, options)
|
|
2198
|
+
} else {
|
|
2199
|
+
throw new Error('first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a Promise')
|
|
2200
|
+
}
|
|
2201
|
+
}
|
|
2202
|
+
|
|
2203
|
+
function * encodeIterSync (objectIterator, options) {
|
|
2204
|
+
const encoder = new Encoder(options);
|
|
2205
|
+
for (const value of objectIterator) {
|
|
2206
|
+
yield encoder.encode(value);
|
|
2207
|
+
}
|
|
2208
|
+
}
|
|
2209
|
+
|
|
2210
|
+
async function * encodeIterAsync (objectIterator, options) {
|
|
2211
|
+
const encoder = new Encoder(options);
|
|
2212
|
+
for await (const value of objectIterator) {
|
|
2213
|
+
yield encoder.encode(value);
|
|
2214
|
+
}
|
|
2255
2215
|
}
|
|
2256
2216
|
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2217
|
+
/**
|
|
2218
|
+
* Given an Iterable/Iterator input which yields buffers, returns an IterableIterator which yields sync decoded objects
|
|
2219
|
+
* Or, given an Async Iterable/Iterator which yields promises resolving in buffers, returns an AsyncIterableIterator.
|
|
2220
|
+
* @param {Iterable|Iterator|AsyncIterable|AsyncIterableIterator} bufferIterator
|
|
2221
|
+
* @param {object} [options] - Decoder options
|
|
2222
|
+
* @returns {IterableIterator|Promise.<AsyncIterableIterator}
|
|
2223
|
+
*/
|
|
2224
|
+
function decodeIter (bufferIterator, options = {}) {
|
|
2225
|
+
if (!bufferIterator || typeof bufferIterator !== 'object') {
|
|
2226
|
+
throw new Error('first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a promise')
|
|
2227
|
+
}
|
|
2228
|
+
|
|
2229
|
+
const decoder = new Decoder(options);
|
|
2230
|
+
let incomplete;
|
|
2231
|
+
const parser = (chunk) => {
|
|
2232
|
+
let yields;
|
|
2233
|
+
// if there's incomplete data from previous chunk, concatinate and try again
|
|
2234
|
+
if (incomplete) {
|
|
2235
|
+
chunk = Buffer.concat([incomplete, chunk]);
|
|
2236
|
+
incomplete = undefined;
|
|
2237
|
+
}
|
|
2238
|
+
|
|
2239
|
+
try {
|
|
2240
|
+
yields = decoder.decodeMultiple(chunk);
|
|
2241
|
+
} catch (err) {
|
|
2242
|
+
if (err.incomplete) {
|
|
2243
|
+
incomplete = chunk.slice(err.lastPosition);
|
|
2244
|
+
yields = err.values;
|
|
2245
|
+
} else {
|
|
2246
|
+
throw err
|
|
2247
|
+
}
|
|
2248
|
+
}
|
|
2249
|
+
return yields
|
|
2250
|
+
};
|
|
2251
|
+
|
|
2252
|
+
if (typeof bufferIterator[Symbol.iterator] === 'function') {
|
|
2253
|
+
return (function * iter () {
|
|
2254
|
+
for (const value of bufferIterator) {
|
|
2255
|
+
yield * parser(value);
|
|
2256
|
+
}
|
|
2257
|
+
})()
|
|
2258
|
+
} else if (typeof bufferIterator[Symbol.asyncIterator] === 'function') {
|
|
2259
|
+
return (async function * iter () {
|
|
2260
|
+
for await (const value of bufferIterator) {
|
|
2261
|
+
yield * parser(value);
|
|
2262
|
+
}
|
|
2263
|
+
})()
|
|
2264
|
+
}
|
|
2265
|
+
}
|
|
2266
|
+
|
|
2267
|
+
const useRecords = false;
|
|
2268
|
+
const mapsAsObjects = true;
|
|
2269
|
+
|
|
2270
|
+
const nativeAccelerationDisabled = process.env.CBOR_NATIVE_ACCELERATION_DISABLED !== undefined && process.env.CBOR_NATIVE_ACCELERATION_DISABLED.toLowerCase() === 'true';
|
|
2271
|
+
|
|
2272
|
+
if (!nativeAccelerationDisabled) {
|
|
2273
|
+
let extractor;
|
|
2274
|
+
try {
|
|
2275
|
+
if (typeof require == 'function')
|
|
2276
|
+
extractor = require('cbor-extract');
|
|
2277
|
+
else
|
|
2278
|
+
extractor = module$1.createRequire((typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('node.cjs', document.baseURI).href)))('cbor-extract');
|
|
2279
|
+
if (extractor)
|
|
2280
|
+
setExtractor(extractor.extractStrings);
|
|
2281
|
+
} catch (error) {
|
|
2282
|
+
// native module is optional
|
|
2283
|
+
}
|
|
2274
2284
|
}
|
|
2275
2285
|
|
|
2276
2286
|
exports.ALWAYS = ALWAYS;
|