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