msgpackr 1.11.12 → 2.0.1
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/README.md +16 -0
- package/dist/index-no-eval.cjs +242 -230
- package/dist/index-no-eval.cjs.map +1 -1
- package/dist/index-no-eval.min.js +1 -1
- package/dist/index-no-eval.min.js.map +1 -1
- package/dist/index.js +242 -230
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/node.cjs +264 -1048
- package/dist/node.cjs.map +1 -1
- package/dist/test.js +278 -1121
- package/dist/test.js.map +1 -1
- package/dist/unpack-no-eval.cjs +176 -179
- package/dist/unpack-no-eval.cjs.map +1 -1
- package/index.js +5 -5
- package/iterators.js +28 -28
- package/node-index.js +12 -13
- package/pack.js +607 -606
- package/package.json +1 -1
- package/stream.js +31 -31
- package/unpack.js +626 -628
- package/struct.js +0 -815
package/pack.js
CHANGED
|
@@ -1,139 +1,138 @@
|
|
|
1
|
-
import { Unpackr, mult10, C1Type, typedArrays, addExtension as unpackAddExtension } from './unpack.js'
|
|
2
|
-
let textEncoder
|
|
1
|
+
import { Unpackr, mult10, C1Type, typedArrays, addExtension as unpackAddExtension } from './unpack.js';
|
|
2
|
+
let textEncoder;
|
|
3
3
|
try {
|
|
4
|
-
textEncoder = new TextEncoder()
|
|
4
|
+
textEncoder = new TextEncoder();
|
|
5
5
|
} catch (error) {}
|
|
6
|
-
let extensions, extensionClasses
|
|
7
|
-
const hasNodeBuffer = typeof Buffer !== 'undefined'
|
|
6
|
+
let extensions, extensionClasses;
|
|
7
|
+
const hasNodeBuffer = typeof Buffer !== 'undefined';
|
|
8
8
|
const ByteArrayAllocate = hasNodeBuffer ?
|
|
9
|
-
function(length) { return Buffer.allocUnsafeSlow(length) } : Uint8Array
|
|
10
|
-
const ByteArray = hasNodeBuffer ? Buffer : Uint8Array
|
|
11
|
-
const MAX_BUFFER_SIZE = hasNodeBuffer ? 0x100000000 : 0x7fd00000
|
|
12
|
-
let target, keysTarget
|
|
13
|
-
let targetView
|
|
14
|
-
let position = 0
|
|
15
|
-
let safeEnd
|
|
16
|
-
let bundledStrings = null
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
export const RECORD_SYMBOL = Symbol('record-id')
|
|
9
|
+
function(length) { return Buffer.allocUnsafeSlow(length); } : Uint8Array;
|
|
10
|
+
const ByteArray = hasNodeBuffer ? Buffer : Uint8Array;
|
|
11
|
+
const MAX_BUFFER_SIZE = hasNodeBuffer ? 0x100000000 : 0x7fd00000;
|
|
12
|
+
let target, keysTarget;
|
|
13
|
+
let targetView;
|
|
14
|
+
let position = 0;
|
|
15
|
+
let safeEnd;
|
|
16
|
+
let bundledStrings = null;
|
|
17
|
+
const MAX_BUNDLE_SIZE = 0x5500; // maximum characters such that the encoded bytes fits in 16 bits.
|
|
18
|
+
const hasNonLatin = /[\u0080-\uFFFF]/;
|
|
19
|
+
export const RECORD_SYMBOL = Symbol('record-id');
|
|
21
20
|
export class Packr extends Unpackr {
|
|
22
21
|
constructor(options) {
|
|
23
|
-
super(options)
|
|
24
|
-
this.offset = 0
|
|
25
|
-
let typeBuffer
|
|
26
|
-
let start
|
|
27
|
-
let hasSharedUpdate
|
|
28
|
-
let structures
|
|
29
|
-
let referenceMap
|
|
22
|
+
super(options);
|
|
23
|
+
this.offset = 0;
|
|
24
|
+
let typeBuffer;
|
|
25
|
+
let start;
|
|
26
|
+
let hasSharedUpdate;
|
|
27
|
+
let structures;
|
|
28
|
+
let referenceMap;
|
|
30
29
|
let encodeUtf8 = ByteArray.prototype.utf8Write ? function(string, position) {
|
|
31
|
-
return target.utf8Write(string, position, target.byteLength - position)
|
|
30
|
+
return target.utf8Write(string, position, target.byteLength - position);
|
|
32
31
|
} : (textEncoder && textEncoder.encodeInto) ?
|
|
33
32
|
function(string, position) {
|
|
34
|
-
return textEncoder.encodeInto(string, target.subarray(position)).written
|
|
35
|
-
} : false
|
|
33
|
+
return textEncoder.encodeInto(string, target.subarray(position)).written;
|
|
34
|
+
} : false;
|
|
36
35
|
|
|
37
|
-
let packr = this
|
|
36
|
+
let packr = this;
|
|
38
37
|
if (!options)
|
|
39
|
-
options = {}
|
|
40
|
-
let isSequential = options && options.sequential
|
|
41
|
-
let hasSharedStructures = options.structures || options.saveStructures
|
|
42
|
-
let maxSharedStructures = options.maxSharedStructures
|
|
38
|
+
options = {};
|
|
39
|
+
let isSequential = options && options.sequential;
|
|
40
|
+
let hasSharedStructures = options.structures || options.saveStructures;
|
|
41
|
+
let maxSharedStructures = options.maxSharedStructures;
|
|
43
42
|
if (maxSharedStructures == null)
|
|
44
|
-
maxSharedStructures = hasSharedStructures ? 32 : 0
|
|
43
|
+
maxSharedStructures = hasSharedStructures ? 32 : 0;
|
|
45
44
|
if (maxSharedStructures > 8160)
|
|
46
|
-
throw new Error('Maximum maxSharedStructure is 8160')
|
|
45
|
+
throw new Error('Maximum maxSharedStructure is 8160');
|
|
47
46
|
if (options.structuredClone && options.moreTypes == undefined) {
|
|
48
|
-
this.moreTypes = true
|
|
47
|
+
this.moreTypes = true;
|
|
49
48
|
}
|
|
50
|
-
let maxOwnStructures = options.maxOwnStructures
|
|
49
|
+
let maxOwnStructures = options.maxOwnStructures;
|
|
51
50
|
if (maxOwnStructures == null)
|
|
52
|
-
maxOwnStructures = hasSharedStructures ? 32 : 64
|
|
51
|
+
maxOwnStructures = hasSharedStructures ? 32 : 64;
|
|
53
52
|
if (!this.structures && options.useRecords != false)
|
|
54
|
-
this.structures = []
|
|
53
|
+
this.structures = [];
|
|
55
54
|
// two byte record ids for shared structures
|
|
56
|
-
let useTwoByteRecords = maxSharedStructures > 32 || (maxOwnStructures + maxSharedStructures > 64)
|
|
57
|
-
let sharedLimitId = maxSharedStructures + 0x40
|
|
58
|
-
let maxStructureId = maxSharedStructures + maxOwnStructures + 0x40
|
|
55
|
+
let useTwoByteRecords = maxSharedStructures > 32 || (maxOwnStructures + maxSharedStructures > 64);
|
|
56
|
+
let sharedLimitId = maxSharedStructures + 0x40;
|
|
57
|
+
let maxStructureId = maxSharedStructures + maxOwnStructures + 0x40;
|
|
59
58
|
if (maxStructureId > 8256) {
|
|
60
|
-
throw new Error('Maximum maxSharedStructure + maxOwnStructure is 8192')
|
|
59
|
+
throw new Error('Maximum maxSharedStructure + maxOwnStructure is 8192');
|
|
61
60
|
}
|
|
62
|
-
let recordIdsToRemove = []
|
|
63
|
-
let transitionsCount = 0
|
|
64
|
-
let serializationsSinceTransitionRebuild = 0
|
|
61
|
+
let recordIdsToRemove = [];
|
|
62
|
+
let transitionsCount = 0;
|
|
63
|
+
let serializationsSinceTransitionRebuild = 0;
|
|
65
64
|
|
|
66
65
|
this.pack = this.encode = function(value, encodeOptions) {
|
|
67
66
|
if (!target) {
|
|
68
|
-
target = new ByteArrayAllocate(8192)
|
|
69
|
-
targetView = target.dataView || (target.dataView = new DataView(target.buffer, 0, 8192))
|
|
70
|
-
position = 0
|
|
67
|
+
target = new ByteArrayAllocate(8192);
|
|
68
|
+
targetView = target.dataView || (target.dataView = new DataView(target.buffer, 0, 8192));
|
|
69
|
+
position = 0;
|
|
71
70
|
}
|
|
72
|
-
safeEnd = target.length - 10
|
|
71
|
+
safeEnd = target.length - 10;
|
|
73
72
|
if (safeEnd - position < 0x800) {
|
|
74
73
|
// don't start too close to the end,
|
|
75
|
-
target = new ByteArrayAllocate(target.length)
|
|
76
|
-
targetView = target.dataView || (target.dataView = new DataView(target.buffer, 0, target.length))
|
|
77
|
-
safeEnd = target.length - 10
|
|
78
|
-
position = 0
|
|
74
|
+
target = new ByteArrayAllocate(target.length);
|
|
75
|
+
targetView = target.dataView || (target.dataView = new DataView(target.buffer, 0, target.length));
|
|
76
|
+
safeEnd = target.length - 10;
|
|
77
|
+
position = 0;
|
|
79
78
|
} else
|
|
80
|
-
position = (position + 7) & 0x7ffffff8 // Word align to make any future copying of this buffer faster
|
|
81
|
-
start = position
|
|
82
|
-
if (encodeOptions & RESERVE_START_SPACE) position += (encodeOptions & 0xff)
|
|
83
|
-
referenceMap = packr.structuredClone ? new Map() : null
|
|
79
|
+
position = (position + 7) & 0x7ffffff8; // Word align to make any future copying of this buffer faster
|
|
80
|
+
start = position;
|
|
81
|
+
if (encodeOptions & RESERVE_START_SPACE) position += (encodeOptions & 0xff);
|
|
82
|
+
referenceMap = packr.structuredClone ? new Map() : null;
|
|
84
83
|
if (packr.bundleStrings && typeof value !== 'string') {
|
|
85
|
-
bundledStrings = []
|
|
86
|
-
bundledStrings.size = Infinity // force a new bundle start on first string
|
|
84
|
+
bundledStrings = [];
|
|
85
|
+
bundledStrings.size = Infinity; // force a new bundle start on first string
|
|
87
86
|
} else
|
|
88
|
-
bundledStrings = null
|
|
89
|
-
structures = packr.structures
|
|
87
|
+
bundledStrings = null;
|
|
88
|
+
structures = packr.structures;
|
|
90
89
|
if (structures) {
|
|
91
90
|
if (structures.uninitialized)
|
|
92
|
-
structures = packr._mergeStructures(packr.getStructures())
|
|
93
|
-
let sharedLength = structures.sharedLength || 0
|
|
91
|
+
structures = packr._mergeStructures(packr.getStructures());
|
|
92
|
+
let sharedLength = structures.sharedLength || 0;
|
|
94
93
|
if (sharedLength > maxSharedStructures) {
|
|
95
94
|
//if (maxSharedStructures <= 32 && structures.sharedLength > 32) // TODO: could support this, but would need to update the limit ids
|
|
96
|
-
throw new Error('Shared structures is larger than maximum shared structures, try increasing maxSharedStructures to ' + structures.sharedLength)
|
|
95
|
+
throw new Error('Shared structures is larger than maximum shared structures, try increasing maxSharedStructures to ' + structures.sharedLength);
|
|
97
96
|
}
|
|
98
97
|
if (!structures.transitions) {
|
|
99
98
|
// rebuild our structure transitions
|
|
100
|
-
structures.transitions = Object.create(null)
|
|
99
|
+
structures.transitions = Object.create(null);
|
|
101
100
|
for (let i = 0; i < sharedLength; i++) {
|
|
102
|
-
let keys = structures[i]
|
|
101
|
+
let keys = structures[i];
|
|
103
102
|
if (!keys)
|
|
104
|
-
continue
|
|
105
|
-
let nextTransition, transition = structures.transitions
|
|
103
|
+
continue;
|
|
104
|
+
let nextTransition, transition = structures.transitions;
|
|
106
105
|
for (let j = 0, l = keys.length; j < l; j++) {
|
|
107
|
-
let key = keys[j]
|
|
108
|
-
nextTransition = transition[key]
|
|
106
|
+
let key = keys[j];
|
|
107
|
+
nextTransition = transition[key];
|
|
109
108
|
if (!nextTransition) {
|
|
110
|
-
nextTransition = transition[key] = Object.create(null)
|
|
109
|
+
nextTransition = transition[key] = Object.create(null);
|
|
111
110
|
}
|
|
112
|
-
transition = nextTransition
|
|
111
|
+
transition = nextTransition;
|
|
113
112
|
}
|
|
114
|
-
transition[RECORD_SYMBOL] = i + 0x40
|
|
113
|
+
transition[RECORD_SYMBOL] = i + 0x40;
|
|
115
114
|
}
|
|
116
|
-
this.lastNamedStructuresLength = sharedLength
|
|
115
|
+
this.lastNamedStructuresLength = sharedLength;
|
|
117
116
|
}
|
|
118
117
|
if (!isSequential) {
|
|
119
|
-
structures.nextId = sharedLength + 0x40
|
|
118
|
+
structures.nextId = sharedLength + 0x40;
|
|
120
119
|
}
|
|
121
120
|
}
|
|
122
121
|
if (hasSharedUpdate)
|
|
123
|
-
hasSharedUpdate = false
|
|
122
|
+
hasSharedUpdate = false;
|
|
124
123
|
let encodingError;
|
|
125
124
|
try {
|
|
126
|
-
if (packr.
|
|
125
|
+
if (packr._writeStruct && value && typeof value === 'object') {
|
|
127
126
|
if (value.constructor === Object) writeStruct(value); // simple object
|
|
128
127
|
else if (value.constructor !== Map && !Array.isArray(value) && !extensionClasses.some(extClass => value instanceof extClass)) {
|
|
129
128
|
// allow user classes, if they don't need special handling (but do use toJSON if available)
|
|
130
129
|
writeStruct(value.toJSON ? value.toJSON() : value);
|
|
131
|
-
} else pack(value)
|
|
130
|
+
} else pack(value);
|
|
132
131
|
} else
|
|
133
|
-
pack(value)
|
|
132
|
+
pack(value);
|
|
134
133
|
let lastBundle = bundledStrings;
|
|
135
134
|
if (bundledStrings)
|
|
136
|
-
writeBundles(start, pack, 0)
|
|
135
|
+
writeBundles(start, pack, 0);
|
|
137
136
|
if (referenceMap && referenceMap.idsToInsert) {
|
|
138
137
|
let idsToInsert = referenceMap.idsToInsert.sort((a, b) => a.offset > b.offset ? 1 : -1);
|
|
139
138
|
let i = idsToInsert.length;
|
|
@@ -149,7 +148,7 @@ export class Packr extends Unpackr {
|
|
|
149
148
|
if (incrementPosition >= 0) {
|
|
150
149
|
// update the bundle reference now
|
|
151
150
|
targetView.setUint32(lastBundle.position + start,
|
|
152
|
-
targetView.getUint32(lastBundle.position + start) + incrementPosition)
|
|
151
|
+
targetView.getUint32(lastBundle.position + start) + incrementPosition);
|
|
153
152
|
incrementPosition = -1; // reset
|
|
154
153
|
}
|
|
155
154
|
lastBundle = lastBundle.previous;
|
|
@@ -159,23 +158,23 @@ export class Packr extends Unpackr {
|
|
|
159
158
|
if (incrementPosition >= 0 && lastBundle) {
|
|
160
159
|
// update the bundle reference now
|
|
161
160
|
targetView.setUint32(lastBundle.position + start,
|
|
162
|
-
targetView.getUint32(lastBundle.position + start) + incrementPosition)
|
|
161
|
+
targetView.getUint32(lastBundle.position + start) + incrementPosition);
|
|
163
162
|
}
|
|
164
163
|
position += idsToInsert.length * 6;
|
|
165
164
|
if (position > safeEnd)
|
|
166
|
-
makeRoom(position)
|
|
167
|
-
packr.offset = position
|
|
168
|
-
let serialized = insertIds(target.subarray(start, position), idsToInsert)
|
|
169
|
-
referenceMap = null
|
|
170
|
-
return serialized
|
|
165
|
+
makeRoom(position);
|
|
166
|
+
packr.offset = position;
|
|
167
|
+
let serialized = insertIds(target.subarray(start, position), idsToInsert);
|
|
168
|
+
referenceMap = null;
|
|
169
|
+
return serialized;
|
|
171
170
|
}
|
|
172
|
-
packr.offset = position // update the offset so next serialization doesn't write over our buffer, but can continue writing to same buffer sequentially
|
|
171
|
+
packr.offset = position; // update the offset so next serialization doesn't write over our buffer, but can continue writing to same buffer sequentially
|
|
173
172
|
if (encodeOptions & REUSE_BUFFER_MODE) {
|
|
174
|
-
target.start = start
|
|
175
|
-
target.end = position
|
|
176
|
-
return target
|
|
173
|
+
target.start = start;
|
|
174
|
+
target.end = position;
|
|
175
|
+
return target;
|
|
177
176
|
}
|
|
178
|
-
return target.subarray(start, position) // position can change if we call pack again in saveStructures, so we get the buffer now
|
|
177
|
+
return target.subarray(start, position); // position can change if we call pack again in saveStructures, so we get the buffer now
|
|
179
178
|
} catch(error) {
|
|
180
179
|
encodingError = error;
|
|
181
180
|
throw error;
|
|
@@ -183,336 +182,336 @@ export class Packr extends Unpackr {
|
|
|
183
182
|
if (structures) {
|
|
184
183
|
resetStructures();
|
|
185
184
|
if (hasSharedUpdate && packr.saveStructures) {
|
|
186
|
-
let sharedLength = structures.sharedLength || 0
|
|
185
|
+
let sharedLength = structures.sharedLength || 0;
|
|
187
186
|
// we can't rely on start/end with REUSE_BUFFER_MODE since they will (probably) change when we save
|
|
188
|
-
let returnBuffer = target.subarray(start, position)
|
|
189
|
-
let newSharedData = prepareStructures(structures, packr);
|
|
187
|
+
let returnBuffer = target.subarray(start, position);
|
|
188
|
+
let newSharedData = (packr._prepareStructures || prepareStructures)(structures, packr);
|
|
190
189
|
if (!encodingError) { // TODO: If there is an encoding error, should make the structures as uninitialized so they get rebuilt next time
|
|
191
190
|
if (packr.saveStructures(newSharedData, newSharedData.isCompatible) === false) {
|
|
192
191
|
// get updated structures and try again if the update failed
|
|
193
|
-
return packr.pack(value, encodeOptions)
|
|
192
|
+
return packr.pack(value, encodeOptions);
|
|
194
193
|
}
|
|
195
|
-
packr.lastNamedStructuresLength = sharedLength
|
|
194
|
+
packr.lastNamedStructuresLength = sharedLength;
|
|
196
195
|
// don't keep large buffers around
|
|
197
|
-
if (target.length > 0x40000000) target = null
|
|
198
|
-
return returnBuffer
|
|
196
|
+
if (target.length > 0x40000000) target = null;
|
|
197
|
+
return returnBuffer;
|
|
199
198
|
}
|
|
200
199
|
}
|
|
201
200
|
}
|
|
202
201
|
// don't keep large buffers around, they take too much memory and cause problems (limit at 1GB)
|
|
203
|
-
if (target.length > 0x40000000) target = null
|
|
202
|
+
if (target.length > 0x40000000) target = null;
|
|
204
203
|
if (encodeOptions & RESET_BUFFER_MODE)
|
|
205
|
-
position = start
|
|
204
|
+
position = start;
|
|
206
205
|
}
|
|
207
|
-
}
|
|
206
|
+
};
|
|
208
207
|
const resetStructures = () => {
|
|
209
208
|
if (serializationsSinceTransitionRebuild < 10)
|
|
210
|
-
serializationsSinceTransitionRebuild
|
|
211
|
-
let sharedLength = structures.sharedLength || 0
|
|
209
|
+
serializationsSinceTransitionRebuild++;
|
|
210
|
+
let sharedLength = structures.sharedLength || 0;
|
|
212
211
|
if (structures.length > sharedLength && !isSequential)
|
|
213
|
-
structures.length = sharedLength
|
|
212
|
+
structures.length = sharedLength;
|
|
214
213
|
if (transitionsCount > 10000) {
|
|
215
214
|
// force a rebuild occasionally after a lot of transitions so it can get cleaned up
|
|
216
|
-
structures.transitions = null
|
|
217
|
-
serializationsSinceTransitionRebuild = 0
|
|
218
|
-
transitionsCount = 0
|
|
215
|
+
structures.transitions = null;
|
|
216
|
+
serializationsSinceTransitionRebuild = 0;
|
|
217
|
+
transitionsCount = 0;
|
|
219
218
|
if (recordIdsToRemove.length > 0)
|
|
220
|
-
recordIdsToRemove = []
|
|
219
|
+
recordIdsToRemove = [];
|
|
221
220
|
} else if (recordIdsToRemove.length > 0 && !isSequential) {
|
|
222
221
|
for (let i = 0, l = recordIdsToRemove.length; i < l; i++) {
|
|
223
|
-
recordIdsToRemove[i][RECORD_SYMBOL] = 0
|
|
222
|
+
recordIdsToRemove[i][RECORD_SYMBOL] = 0;
|
|
224
223
|
}
|
|
225
|
-
recordIdsToRemove = []
|
|
224
|
+
recordIdsToRemove = [];
|
|
226
225
|
}
|
|
227
|
-
}
|
|
226
|
+
};
|
|
228
227
|
const packArray = (value) => {
|
|
229
|
-
var length = value.length
|
|
228
|
+
var length = value.length;
|
|
230
229
|
if (length < 0x10) {
|
|
231
|
-
target[position++] = 0x90 | length
|
|
230
|
+
target[position++] = 0x90 | length;
|
|
232
231
|
} else if (length < 0x10000) {
|
|
233
|
-
target[position++] = 0xdc
|
|
234
|
-
target[position++] = length >> 8
|
|
235
|
-
target[position++] = length & 0xff
|
|
232
|
+
target[position++] = 0xdc;
|
|
233
|
+
target[position++] = length >> 8;
|
|
234
|
+
target[position++] = length & 0xff;
|
|
236
235
|
} else {
|
|
237
|
-
target[position++] = 0xdd
|
|
238
|
-
targetView.setUint32(position, length)
|
|
239
|
-
position += 4
|
|
236
|
+
target[position++] = 0xdd;
|
|
237
|
+
targetView.setUint32(position, length);
|
|
238
|
+
position += 4;
|
|
240
239
|
}
|
|
241
240
|
for (let i = 0; i < length; i++) {
|
|
242
|
-
pack(value[i])
|
|
241
|
+
pack(value[i]);
|
|
243
242
|
}
|
|
244
|
-
}
|
|
243
|
+
};
|
|
245
244
|
const pack = (value) => {
|
|
246
245
|
if (position > safeEnd)
|
|
247
|
-
target = makeRoom(position)
|
|
246
|
+
target = makeRoom(position);
|
|
248
247
|
|
|
249
|
-
var type = typeof value
|
|
250
|
-
var length
|
|
248
|
+
var type = typeof value;
|
|
249
|
+
var length;
|
|
251
250
|
if (type === 'string') {
|
|
252
|
-
let strLength = value.length
|
|
251
|
+
let strLength = value.length;
|
|
253
252
|
if (bundledStrings && strLength >= 4 && strLength < 0x1000) {
|
|
254
253
|
if ((bundledStrings.size += strLength) > MAX_BUNDLE_SIZE) {
|
|
255
|
-
let extStart
|
|
256
|
-
let maxBytes = (bundledStrings[0] ? bundledStrings[0].length * 3 + bundledStrings[1].length : 0) + 10
|
|
254
|
+
let extStart;
|
|
255
|
+
let maxBytes = (bundledStrings[0] ? bundledStrings[0].length * 3 + bundledStrings[1].length : 0) + 10;
|
|
257
256
|
if (position + maxBytes > safeEnd)
|
|
258
|
-
target = makeRoom(position + maxBytes)
|
|
259
|
-
let lastBundle
|
|
257
|
+
target = makeRoom(position + maxBytes);
|
|
258
|
+
let lastBundle;
|
|
260
259
|
if (bundledStrings.position) { // here we use the 0x62 extension to write the last bundle and reserve space for the reference pointer to the next/current bundle
|
|
261
|
-
lastBundle = bundledStrings
|
|
262
|
-
target[position] = 0xc8 // ext 16
|
|
263
|
-
position += 3 // reserve for the writing bundle size
|
|
264
|
-
target[position++] = 0x62 // 'b'
|
|
265
|
-
extStart = position - start
|
|
266
|
-
position += 4 // reserve for writing bundle reference
|
|
267
|
-
writeBundles(start, pack, 0) // write the last bundles
|
|
268
|
-
targetView.setUint16(extStart + start - 3, position - start - extStart)
|
|
260
|
+
lastBundle = bundledStrings;
|
|
261
|
+
target[position] = 0xc8; // ext 16
|
|
262
|
+
position += 3; // reserve for the writing bundle size
|
|
263
|
+
target[position++] = 0x62; // 'b'
|
|
264
|
+
extStart = position - start;
|
|
265
|
+
position += 4; // reserve for writing bundle reference
|
|
266
|
+
writeBundles(start, pack, 0); // write the last bundles
|
|
267
|
+
targetView.setUint16(extStart + start - 3, position - start - extStart);
|
|
269
268
|
} else { // here we use the 0x62 extension just to reserve the space for the reference pointer to the bundle (will be updated once the bundle is written)
|
|
270
|
-
target[position++] = 0xd6 // fixext 4
|
|
271
|
-
target[position++] = 0x62 // 'b'
|
|
272
|
-
extStart = position - start
|
|
273
|
-
position += 4 // reserve for writing bundle reference
|
|
269
|
+
target[position++] = 0xd6; // fixext 4
|
|
270
|
+
target[position++] = 0x62; // 'b'
|
|
271
|
+
extStart = position - start;
|
|
272
|
+
position += 4; // reserve for writing bundle reference
|
|
274
273
|
}
|
|
275
|
-
bundledStrings = ['', ''] // create new ones
|
|
274
|
+
bundledStrings = ['', '']; // create new ones
|
|
276
275
|
bundledStrings.previous = lastBundle;
|
|
277
|
-
bundledStrings.size = 0
|
|
278
|
-
bundledStrings.position = extStart
|
|
276
|
+
bundledStrings.size = 0;
|
|
277
|
+
bundledStrings.position = extStart;
|
|
279
278
|
}
|
|
280
|
-
let twoByte = hasNonLatin.test(value)
|
|
281
|
-
bundledStrings[twoByte ? 0 : 1] += value
|
|
282
|
-
target[position++] = 0xc1
|
|
279
|
+
let twoByte = hasNonLatin.test(value);
|
|
280
|
+
bundledStrings[twoByte ? 0 : 1] += value;
|
|
281
|
+
target[position++] = 0xc1;
|
|
283
282
|
pack(twoByte ? -strLength : strLength);
|
|
284
|
-
return
|
|
283
|
+
return;
|
|
285
284
|
}
|
|
286
|
-
let headerSize
|
|
285
|
+
let headerSize;
|
|
287
286
|
// first we estimate the header size, so we can write to the correct location
|
|
288
287
|
if (strLength < 0x20) {
|
|
289
|
-
headerSize = 1
|
|
288
|
+
headerSize = 1;
|
|
290
289
|
} else if (strLength < 0x100) {
|
|
291
|
-
headerSize = 2
|
|
290
|
+
headerSize = 2;
|
|
292
291
|
} else if (strLength < 0x10000) {
|
|
293
|
-
headerSize = 3
|
|
292
|
+
headerSize = 3;
|
|
294
293
|
} else {
|
|
295
|
-
headerSize = 5
|
|
294
|
+
headerSize = 5;
|
|
296
295
|
}
|
|
297
|
-
let maxBytes = strLength * 3
|
|
296
|
+
let maxBytes = strLength * 3;
|
|
298
297
|
if (position + maxBytes > safeEnd)
|
|
299
|
-
target = makeRoom(position + maxBytes)
|
|
298
|
+
target = makeRoom(position + maxBytes);
|
|
300
299
|
|
|
301
300
|
if (strLength < 0x40 || !encodeUtf8) {
|
|
302
|
-
let i, c1, c2, strPosition = position + headerSize
|
|
301
|
+
let i, c1, c2, strPosition = position + headerSize;
|
|
303
302
|
for (i = 0; i < strLength; i++) {
|
|
304
|
-
c1 = value.charCodeAt(i)
|
|
303
|
+
c1 = value.charCodeAt(i);
|
|
305
304
|
if (c1 < 0x80) {
|
|
306
|
-
target[strPosition++] = c1
|
|
305
|
+
target[strPosition++] = c1;
|
|
307
306
|
} else if (c1 < 0x800) {
|
|
308
|
-
target[strPosition++] = c1 >> 6 | 0xc0
|
|
309
|
-
target[strPosition++] = c1 & 0x3f | 0x80
|
|
307
|
+
target[strPosition++] = c1 >> 6 | 0xc0;
|
|
308
|
+
target[strPosition++] = c1 & 0x3f | 0x80;
|
|
310
309
|
} else if (
|
|
311
310
|
(c1 & 0xfc00) === 0xd800 &&
|
|
312
311
|
((c2 = value.charCodeAt(i + 1)) & 0xfc00) === 0xdc00
|
|
313
312
|
) {
|
|
314
|
-
c1 = 0x10000 + ((c1 & 0x03ff) << 10) + (c2 & 0x03ff)
|
|
315
|
-
i
|
|
316
|
-
target[strPosition++] = c1 >> 18 | 0xf0
|
|
317
|
-
target[strPosition++] = c1 >> 12 & 0x3f | 0x80
|
|
318
|
-
target[strPosition++] = c1 >> 6 & 0x3f | 0x80
|
|
319
|
-
target[strPosition++] = c1 & 0x3f | 0x80
|
|
313
|
+
c1 = 0x10000 + ((c1 & 0x03ff) << 10) + (c2 & 0x03ff);
|
|
314
|
+
i++;
|
|
315
|
+
target[strPosition++] = c1 >> 18 | 0xf0;
|
|
316
|
+
target[strPosition++] = c1 >> 12 & 0x3f | 0x80;
|
|
317
|
+
target[strPosition++] = c1 >> 6 & 0x3f | 0x80;
|
|
318
|
+
target[strPosition++] = c1 & 0x3f | 0x80;
|
|
320
319
|
} else {
|
|
321
|
-
target[strPosition++] = c1 >> 12 | 0xe0
|
|
322
|
-
target[strPosition++] = c1 >> 6 & 0x3f | 0x80
|
|
323
|
-
target[strPosition++] = c1 & 0x3f | 0x80
|
|
320
|
+
target[strPosition++] = c1 >> 12 | 0xe0;
|
|
321
|
+
target[strPosition++] = c1 >> 6 & 0x3f | 0x80;
|
|
322
|
+
target[strPosition++] = c1 & 0x3f | 0x80;
|
|
324
323
|
}
|
|
325
324
|
}
|
|
326
|
-
length = strPosition - position - headerSize
|
|
325
|
+
length = strPosition - position - headerSize;
|
|
327
326
|
} else {
|
|
328
|
-
length = encodeUtf8(value, position + headerSize)
|
|
327
|
+
length = encodeUtf8(value, position + headerSize);
|
|
329
328
|
}
|
|
330
329
|
|
|
331
330
|
if (length < 0x20) {
|
|
332
|
-
target[position++] = 0xa0 | length
|
|
331
|
+
target[position++] = 0xa0 | length;
|
|
333
332
|
} else if (length < 0x100) {
|
|
334
333
|
if (headerSize < 2) {
|
|
335
|
-
target.copyWithin(position + 2, position + 1, position + 1 + length)
|
|
334
|
+
target.copyWithin(position + 2, position + 1, position + 1 + length);
|
|
336
335
|
}
|
|
337
|
-
target[position++] = 0xd9
|
|
338
|
-
target[position++] = length
|
|
336
|
+
target[position++] = 0xd9;
|
|
337
|
+
target[position++] = length;
|
|
339
338
|
} else if (length < 0x10000) {
|
|
340
339
|
if (headerSize < 3) {
|
|
341
|
-
target.copyWithin(position + 3, position + 2, position + 2 + length)
|
|
340
|
+
target.copyWithin(position + 3, position + 2, position + 2 + length);
|
|
342
341
|
}
|
|
343
|
-
target[position++] = 0xda
|
|
344
|
-
target[position++] = length >> 8
|
|
345
|
-
target[position++] = length & 0xff
|
|
342
|
+
target[position++] = 0xda;
|
|
343
|
+
target[position++] = length >> 8;
|
|
344
|
+
target[position++] = length & 0xff;
|
|
346
345
|
} else {
|
|
347
346
|
if (headerSize < 5) {
|
|
348
|
-
target.copyWithin(position + 5, position + 3, position + 3 + length)
|
|
347
|
+
target.copyWithin(position + 5, position + 3, position + 3 + length);
|
|
349
348
|
}
|
|
350
|
-
target[position++] = 0xdb
|
|
351
|
-
targetView.setUint32(position, length)
|
|
352
|
-
position += 4
|
|
349
|
+
target[position++] = 0xdb;
|
|
350
|
+
targetView.setUint32(position, length);
|
|
351
|
+
position += 4;
|
|
353
352
|
}
|
|
354
|
-
position += length
|
|
353
|
+
position += length;
|
|
355
354
|
} else if (type === 'number') {
|
|
356
355
|
if (value >>> 0 === value) {// positive integer, 32-bit or less
|
|
357
356
|
// positive uint
|
|
358
|
-
if (value < 0x20 || (value < 0x80 && this.useRecords === false) || (value < 0x40 && !this.
|
|
359
|
-
target[position++] = value
|
|
357
|
+
if (value < 0x20 || (value < 0x80 && this.useRecords === false) || (value < 0x40 && !this._writeStruct)) {
|
|
358
|
+
target[position++] = value;
|
|
360
359
|
} else if (value < 0x100) {
|
|
361
|
-
target[position++] = 0xcc
|
|
362
|
-
target[position++] = value
|
|
360
|
+
target[position++] = 0xcc;
|
|
361
|
+
target[position++] = value;
|
|
363
362
|
} else if (value < 0x10000) {
|
|
364
|
-
target[position++] = 0xcd
|
|
365
|
-
target[position++] = value >> 8
|
|
366
|
-
target[position++] = value & 0xff
|
|
363
|
+
target[position++] = 0xcd;
|
|
364
|
+
target[position++] = value >> 8;
|
|
365
|
+
target[position++] = value & 0xff;
|
|
367
366
|
} else {
|
|
368
|
-
target[position++] = 0xce
|
|
369
|
-
targetView.setUint32(position, value)
|
|
370
|
-
position += 4
|
|
367
|
+
target[position++] = 0xce;
|
|
368
|
+
targetView.setUint32(position, value);
|
|
369
|
+
position += 4;
|
|
371
370
|
}
|
|
372
371
|
} else if (value >> 0 === value) { // negative integer
|
|
373
372
|
if (value >= -0x20) {
|
|
374
|
-
target[position++] = 0x100 + value
|
|
373
|
+
target[position++] = 0x100 + value;
|
|
375
374
|
} else if (value >= -0x80) {
|
|
376
|
-
target[position++] = 0xd0
|
|
377
|
-
target[position++] = value + 0x100
|
|
375
|
+
target[position++] = 0xd0;
|
|
376
|
+
target[position++] = value + 0x100;
|
|
378
377
|
} else if (value >= -0x8000) {
|
|
379
|
-
target[position++] = 0xd1
|
|
380
|
-
targetView.setInt16(position, value)
|
|
381
|
-
position += 2
|
|
378
|
+
target[position++] = 0xd1;
|
|
379
|
+
targetView.setInt16(position, value);
|
|
380
|
+
position += 2;
|
|
382
381
|
} else {
|
|
383
|
-
target[position++] = 0xd2
|
|
384
|
-
targetView.setInt32(position, value)
|
|
385
|
-
position += 4
|
|
382
|
+
target[position++] = 0xd2;
|
|
383
|
+
targetView.setInt32(position, value);
|
|
384
|
+
position += 4;
|
|
386
385
|
}
|
|
387
386
|
} else {
|
|
388
|
-
let useFloat32
|
|
387
|
+
let useFloat32;
|
|
389
388
|
if ((useFloat32 = this.useFloat32) > 0 && value < 0x100000000 && value >= -0x80000000) {
|
|
390
|
-
target[position++] = 0xca
|
|
391
|
-
targetView.setFloat32(position, value)
|
|
392
|
-
let xShifted
|
|
389
|
+
target[position++] = 0xca;
|
|
390
|
+
targetView.setFloat32(position, value);
|
|
391
|
+
let xShifted;
|
|
393
392
|
if (useFloat32 < 4 ||
|
|
394
393
|
// this checks for rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
|
|
395
394
|
((xShifted = value * mult10[((target[position] & 0x7f) << 1) | (target[position + 1] >> 7)]) >> 0) === xShifted) {
|
|
396
|
-
position += 4
|
|
397
|
-
return
|
|
395
|
+
position += 4;
|
|
396
|
+
return;
|
|
398
397
|
} else
|
|
399
|
-
position
|
|
398
|
+
position--; // move back into position for writing a double
|
|
400
399
|
}
|
|
401
|
-
target[position++] = 0xcb
|
|
402
|
-
targetView.setFloat64(position, value)
|
|
403
|
-
position += 8
|
|
400
|
+
target[position++] = 0xcb;
|
|
401
|
+
targetView.setFloat64(position, value);
|
|
402
|
+
position += 8;
|
|
404
403
|
}
|
|
405
404
|
} else if (type === 'object' || type === 'function') {
|
|
406
405
|
if (!value)
|
|
407
|
-
target[position++] = 0xc0
|
|
406
|
+
target[position++] = 0xc0;
|
|
408
407
|
else {
|
|
409
408
|
if (referenceMap) {
|
|
410
|
-
let referee = referenceMap.get(value)
|
|
409
|
+
let referee = referenceMap.get(value);
|
|
411
410
|
if (referee) {
|
|
412
411
|
if (!referee.id) {
|
|
413
|
-
let idsToInsert = referenceMap.idsToInsert || (referenceMap.idsToInsert = [])
|
|
414
|
-
referee.id = idsToInsert.push(referee)
|
|
412
|
+
let idsToInsert = referenceMap.idsToInsert || (referenceMap.idsToInsert = []);
|
|
413
|
+
referee.id = idsToInsert.push(referee);
|
|
415
414
|
}
|
|
416
|
-
target[position++] = 0xd6 // fixext 4
|
|
417
|
-
target[position++] = 0x70 // "p" for pointer
|
|
418
|
-
targetView.setUint32(position, referee.id)
|
|
419
|
-
position += 4
|
|
420
|
-
return
|
|
415
|
+
target[position++] = 0xd6; // fixext 4
|
|
416
|
+
target[position++] = 0x70; // "p" for pointer
|
|
417
|
+
targetView.setUint32(position, referee.id);
|
|
418
|
+
position += 4;
|
|
419
|
+
return;
|
|
421
420
|
} else
|
|
422
|
-
referenceMap.set(value, { offset: position - start })
|
|
421
|
+
referenceMap.set(value, { offset: position - start });
|
|
423
422
|
}
|
|
424
|
-
let constructor = value.constructor
|
|
423
|
+
let constructor = value.constructor;
|
|
425
424
|
if (constructor === Object) {
|
|
426
|
-
writeObject(value)
|
|
425
|
+
writeObject(value);
|
|
427
426
|
} else if (constructor === Array) {
|
|
428
|
-
packArray(value)
|
|
427
|
+
packArray(value);
|
|
429
428
|
} else if (constructor === Map) {
|
|
430
|
-
if (this.mapAsEmptyObject) target[position++] = 0x80
|
|
429
|
+
if (this.mapAsEmptyObject) target[position++] = 0x80;
|
|
431
430
|
else {
|
|
432
|
-
length = value.size
|
|
431
|
+
length = value.size;
|
|
433
432
|
if (length < 0x10) {
|
|
434
|
-
target[position++] = 0x80 | length
|
|
433
|
+
target[position++] = 0x80 | length;
|
|
435
434
|
} else if (length < 0x10000) {
|
|
436
|
-
target[position++] = 0xde
|
|
437
|
-
target[position++] = length >> 8
|
|
438
|
-
target[position++] = length & 0xff
|
|
435
|
+
target[position++] = 0xde;
|
|
436
|
+
target[position++] = length >> 8;
|
|
437
|
+
target[position++] = length & 0xff;
|
|
439
438
|
} else {
|
|
440
|
-
target[position++] = 0xdf
|
|
441
|
-
targetView.setUint32(position, length)
|
|
442
|
-
position += 4
|
|
439
|
+
target[position++] = 0xdf;
|
|
440
|
+
targetView.setUint32(position, length);
|
|
441
|
+
position += 4;
|
|
443
442
|
}
|
|
444
443
|
for (let [key, entryValue] of value) {
|
|
445
|
-
pack(key)
|
|
446
|
-
pack(entryValue)
|
|
444
|
+
pack(key);
|
|
445
|
+
pack(entryValue);
|
|
447
446
|
}
|
|
448
447
|
}
|
|
449
448
|
} else {
|
|
450
449
|
for (let i = 0, l = extensions.length; i < l; i++) {
|
|
451
|
-
let extensionClass = extensionClasses[i]
|
|
450
|
+
let extensionClass = extensionClasses[i];
|
|
452
451
|
if (value instanceof extensionClass) {
|
|
453
|
-
let extension = extensions[i]
|
|
452
|
+
let extension = extensions[i];
|
|
454
453
|
if (extension.write) {
|
|
455
454
|
if (extension.type) {
|
|
456
|
-
target[position++] = 0xd4 // one byte "tag" extension
|
|
457
|
-
target[position++] = extension.type
|
|
458
|
-
target[position++] = 0
|
|
455
|
+
target[position++] = 0xd4; // one byte "tag" extension
|
|
456
|
+
target[position++] = extension.type;
|
|
457
|
+
target[position++] = 0;
|
|
459
458
|
}
|
|
460
|
-
let writeResult = extension.write.call(this, value)
|
|
459
|
+
let writeResult = extension.write.call(this, value);
|
|
461
460
|
if (writeResult === value) { // avoid infinite recursion
|
|
462
461
|
if (Array.isArray(value)) {
|
|
463
|
-
packArray(value)
|
|
462
|
+
packArray(value);
|
|
464
463
|
} else {
|
|
465
|
-
writeObject(value)
|
|
464
|
+
writeObject(value);
|
|
466
465
|
}
|
|
467
466
|
} else {
|
|
468
|
-
pack(writeResult)
|
|
467
|
+
pack(writeResult);
|
|
469
468
|
}
|
|
470
|
-
return
|
|
469
|
+
return;
|
|
471
470
|
}
|
|
472
|
-
let currentTarget = target
|
|
473
|
-
let currentTargetView = targetView
|
|
474
|
-
let currentPosition = position
|
|
475
|
-
target = null
|
|
476
|
-
let result
|
|
471
|
+
let currentTarget = target;
|
|
472
|
+
let currentTargetView = targetView;
|
|
473
|
+
let currentPosition = position;
|
|
474
|
+
target = null;
|
|
475
|
+
let result;
|
|
477
476
|
try {
|
|
478
477
|
result = extension.pack.call(this, value, (size) => {
|
|
479
478
|
// restore target and use it
|
|
480
|
-
target = currentTarget
|
|
481
|
-
currentTarget = null
|
|
482
|
-
position += size
|
|
479
|
+
target = currentTarget;
|
|
480
|
+
currentTarget = null;
|
|
481
|
+
position += size;
|
|
483
482
|
if (position > safeEnd)
|
|
484
|
-
makeRoom(position)
|
|
483
|
+
makeRoom(position);
|
|
485
484
|
return {
|
|
486
485
|
target, targetView, position: position - size
|
|
487
|
-
}
|
|
488
|
-
}, pack)
|
|
486
|
+
};
|
|
487
|
+
}, pack);
|
|
489
488
|
} finally {
|
|
490
489
|
// restore current target information (unless already restored)
|
|
491
490
|
if (currentTarget) {
|
|
492
|
-
target = currentTarget
|
|
493
|
-
targetView = currentTargetView
|
|
494
|
-
position = currentPosition
|
|
495
|
-
safeEnd = target.length - 10
|
|
491
|
+
target = currentTarget;
|
|
492
|
+
targetView = currentTargetView;
|
|
493
|
+
position = currentPosition;
|
|
494
|
+
safeEnd = target.length - 10;
|
|
496
495
|
}
|
|
497
496
|
}
|
|
498
497
|
if (result) {
|
|
499
498
|
if (result.length + position > safeEnd)
|
|
500
|
-
makeRoom(result.length + position)
|
|
501
|
-
position = writeExtensionData(result, target, position, extension.type)
|
|
499
|
+
makeRoom(result.length + position);
|
|
500
|
+
position = writeExtensionData(result, target, position, extension.type);
|
|
502
501
|
}
|
|
503
|
-
return
|
|
502
|
+
return;
|
|
504
503
|
}
|
|
505
504
|
}
|
|
506
505
|
// check isArray after extensions, because extensions can extend Array
|
|
507
506
|
if (Array.isArray(value)) {
|
|
508
|
-
packArray(value)
|
|
507
|
+
packArray(value);
|
|
509
508
|
} else {
|
|
510
509
|
// use this as an alternate mechanism for expressing how to serialize
|
|
511
510
|
if (value.toJSON) {
|
|
512
|
-
const json = value.toJSON()
|
|
511
|
+
const json = value.toJSON();
|
|
513
512
|
// if for some reason value.toJSON returns itself it'll loop forever
|
|
514
513
|
if (json !== value)
|
|
515
|
-
return pack(json)
|
|
514
|
+
return pack(json);
|
|
516
515
|
}
|
|
517
516
|
|
|
518
517
|
// if there is a writeFunction, use it, otherwise just encode as undefined
|
|
@@ -520,89 +519,89 @@ export class Packr extends Unpackr {
|
|
|
520
519
|
return pack(this.writeFunction && this.writeFunction(value));
|
|
521
520
|
|
|
522
521
|
// no extension found, write as plain object
|
|
523
|
-
writeObject(value)
|
|
522
|
+
writeObject(value);
|
|
524
523
|
}
|
|
525
524
|
}
|
|
526
525
|
}
|
|
527
526
|
} else if (type === 'boolean') {
|
|
528
|
-
target[position++] = value ? 0xc3 : 0xc2
|
|
527
|
+
target[position++] = value ? 0xc3 : 0xc2;
|
|
529
528
|
} else if (type === 'bigint') {
|
|
530
529
|
if (value < 0x8000000000000000 && value >= -0x8000000000000000) {
|
|
531
530
|
// use a signed int as long as it fits
|
|
532
|
-
target[position++] = 0xd3
|
|
533
|
-
targetView.setBigInt64(position, value)
|
|
531
|
+
target[position++] = 0xd3;
|
|
532
|
+
targetView.setBigInt64(position, value);
|
|
534
533
|
} else if (value < 0x10000000000000000 && value > 0) {
|
|
535
534
|
// if we can fit an unsigned int, use that
|
|
536
|
-
target[position++] = 0xcf
|
|
537
|
-
targetView.setBigUint64(position, value)
|
|
535
|
+
target[position++] = 0xcf;
|
|
536
|
+
targetView.setBigUint64(position, value);
|
|
538
537
|
} else {
|
|
539
538
|
// overflow
|
|
540
539
|
if (this.largeBigIntToFloat) {
|
|
541
|
-
target[position++] = 0xcb
|
|
542
|
-
targetView.setFloat64(position, Number(value))
|
|
540
|
+
target[position++] = 0xcb;
|
|
541
|
+
targetView.setFloat64(position, Number(value));
|
|
543
542
|
} else if (this.largeBigIntToString) {
|
|
544
543
|
return pack(value.toString());
|
|
545
544
|
} else if (this.useBigIntExtension || this.moreTypes) {
|
|
546
|
-
let empty = value < 0 ? BigInt(-1) : BigInt(0)
|
|
545
|
+
let empty = value < 0 ? BigInt(-1) : BigInt(0);
|
|
547
546
|
|
|
548
|
-
let array
|
|
547
|
+
let array;
|
|
549
548
|
if (value >> BigInt(0x10000) === empty) {
|
|
550
|
-
let mask = BigInt(0x10000000000000000) - BigInt(1) // literal would overflow
|
|
551
|
-
let chunks = []
|
|
549
|
+
let mask = BigInt(0x10000000000000000) - BigInt(1); // literal would overflow
|
|
550
|
+
let chunks = [];
|
|
552
551
|
while (true) {
|
|
553
|
-
chunks.push(value & mask)
|
|
554
|
-
if ((value >> BigInt(63)) === empty) break
|
|
555
|
-
value >>= BigInt(64)
|
|
552
|
+
chunks.push(value & mask);
|
|
553
|
+
if ((value >> BigInt(63)) === empty) break;
|
|
554
|
+
value >>= BigInt(64);
|
|
556
555
|
}
|
|
557
556
|
|
|
558
|
-
array = new Uint8Array(new BigUint64Array(chunks).buffer)
|
|
559
|
-
array.reverse()
|
|
557
|
+
array = new Uint8Array(new BigUint64Array(chunks).buffer);
|
|
558
|
+
array.reverse();
|
|
560
559
|
} else {
|
|
561
|
-
let invert = value < 0
|
|
562
|
-
let string = (invert ? ~value : value).toString(16)
|
|
560
|
+
let invert = value < 0;
|
|
561
|
+
let string = (invert ? ~value : value).toString(16);
|
|
563
562
|
if (string.length % 2) {
|
|
564
|
-
string = '0' + string
|
|
563
|
+
string = '0' + string;
|
|
565
564
|
} else if (parseInt(string.charAt(0), 16) >= 8) {
|
|
566
|
-
string = '00' + string
|
|
565
|
+
string = '00' + string;
|
|
567
566
|
}
|
|
568
567
|
|
|
569
568
|
if (hasNodeBuffer) {
|
|
570
|
-
array = Buffer.from(string, 'hex')
|
|
569
|
+
array = Buffer.from(string, 'hex');
|
|
571
570
|
} else {
|
|
572
|
-
array = new Uint8Array(string.length / 2)
|
|
571
|
+
array = new Uint8Array(string.length / 2);
|
|
573
572
|
for (let i = 0; i < array.length; i++) {
|
|
574
|
-
array[i] = parseInt(string.slice(i * 2, i * 2 + 2), 16)
|
|
573
|
+
array[i] = parseInt(string.slice(i * 2, i * 2 + 2), 16);
|
|
575
574
|
}
|
|
576
575
|
}
|
|
577
576
|
|
|
578
577
|
if (invert) {
|
|
579
|
-
for (let i = 0; i < array.length; i++) array[i] = ~array[i]
|
|
578
|
+
for (let i = 0; i < array.length; i++) array[i] = ~array[i];
|
|
580
579
|
}
|
|
581
580
|
}
|
|
582
581
|
|
|
583
582
|
if (array.length + position > safeEnd)
|
|
584
|
-
makeRoom(array.length + position)
|
|
585
|
-
position = writeExtensionData(array, target, position, 0x42)
|
|
586
|
-
return
|
|
583
|
+
makeRoom(array.length + position);
|
|
584
|
+
position = writeExtensionData(array, target, position, 0x42);
|
|
585
|
+
return;
|
|
587
586
|
} else {
|
|
588
587
|
throw new RangeError(value + ' was too large to fit in MessagePack 64-bit integer format, use' +
|
|
589
588
|
' useBigIntExtension, or set largeBigIntToFloat to convert to float-64, or set' +
|
|
590
|
-
' largeBigIntToString to convert to string')
|
|
589
|
+
' largeBigIntToString to convert to string');
|
|
591
590
|
}
|
|
592
591
|
}
|
|
593
|
-
position += 8
|
|
592
|
+
position += 8;
|
|
594
593
|
} else if (type === 'undefined') {
|
|
595
594
|
if (this.encodeUndefinedAsNil)
|
|
596
|
-
target[position++] = 0xc0
|
|
595
|
+
target[position++] = 0xc0;
|
|
597
596
|
else {
|
|
598
|
-
target[position++] = 0xd4 // a number of implementations use fixext1 with type 0, data 0 to denote undefined, so we follow suite
|
|
599
|
-
target[position++] = 0
|
|
600
|
-
target[position++] = 0
|
|
597
|
+
target[position++] = 0xd4; // a number of implementations use fixext1 with type 0, data 0 to denote undefined, so we follow suite
|
|
598
|
+
target[position++] = 0;
|
|
599
|
+
target[position++] = 0;
|
|
601
600
|
}
|
|
602
601
|
} else {
|
|
603
|
-
throw new Error('Unknown type: ' + type)
|
|
602
|
+
throw new Error('Unknown type: ' + type);
|
|
604
603
|
}
|
|
605
|
-
}
|
|
604
|
+
};
|
|
606
605
|
|
|
607
606
|
const writePlainObject = (this.variableMapSize || this.coercibleKeyAsNumber || this.skipValues) ? (object) => {
|
|
608
607
|
// this method is slightly slower, but generates "preferred serialization" (optimally small for smaller objects)
|
|
@@ -615,263 +614,264 @@ export class Packr extends Unpackr {
|
|
|
615
614
|
keys.push(key);
|
|
616
615
|
}
|
|
617
616
|
} else {
|
|
618
|
-
keys = Object.keys(object)
|
|
617
|
+
keys = Object.keys(object);
|
|
619
618
|
}
|
|
620
|
-
let length = keys.length
|
|
619
|
+
let length = keys.length;
|
|
621
620
|
if (length < 0x10) {
|
|
622
|
-
target[position++] = 0x80 | length
|
|
621
|
+
target[position++] = 0x80 | length;
|
|
623
622
|
} else if (length < 0x10000) {
|
|
624
|
-
target[position++] = 0xde
|
|
625
|
-
target[position++] = length >> 8
|
|
626
|
-
target[position++] = length & 0xff
|
|
623
|
+
target[position++] = 0xde;
|
|
624
|
+
target[position++] = length >> 8;
|
|
625
|
+
target[position++] = length & 0xff;
|
|
627
626
|
} else {
|
|
628
|
-
target[position++] = 0xdf
|
|
629
|
-
targetView.setUint32(position, length)
|
|
630
|
-
position += 4
|
|
627
|
+
target[position++] = 0xdf;
|
|
628
|
+
targetView.setUint32(position, length);
|
|
629
|
+
position += 4;
|
|
631
630
|
}
|
|
632
|
-
let key
|
|
631
|
+
let key;
|
|
633
632
|
if (this.coercibleKeyAsNumber) {
|
|
634
633
|
for (let i = 0; i < length; i++) {
|
|
635
|
-
key = keys[i]
|
|
636
|
-
let num = Number(key)
|
|
637
|
-
pack(isNaN(num) ? key : num)
|
|
638
|
-
pack(object[key])
|
|
634
|
+
key = keys[i];
|
|
635
|
+
let num = Number(key);
|
|
636
|
+
pack(isNaN(num) ? key : num);
|
|
637
|
+
pack(object[key]);
|
|
639
638
|
}
|
|
640
639
|
|
|
641
640
|
} else {
|
|
642
641
|
for (let i = 0; i < length; i++) {
|
|
643
|
-
pack(key = keys[i])
|
|
644
|
-
pack(object[key])
|
|
642
|
+
pack(key = keys[i]);
|
|
643
|
+
pack(object[key]);
|
|
645
644
|
}
|
|
646
645
|
}
|
|
647
646
|
} :
|
|
648
647
|
(object) => {
|
|
649
|
-
target[position++] = 0xde // always using map 16, so we can preallocate and set the length afterwards
|
|
650
|
-
let objectOffset = position - start
|
|
651
|
-
position += 2
|
|
652
|
-
let size = 0
|
|
648
|
+
target[position++] = 0xde; // always using map 16, so we can preallocate and set the length afterwards
|
|
649
|
+
let objectOffset = position - start;
|
|
650
|
+
position += 2;
|
|
651
|
+
let size = 0;
|
|
653
652
|
for (let key in object) {
|
|
654
653
|
if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
|
|
655
|
-
pack(key)
|
|
656
|
-
pack(object[key])
|
|
657
|
-
size
|
|
654
|
+
pack(key);
|
|
655
|
+
pack(object[key]);
|
|
656
|
+
size++;
|
|
658
657
|
}
|
|
659
658
|
}
|
|
660
659
|
if (size > 0xffff) {
|
|
661
660
|
throw new Error('Object is too large to serialize with fast 16-bit map size,' +
|
|
662
661
|
' use the "variableMapSize" option to serialize this object');
|
|
663
662
|
}
|
|
664
|
-
target[objectOffset++ + start] = size >> 8
|
|
665
|
-
target[objectOffset + start] = size & 0xff
|
|
666
|
-
}
|
|
663
|
+
target[objectOffset++ + start] = size >> 8;
|
|
664
|
+
target[objectOffset + start] = size & 0xff;
|
|
665
|
+
};
|
|
667
666
|
|
|
668
667
|
const writeRecord = this.useRecords === false ? writePlainObject :
|
|
669
668
|
(options.progressiveRecords && !useTwoByteRecords) ? // this is about 2% faster for highly stable structures, since it only requires one for-in loop (but much more expensive when new structure needs to be written)
|
|
670
669
|
(object) => {
|
|
671
|
-
let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null))
|
|
672
|
-
let objectOffset = position++ - start
|
|
673
|
-
let wroteKeys
|
|
670
|
+
let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
|
|
671
|
+
let objectOffset = position++ - start;
|
|
672
|
+
let wroteKeys;
|
|
674
673
|
for (let key in object) {
|
|
675
674
|
if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
|
|
676
|
-
nextTransition = transition[key]
|
|
675
|
+
nextTransition = transition[key];
|
|
677
676
|
if (nextTransition)
|
|
678
|
-
transition = nextTransition
|
|
677
|
+
transition = nextTransition;
|
|
679
678
|
else {
|
|
680
679
|
// record doesn't exist, create full new record and insert it
|
|
681
|
-
let keys = Object.keys(object)
|
|
682
|
-
let lastTransition = transition
|
|
683
|
-
transition = structures.transitions
|
|
684
|
-
let newTransitions = 0
|
|
680
|
+
let keys = Object.keys(object);
|
|
681
|
+
let lastTransition = transition;
|
|
682
|
+
transition = structures.transitions;
|
|
683
|
+
let newTransitions = 0;
|
|
685
684
|
for (let i = 0, l = keys.length; i < l; i++) {
|
|
686
|
-
let key = keys[i]
|
|
687
|
-
nextTransition = transition[key]
|
|
685
|
+
let key = keys[i];
|
|
686
|
+
nextTransition = transition[key];
|
|
688
687
|
if (!nextTransition) {
|
|
689
|
-
nextTransition = transition[key] = Object.create(null)
|
|
690
|
-
newTransitions
|
|
688
|
+
nextTransition = transition[key] = Object.create(null);
|
|
689
|
+
newTransitions++;
|
|
691
690
|
}
|
|
692
|
-
transition = nextTransition
|
|
691
|
+
transition = nextTransition;
|
|
693
692
|
}
|
|
694
693
|
if (objectOffset + start + 1 == position) {
|
|
695
694
|
// first key, so we don't need to insert, we can just write record directly
|
|
696
|
-
position
|
|
697
|
-
newRecord(transition, keys, newTransitions)
|
|
695
|
+
position--;
|
|
696
|
+
newRecord(transition, keys, newTransitions);
|
|
698
697
|
} else // otherwise we need to insert the record, moving existing data after the record
|
|
699
|
-
insertNewRecord(transition, keys, objectOffset, newTransitions)
|
|
700
|
-
wroteKeys = true
|
|
701
|
-
transition = lastTransition[key]
|
|
698
|
+
insertNewRecord(transition, keys, objectOffset, newTransitions);
|
|
699
|
+
wroteKeys = true;
|
|
700
|
+
transition = lastTransition[key];
|
|
702
701
|
}
|
|
703
|
-
pack(object[key])
|
|
702
|
+
pack(object[key]);
|
|
704
703
|
}
|
|
705
704
|
}
|
|
706
705
|
if (!wroteKeys) {
|
|
707
|
-
let recordId = transition[RECORD_SYMBOL]
|
|
706
|
+
let recordId = transition[RECORD_SYMBOL];
|
|
708
707
|
if (recordId)
|
|
709
|
-
target[objectOffset + start] = recordId
|
|
708
|
+
target[objectOffset + start] = recordId;
|
|
710
709
|
else
|
|
711
|
-
insertNewRecord(transition, Object.keys(object), objectOffset, 0)
|
|
710
|
+
insertNewRecord(transition, Object.keys(object), objectOffset, 0);
|
|
712
711
|
}
|
|
713
712
|
} :
|
|
714
713
|
(object) => {
|
|
715
|
-
let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null))
|
|
716
|
-
let newTransitions = 0
|
|
714
|
+
let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
|
|
715
|
+
let newTransitions = 0;
|
|
717
716
|
for (let key in object) if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
|
|
718
|
-
nextTransition = transition[key]
|
|
717
|
+
nextTransition = transition[key];
|
|
719
718
|
if (!nextTransition) {
|
|
720
|
-
nextTransition = transition[key] = Object.create(null)
|
|
721
|
-
newTransitions
|
|
719
|
+
nextTransition = transition[key] = Object.create(null);
|
|
720
|
+
newTransitions++;
|
|
722
721
|
}
|
|
723
|
-
transition = nextTransition
|
|
722
|
+
transition = nextTransition;
|
|
724
723
|
}
|
|
725
|
-
let recordId = transition[RECORD_SYMBOL]
|
|
724
|
+
let recordId = transition[RECORD_SYMBOL];
|
|
726
725
|
if (recordId) {
|
|
727
726
|
if (recordId >= 0x60 && useTwoByteRecords) {
|
|
728
|
-
target[position++] = ((recordId -= 0x60) & 0x1f) + 0x60
|
|
729
|
-
target[position++] = recordId >> 5
|
|
727
|
+
target[position++] = ((recordId -= 0x60) & 0x1f) + 0x60;
|
|
728
|
+
target[position++] = recordId >> 5;
|
|
730
729
|
} else
|
|
731
|
-
target[position++] = recordId
|
|
730
|
+
target[position++] = recordId;
|
|
732
731
|
} else {
|
|
733
|
-
newRecord(transition, transition.__keys__ || Object.keys(object), newTransitions)
|
|
732
|
+
newRecord(transition, transition.__keys__ || Object.keys(object), newTransitions);
|
|
734
733
|
}
|
|
735
734
|
// now write the values
|
|
736
735
|
for (let key in object)
|
|
737
736
|
if (typeof object.hasOwnProperty !== 'function' || object.hasOwnProperty(key)) {
|
|
738
|
-
pack(object[key])
|
|
737
|
+
pack(object[key]);
|
|
739
738
|
}
|
|
740
|
-
}
|
|
739
|
+
};
|
|
741
740
|
|
|
742
741
|
// create reference to useRecords if useRecords is a function
|
|
743
742
|
const checkUseRecords = typeof this.useRecords == 'function' && this.useRecords;
|
|
744
743
|
|
|
745
744
|
const writeObject = checkUseRecords ? (object) => {
|
|
746
|
-
checkUseRecords(object) ? writeRecord(object) : writePlainObject(object)
|
|
747
|
-
} : writeRecord
|
|
745
|
+
checkUseRecords(object) ? writeRecord(object) : writePlainObject(object);
|
|
746
|
+
} : writeRecord;
|
|
747
|
+
|
|
748
|
+
const writeStruct = (object) => {
|
|
749
|
+
let newPosition = packr._writeStruct(object, target, start, position, structures, makeRoom, (value, newPosition, notifySharedUpdate) => {
|
|
750
|
+
if (notifySharedUpdate)
|
|
751
|
+
return hasSharedUpdate = true;
|
|
752
|
+
position = newPosition;
|
|
753
|
+
let startTarget = target;
|
|
754
|
+
pack(value);
|
|
755
|
+
resetStructures();
|
|
756
|
+
if (startTarget !== target) {
|
|
757
|
+
return { position, targetView, target }; // indicate the buffer was re-allocated
|
|
758
|
+
}
|
|
759
|
+
return position;
|
|
760
|
+
});
|
|
761
|
+
if (newPosition === 0) // bail and go to a msgpack object
|
|
762
|
+
return writeObject(object);
|
|
763
|
+
position = newPosition;
|
|
764
|
+
};
|
|
748
765
|
|
|
749
766
|
const makeRoom = (end) => {
|
|
750
|
-
let newSize
|
|
767
|
+
let newSize;
|
|
751
768
|
if (end > 0x1000000) {
|
|
752
769
|
// special handling for really large buffers
|
|
753
770
|
if ((end - start) > MAX_BUFFER_SIZE)
|
|
754
|
-
throw new Error('Packed buffer would be larger than maximum buffer size')
|
|
771
|
+
throw new Error('Packed buffer would be larger than maximum buffer size');
|
|
755
772
|
newSize = Math.min(MAX_BUFFER_SIZE,
|
|
756
|
-
Math.round(Math.max((end - start) * (end > 0x4000000 ? 1.25 : 2), 0x400000) / 0x1000) * 0x1000)
|
|
773
|
+
Math.round(Math.max((end - start) * (end > 0x4000000 ? 1.25 : 2), 0x400000) / 0x1000) * 0x1000);
|
|
757
774
|
} else // faster handling for smaller buffers
|
|
758
|
-
newSize = ((Math.max((end - start) << 2, target.length - 1) >> 12) + 1) << 12
|
|
759
|
-
let newBuffer = new ByteArrayAllocate(newSize)
|
|
760
|
-
targetView = newBuffer.dataView || (newBuffer.dataView = new DataView(newBuffer.buffer, 0, newSize))
|
|
761
|
-
end = Math.min(end, target.length)
|
|
775
|
+
newSize = ((Math.max((end - start) << 2, target.length - 1) >> 12) + 1) << 12;
|
|
776
|
+
let newBuffer = new ByteArrayAllocate(newSize);
|
|
777
|
+
targetView = newBuffer.dataView || (newBuffer.dataView = new DataView(newBuffer.buffer, 0, newSize));
|
|
778
|
+
end = Math.min(end, target.length);
|
|
762
779
|
if (target.copy)
|
|
763
|
-
target.copy(newBuffer, 0, start, end)
|
|
780
|
+
target.copy(newBuffer, 0, start, end);
|
|
764
781
|
else
|
|
765
|
-
newBuffer.set(target.slice(start, end))
|
|
766
|
-
position -= start
|
|
767
|
-
start = 0
|
|
768
|
-
safeEnd = newBuffer.length - 10
|
|
769
|
-
return target = newBuffer
|
|
770
|
-
}
|
|
782
|
+
newBuffer.set(target.slice(start, end));
|
|
783
|
+
position -= start;
|
|
784
|
+
start = 0;
|
|
785
|
+
safeEnd = newBuffer.length - 10;
|
|
786
|
+
return target = newBuffer;
|
|
787
|
+
};
|
|
771
788
|
const newRecord = (transition, keys, newTransitions) => {
|
|
772
|
-
let recordId = structures.nextId
|
|
789
|
+
let recordId = structures.nextId;
|
|
773
790
|
if (!recordId)
|
|
774
|
-
recordId = 0x40
|
|
791
|
+
recordId = 0x40;
|
|
775
792
|
if (recordId < sharedLimitId && this.shouldShareStructure && !this.shouldShareStructure(keys)) {
|
|
776
|
-
recordId = structures.nextOwnId
|
|
793
|
+
recordId = structures.nextOwnId;
|
|
777
794
|
if (!(recordId < maxStructureId))
|
|
778
|
-
recordId = sharedLimitId
|
|
779
|
-
structures.nextOwnId = recordId + 1
|
|
795
|
+
recordId = sharedLimitId;
|
|
796
|
+
structures.nextOwnId = recordId + 1;
|
|
780
797
|
} else {
|
|
781
798
|
if (recordId >= maxStructureId)// cycle back around
|
|
782
|
-
recordId = sharedLimitId
|
|
783
|
-
structures.nextId = recordId + 1
|
|
799
|
+
recordId = sharedLimitId;
|
|
800
|
+
structures.nextId = recordId + 1;
|
|
784
801
|
}
|
|
785
|
-
let highByte = keys.highByte = recordId >= 0x60 && useTwoByteRecords ? (recordId - 0x60) >> 5 : -1
|
|
786
|
-
transition[RECORD_SYMBOL] = recordId
|
|
787
|
-
transition.__keys__ = keys
|
|
788
|
-
structures[recordId - 0x40] = keys
|
|
802
|
+
let highByte = keys.highByte = recordId >= 0x60 && useTwoByteRecords ? (recordId - 0x60) >> 5 : -1;
|
|
803
|
+
transition[RECORD_SYMBOL] = recordId;
|
|
804
|
+
transition.__keys__ = keys;
|
|
805
|
+
structures[recordId - 0x40] = keys;
|
|
789
806
|
|
|
790
807
|
if (recordId < sharedLimitId) {
|
|
791
|
-
keys.isShared = true
|
|
792
|
-
structures.sharedLength = recordId - 0x3f
|
|
793
|
-
hasSharedUpdate = true
|
|
808
|
+
keys.isShared = true;
|
|
809
|
+
structures.sharedLength = recordId - 0x3f;
|
|
810
|
+
hasSharedUpdate = true;
|
|
794
811
|
if (highByte >= 0) {
|
|
795
|
-
target[position++] = (recordId & 0x1f) + 0x60
|
|
796
|
-
target[position++] = highByte
|
|
812
|
+
target[position++] = (recordId & 0x1f) + 0x60;
|
|
813
|
+
target[position++] = highByte;
|
|
797
814
|
} else {
|
|
798
|
-
target[position++] = recordId
|
|
815
|
+
target[position++] = recordId;
|
|
799
816
|
}
|
|
800
817
|
} else {
|
|
801
818
|
if (highByte >= 0) {
|
|
802
|
-
target[position++] = 0xd5 // fixext 2
|
|
803
|
-
target[position++] = 0x72 // "r" record defintion extension type
|
|
804
|
-
target[position++] = (recordId & 0x1f) + 0x60
|
|
805
|
-
target[position++] = highByte
|
|
819
|
+
target[position++] = 0xd5; // fixext 2
|
|
820
|
+
target[position++] = 0x72; // "r" record defintion extension type
|
|
821
|
+
target[position++] = (recordId & 0x1f) + 0x60;
|
|
822
|
+
target[position++] = highByte;
|
|
806
823
|
} else {
|
|
807
|
-
target[position++] = 0xd4 // fixext 1
|
|
808
|
-
target[position++] = 0x72 // "r" record defintion extension type
|
|
809
|
-
target[position++] = recordId
|
|
824
|
+
target[position++] = 0xd4; // fixext 1
|
|
825
|
+
target[position++] = 0x72; // "r" record defintion extension type
|
|
826
|
+
target[position++] = recordId;
|
|
810
827
|
}
|
|
811
828
|
|
|
812
829
|
if (newTransitions)
|
|
813
|
-
transitionsCount += serializationsSinceTransitionRebuild * newTransitions
|
|
830
|
+
transitionsCount += serializationsSinceTransitionRebuild * newTransitions;
|
|
814
831
|
// record the removal of the id, we can maintain our shared structure
|
|
815
832
|
if (recordIdsToRemove.length >= maxOwnStructures)
|
|
816
|
-
recordIdsToRemove.shift()[RECORD_SYMBOL] = 0 // we are cycling back through, and have to remove old ones
|
|
817
|
-
recordIdsToRemove.push(transition)
|
|
818
|
-
pack(keys)
|
|
833
|
+
recordIdsToRemove.shift()[RECORD_SYMBOL] = 0; // we are cycling back through, and have to remove old ones
|
|
834
|
+
recordIdsToRemove.push(transition);
|
|
835
|
+
pack(keys);
|
|
819
836
|
}
|
|
820
|
-
}
|
|
837
|
+
};
|
|
821
838
|
const insertNewRecord = (transition, keys, insertionOffset, newTransitions) => {
|
|
822
|
-
let mainTarget = target
|
|
823
|
-
let mainPosition = position
|
|
824
|
-
let mainSafeEnd = safeEnd
|
|
825
|
-
let mainStart = start
|
|
826
|
-
target = keysTarget
|
|
827
|
-
position = 0
|
|
828
|
-
start = 0
|
|
839
|
+
let mainTarget = target;
|
|
840
|
+
let mainPosition = position;
|
|
841
|
+
let mainSafeEnd = safeEnd;
|
|
842
|
+
let mainStart = start;
|
|
843
|
+
target = keysTarget;
|
|
844
|
+
position = 0;
|
|
845
|
+
start = 0;
|
|
829
846
|
if (!target)
|
|
830
|
-
keysTarget = target = new ByteArrayAllocate(8192)
|
|
831
|
-
safeEnd = target.length - 10
|
|
832
|
-
newRecord(transition, keys, newTransitions)
|
|
833
|
-
keysTarget = target
|
|
834
|
-
let keysPosition = position
|
|
835
|
-
target = mainTarget
|
|
836
|
-
position = mainPosition
|
|
837
|
-
safeEnd = mainSafeEnd
|
|
838
|
-
start = mainStart
|
|
847
|
+
keysTarget = target = new ByteArrayAllocate(8192);
|
|
848
|
+
safeEnd = target.length - 10;
|
|
849
|
+
newRecord(transition, keys, newTransitions);
|
|
850
|
+
keysTarget = target;
|
|
851
|
+
let keysPosition = position;
|
|
852
|
+
target = mainTarget;
|
|
853
|
+
position = mainPosition;
|
|
854
|
+
safeEnd = mainSafeEnd;
|
|
855
|
+
start = mainStart;
|
|
839
856
|
if (keysPosition > 1) {
|
|
840
|
-
let newEnd = position + keysPosition - 1
|
|
857
|
+
let newEnd = position + keysPosition - 1;
|
|
841
858
|
if (newEnd > safeEnd)
|
|
842
|
-
makeRoom(newEnd)
|
|
843
|
-
let insertionPosition = insertionOffset + start
|
|
844
|
-
target.copyWithin(insertionPosition + keysPosition, insertionPosition + 1, position)
|
|
845
|
-
target.set(keysTarget.slice(0, keysPosition), insertionPosition)
|
|
846
|
-
position = newEnd
|
|
859
|
+
makeRoom(newEnd);
|
|
860
|
+
let insertionPosition = insertionOffset + start;
|
|
861
|
+
target.copyWithin(insertionPosition + keysPosition, insertionPosition + 1, position);
|
|
862
|
+
target.set(keysTarget.slice(0, keysPosition), insertionPosition);
|
|
863
|
+
position = newEnd;
|
|
847
864
|
} else {
|
|
848
|
-
target[insertionOffset + start] = keysTarget[0]
|
|
865
|
+
target[insertionOffset + start] = keysTarget[0];
|
|
849
866
|
}
|
|
850
|
-
}
|
|
851
|
-
const writeStruct = (object) => {
|
|
852
|
-
let newPosition = writeStructSlots(object, target, start, position, structures, makeRoom, (value, newPosition, notifySharedUpdate) => {
|
|
853
|
-
if (notifySharedUpdate)
|
|
854
|
-
return hasSharedUpdate = true;
|
|
855
|
-
position = newPosition;
|
|
856
|
-
let startTarget = target;
|
|
857
|
-
pack(value);
|
|
858
|
-
resetStructures();
|
|
859
|
-
if (startTarget !== target) {
|
|
860
|
-
return { position, targetView, target }; // indicate the buffer was re-allocated
|
|
861
|
-
}
|
|
862
|
-
return position;
|
|
863
|
-
}, this);
|
|
864
|
-
if (newPosition === 0) // bail and go to a msgpack object
|
|
865
|
-
return writeObject(object);
|
|
866
|
-
position = newPosition;
|
|
867
|
-
}
|
|
867
|
+
};
|
|
868
868
|
}
|
|
869
869
|
useBuffer(buffer) {
|
|
870
870
|
// this means we are finished using our own buffer and we can write over it safely
|
|
871
|
-
target = buffer
|
|
872
|
-
target.dataView || (target.dataView = new DataView(target.buffer, target.byteOffset, target.byteLength))
|
|
871
|
+
target = buffer;
|
|
872
|
+
target.dataView || (target.dataView = new DataView(target.buffer, target.byteOffset, target.byteLength));
|
|
873
873
|
targetView = target.dataView;
|
|
874
|
-
position = 0
|
|
874
|
+
position = 0;
|
|
875
875
|
}
|
|
876
876
|
set position (value) {
|
|
877
877
|
position = value;
|
|
@@ -881,261 +881,262 @@ export class Packr extends Unpackr {
|
|
|
881
881
|
}
|
|
882
882
|
clearSharedData() {
|
|
883
883
|
if (this.structures)
|
|
884
|
-
this.structures = []
|
|
884
|
+
this.structures = [];
|
|
885
885
|
if (this.typedStructs)
|
|
886
|
-
this.typedStructs = []
|
|
886
|
+
this.typedStructs = [];
|
|
887
887
|
}
|
|
888
888
|
}
|
|
889
889
|
|
|
890
|
-
extensionClasses = [ Date, Set, Error, RegExp, ArrayBuffer, Object.getPrototypeOf(Uint8Array.prototype).constructor /*TypedArray*/, DataView, C1Type ]
|
|
890
|
+
extensionClasses = [ Date, Set, Error, RegExp, ArrayBuffer, Object.getPrototypeOf(Uint8Array.prototype).constructor /*TypedArray*/, DataView, C1Type ];
|
|
891
891
|
extensions = [{
|
|
892
892
|
pack(date, allocateForWrite, pack) {
|
|
893
|
-
let seconds = date.getTime() / 1000
|
|
893
|
+
let seconds = date.getTime() / 1000;
|
|
894
894
|
if ((this.useTimestamp32 || date.getMilliseconds() === 0) && seconds >= 0 && seconds < 0x100000000) {
|
|
895
895
|
// Timestamp 32
|
|
896
|
-
let { target, targetView, position} = allocateForWrite(6)
|
|
897
|
-
target[position++] = 0xd6
|
|
898
|
-
target[position++] = 0xff
|
|
899
|
-
targetView.setUint32(position, seconds)
|
|
896
|
+
let { target, targetView, position} = allocateForWrite(6);
|
|
897
|
+
target[position++] = 0xd6;
|
|
898
|
+
target[position++] = 0xff;
|
|
899
|
+
targetView.setUint32(position, seconds);
|
|
900
900
|
} else if (seconds > 0 && seconds < 0x100000000) {
|
|
901
901
|
// Timestamp 64
|
|
902
|
-
let { target, targetView, position} = allocateForWrite(10)
|
|
903
|
-
target[position++] = 0xd7
|
|
904
|
-
target[position++] = 0xff
|
|
905
|
-
targetView.setUint32(position, date.getMilliseconds() * 4000000 + ((seconds / 1000 / 0x100000000) >> 0))
|
|
906
|
-
targetView.setUint32(position + 4, seconds)
|
|
902
|
+
let { target, targetView, position} = allocateForWrite(10);
|
|
903
|
+
target[position++] = 0xd7;
|
|
904
|
+
target[position++] = 0xff;
|
|
905
|
+
targetView.setUint32(position, date.getMilliseconds() * 4000000 + ((seconds / 1000 / 0x100000000) >> 0));
|
|
906
|
+
targetView.setUint32(position + 4, seconds);
|
|
907
907
|
} else if (isNaN(seconds)) {
|
|
908
908
|
if (this.onInvalidDate) {
|
|
909
|
-
allocateForWrite(0)
|
|
910
|
-
return pack(this.onInvalidDate())
|
|
909
|
+
allocateForWrite(0);
|
|
910
|
+
return pack(this.onInvalidDate());
|
|
911
911
|
}
|
|
912
912
|
// Intentionally invalid timestamp
|
|
913
|
-
let { target, targetView, position} = allocateForWrite(3)
|
|
914
|
-
target[position++] = 0xd4
|
|
915
|
-
target[position++] = 0xff
|
|
916
|
-
target[position++] = 0xff
|
|
913
|
+
let { target, targetView, position} = allocateForWrite(3);
|
|
914
|
+
target[position++] = 0xd4;
|
|
915
|
+
target[position++] = 0xff;
|
|
916
|
+
target[position++] = 0xff;
|
|
917
917
|
} else {
|
|
918
918
|
// Timestamp 96
|
|
919
|
-
let { target, targetView, position} = allocateForWrite(15)
|
|
920
|
-
target[position++] = 0xc7
|
|
921
|
-
target[position++] = 12
|
|
922
|
-
target[position++] = 0xff
|
|
923
|
-
targetView.setUint32(position, date.getMilliseconds() * 1000000)
|
|
924
|
-
targetView.setBigInt64(position + 4, BigInt(Math.floor(seconds)))
|
|
919
|
+
let { target, targetView, position} = allocateForWrite(15);
|
|
920
|
+
target[position++] = 0xc7;
|
|
921
|
+
target[position++] = 12;
|
|
922
|
+
target[position++] = 0xff;
|
|
923
|
+
targetView.setUint32(position, date.getMilliseconds() * 1000000);
|
|
924
|
+
targetView.setBigInt64(position + 4, BigInt(Math.floor(seconds)));
|
|
925
925
|
}
|
|
926
926
|
}
|
|
927
927
|
}, {
|
|
928
928
|
pack(set, allocateForWrite, pack) {
|
|
929
929
|
if (this.setAsEmptyObject) {
|
|
930
930
|
allocateForWrite(0);
|
|
931
|
-
return pack({})
|
|
931
|
+
return pack({});
|
|
932
932
|
}
|
|
933
|
-
let array = Array.from(set)
|
|
934
|
-
let { target, position} = allocateForWrite(this.moreTypes ? 3 : 0)
|
|
933
|
+
let array = Array.from(set);
|
|
934
|
+
let { target, position} = allocateForWrite(this.moreTypes ? 3 : 0);
|
|
935
935
|
if (this.moreTypes) {
|
|
936
|
-
target[position++] = 0xd4
|
|
937
|
-
target[position++] = 0x73 // 's' for Set
|
|
938
|
-
target[position++] = 0
|
|
936
|
+
target[position++] = 0xd4;
|
|
937
|
+
target[position++] = 0x73; // 's' for Set
|
|
938
|
+
target[position++] = 0;
|
|
939
939
|
}
|
|
940
|
-
pack(array)
|
|
940
|
+
pack(array);
|
|
941
941
|
}
|
|
942
942
|
}, {
|
|
943
943
|
pack(error, allocateForWrite, pack) {
|
|
944
|
-
let { target, position} = allocateForWrite(this.moreTypes ? 3 : 0)
|
|
944
|
+
let { target, position} = allocateForWrite(this.moreTypes ? 3 : 0);
|
|
945
945
|
if (this.moreTypes) {
|
|
946
|
-
target[position++] = 0xd4
|
|
947
|
-
target[position++] = 0x65 // 'e' for error
|
|
948
|
-
target[position++] = 0
|
|
946
|
+
target[position++] = 0xd4;
|
|
947
|
+
target[position++] = 0x65; // 'e' for error
|
|
948
|
+
target[position++] = 0;
|
|
949
949
|
}
|
|
950
|
-
pack([ error.name, error.message, error.cause ])
|
|
950
|
+
pack([ error.name, error.message, error.cause ]);
|
|
951
951
|
}
|
|
952
952
|
}, {
|
|
953
953
|
pack(regex, allocateForWrite, pack) {
|
|
954
|
-
let { target, position} = allocateForWrite(this.moreTypes ? 3 : 0)
|
|
954
|
+
let { target, position} = allocateForWrite(this.moreTypes ? 3 : 0);
|
|
955
955
|
if (this.moreTypes) {
|
|
956
|
-
target[position++] = 0xd4
|
|
957
|
-
target[position++] = 0x78 // 'x' for regeXp
|
|
958
|
-
target[position++] = 0
|
|
956
|
+
target[position++] = 0xd4;
|
|
957
|
+
target[position++] = 0x78; // 'x' for regeXp
|
|
958
|
+
target[position++] = 0;
|
|
959
959
|
}
|
|
960
|
-
pack([ regex.source, regex.flags ])
|
|
960
|
+
pack([ regex.source, regex.flags ]);
|
|
961
961
|
}
|
|
962
962
|
}, {
|
|
963
963
|
pack(arrayBuffer, allocateForWrite) {
|
|
964
964
|
if (this.moreTypes)
|
|
965
|
-
writeExtBuffer(arrayBuffer, 0x10, allocateForWrite)
|
|
965
|
+
writeExtBuffer(arrayBuffer, 0x10, allocateForWrite);
|
|
966
966
|
else
|
|
967
|
-
writeBuffer(hasNodeBuffer ? Buffer.from(arrayBuffer) : new Uint8Array(arrayBuffer), allocateForWrite)
|
|
967
|
+
writeBuffer(hasNodeBuffer ? Buffer.from(arrayBuffer) : new Uint8Array(arrayBuffer), allocateForWrite);
|
|
968
968
|
}
|
|
969
969
|
}, {
|
|
970
970
|
pack(typedArray, allocateForWrite) {
|
|
971
|
-
let constructor = typedArray.constructor
|
|
971
|
+
let constructor = typedArray.constructor;
|
|
972
972
|
if (constructor !== ByteArray && this.moreTypes)
|
|
973
|
-
writeExtBuffer(typedArray, typedArrays.indexOf(constructor.name), allocateForWrite)
|
|
973
|
+
writeExtBuffer(typedArray, typedArrays.indexOf(constructor.name), allocateForWrite);
|
|
974
974
|
else
|
|
975
|
-
writeBuffer(typedArray, allocateForWrite)
|
|
975
|
+
writeBuffer(typedArray, allocateForWrite);
|
|
976
976
|
}
|
|
977
977
|
}, {
|
|
978
978
|
pack(arrayBuffer, allocateForWrite) {
|
|
979
979
|
if (this.moreTypes)
|
|
980
|
-
writeExtBuffer(arrayBuffer, 0x11, allocateForWrite)
|
|
980
|
+
writeExtBuffer(arrayBuffer, 0x11, allocateForWrite);
|
|
981
981
|
else
|
|
982
|
-
writeBuffer(hasNodeBuffer ? Buffer.from(arrayBuffer) : new Uint8Array(arrayBuffer), allocateForWrite)
|
|
982
|
+
writeBuffer(hasNodeBuffer ? Buffer.from(arrayBuffer) : new Uint8Array(arrayBuffer), allocateForWrite);
|
|
983
983
|
}
|
|
984
984
|
}, {
|
|
985
985
|
pack(c1, allocateForWrite) { // specific 0xC1 object
|
|
986
|
-
let { target, position} = allocateForWrite(1)
|
|
987
|
-
target[position] = 0xc1
|
|
986
|
+
let { target, position} = allocateForWrite(1);
|
|
987
|
+
target[position] = 0xc1;
|
|
988
988
|
}
|
|
989
|
-
}]
|
|
989
|
+
}];
|
|
990
990
|
|
|
991
991
|
function writeExtBuffer(typedArray, type, allocateForWrite, encode) {
|
|
992
|
-
let length = typedArray.byteLength
|
|
992
|
+
let length = typedArray.byteLength;
|
|
993
993
|
if (length + 1 < 0x100) {
|
|
994
|
-
var { target, position } = allocateForWrite(4 + length)
|
|
995
|
-
target[position++] = 0xc7
|
|
996
|
-
target[position++] = length + 1
|
|
994
|
+
var { target, position } = allocateForWrite(4 + length);
|
|
995
|
+
target[position++] = 0xc7;
|
|
996
|
+
target[position++] = length + 1;
|
|
997
997
|
} else if (length + 1 < 0x10000) {
|
|
998
|
-
var { target, position } = allocateForWrite(5 + length)
|
|
999
|
-
target[position++] = 0xc8
|
|
1000
|
-
target[position++] = (length + 1) >> 8
|
|
1001
|
-
target[position++] = (length + 1) & 0xff
|
|
998
|
+
var { target, position } = allocateForWrite(5 + length);
|
|
999
|
+
target[position++] = 0xc8;
|
|
1000
|
+
target[position++] = (length + 1) >> 8;
|
|
1001
|
+
target[position++] = (length + 1) & 0xff;
|
|
1002
1002
|
} else {
|
|
1003
|
-
var { target, position, targetView } = allocateForWrite(7 + length)
|
|
1004
|
-
target[position++] = 0xc9
|
|
1005
|
-
targetView.setUint32(position, length + 1) // plus one for the type byte
|
|
1006
|
-
position += 4
|
|
1003
|
+
var { target, position, targetView } = allocateForWrite(7 + length);
|
|
1004
|
+
target[position++] = 0xc9;
|
|
1005
|
+
targetView.setUint32(position, length + 1); // plus one for the type byte
|
|
1006
|
+
position += 4;
|
|
1007
1007
|
}
|
|
1008
|
-
target[position++] = 0x74 // "t" for typed array
|
|
1009
|
-
target[position++] = type
|
|
1010
|
-
if (!typedArray.buffer) typedArray = new Uint8Array(typedArray)
|
|
1011
|
-
target.set(new Uint8Array(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength), position)
|
|
1008
|
+
target[position++] = 0x74; // "t" for typed array
|
|
1009
|
+
target[position++] = type;
|
|
1010
|
+
if (!typedArray.buffer) typedArray = new Uint8Array(typedArray);
|
|
1011
|
+
target.set(new Uint8Array(typedArray.buffer, typedArray.byteOffset, typedArray.byteLength), position);
|
|
1012
1012
|
}
|
|
1013
1013
|
function writeBuffer(buffer, allocateForWrite) {
|
|
1014
|
-
let length = buffer.byteLength
|
|
1015
|
-
var target, position
|
|
1014
|
+
let length = buffer.byteLength;
|
|
1015
|
+
var target, position;
|
|
1016
1016
|
if (length < 0x100) {
|
|
1017
|
-
var { target, position } = allocateForWrite(length + 2)
|
|
1018
|
-
target[position++] = 0xc4
|
|
1019
|
-
target[position++] = length
|
|
1017
|
+
var { target, position } = allocateForWrite(length + 2);
|
|
1018
|
+
target[position++] = 0xc4;
|
|
1019
|
+
target[position++] = length;
|
|
1020
1020
|
} else if (length < 0x10000) {
|
|
1021
|
-
var { target, position } = allocateForWrite(length + 3)
|
|
1022
|
-
target[position++] = 0xc5
|
|
1023
|
-
target[position++] = length >> 8
|
|
1024
|
-
target[position++] = length & 0xff
|
|
1021
|
+
var { target, position } = allocateForWrite(length + 3);
|
|
1022
|
+
target[position++] = 0xc5;
|
|
1023
|
+
target[position++] = length >> 8;
|
|
1024
|
+
target[position++] = length & 0xff;
|
|
1025
1025
|
} else {
|
|
1026
|
-
var { target, position, targetView } = allocateForWrite(length + 5)
|
|
1027
|
-
target[position++] = 0xc6
|
|
1028
|
-
targetView.setUint32(position, length)
|
|
1029
|
-
position += 4
|
|
1026
|
+
var { target, position, targetView } = allocateForWrite(length + 5);
|
|
1027
|
+
target[position++] = 0xc6;
|
|
1028
|
+
targetView.setUint32(position, length);
|
|
1029
|
+
position += 4;
|
|
1030
1030
|
}
|
|
1031
|
-
target.set(buffer, position)
|
|
1031
|
+
target.set(buffer, position);
|
|
1032
1032
|
}
|
|
1033
1033
|
|
|
1034
1034
|
function writeExtensionData(result, target, position, type) {
|
|
1035
|
-
let length = result.length
|
|
1035
|
+
let length = result.length;
|
|
1036
1036
|
switch (length) {
|
|
1037
1037
|
case 1:
|
|
1038
|
-
target[position++] = 0xd4
|
|
1039
|
-
break
|
|
1038
|
+
target[position++] = 0xd4;
|
|
1039
|
+
break;
|
|
1040
1040
|
case 2:
|
|
1041
|
-
target[position++] = 0xd5
|
|
1042
|
-
break
|
|
1041
|
+
target[position++] = 0xd5;
|
|
1042
|
+
break;
|
|
1043
1043
|
case 4:
|
|
1044
|
-
target[position++] = 0xd6
|
|
1045
|
-
break
|
|
1044
|
+
target[position++] = 0xd6;
|
|
1045
|
+
break;
|
|
1046
1046
|
case 8:
|
|
1047
|
-
target[position++] = 0xd7
|
|
1048
|
-
break
|
|
1047
|
+
target[position++] = 0xd7;
|
|
1048
|
+
break;
|
|
1049
1049
|
case 16:
|
|
1050
|
-
target[position++] = 0xd8
|
|
1051
|
-
break
|
|
1050
|
+
target[position++] = 0xd8;
|
|
1051
|
+
break;
|
|
1052
1052
|
default:
|
|
1053
1053
|
if (length < 0x100) {
|
|
1054
|
-
target[position++] = 0xc7
|
|
1055
|
-
target[position++] = length
|
|
1054
|
+
target[position++] = 0xc7;
|
|
1055
|
+
target[position++] = length;
|
|
1056
1056
|
} else if (length < 0x10000) {
|
|
1057
|
-
target[position++] = 0xc8
|
|
1058
|
-
target[position++] = length >> 8
|
|
1059
|
-
target[position++] = length & 0xff
|
|
1057
|
+
target[position++] = 0xc8;
|
|
1058
|
+
target[position++] = length >> 8;
|
|
1059
|
+
target[position++] = length & 0xff;
|
|
1060
1060
|
} else {
|
|
1061
|
-
target[position++] = 0xc9
|
|
1062
|
-
target[position++] = length >> 24
|
|
1063
|
-
target[position++] = (length >> 16) & 0xff
|
|
1064
|
-
target[position++] = (length >> 8) & 0xff
|
|
1065
|
-
target[position++] = length & 0xff
|
|
1061
|
+
target[position++] = 0xc9;
|
|
1062
|
+
target[position++] = length >> 24;
|
|
1063
|
+
target[position++] = (length >> 16) & 0xff;
|
|
1064
|
+
target[position++] = (length >> 8) & 0xff;
|
|
1065
|
+
target[position++] = length & 0xff;
|
|
1066
1066
|
}
|
|
1067
1067
|
}
|
|
1068
|
-
target[position++] = type
|
|
1069
|
-
target.set(result, position)
|
|
1070
|
-
position += length
|
|
1071
|
-
return position
|
|
1068
|
+
target[position++] = type;
|
|
1069
|
+
target.set(result, position);
|
|
1070
|
+
position += length;
|
|
1071
|
+
return position;
|
|
1072
1072
|
}
|
|
1073
1073
|
|
|
1074
1074
|
function insertIds(serialized, idsToInsert) {
|
|
1075
1075
|
// insert the ids that need to be referenced for structured clones
|
|
1076
|
-
let nextId
|
|
1077
|
-
let distanceToMove = idsToInsert.length * 6
|
|
1078
|
-
let lastEnd = serialized.length - distanceToMove
|
|
1076
|
+
let nextId;
|
|
1077
|
+
let distanceToMove = idsToInsert.length * 6;
|
|
1078
|
+
let lastEnd = serialized.length - distanceToMove;
|
|
1079
1079
|
while (nextId = idsToInsert.pop()) {
|
|
1080
|
-
let offset = nextId.offset
|
|
1081
|
-
let id = nextId.id
|
|
1082
|
-
serialized.copyWithin(offset + distanceToMove, offset, lastEnd)
|
|
1083
|
-
distanceToMove -= 6
|
|
1084
|
-
let position = offset + distanceToMove
|
|
1085
|
-
serialized[position++] = 0xd6
|
|
1086
|
-
serialized[position++] = 0x69 // 'i'
|
|
1087
|
-
serialized[position++] = id >> 24
|
|
1088
|
-
serialized[position++] = (id >> 16) & 0xff
|
|
1089
|
-
serialized[position++] = (id >> 8) & 0xff
|
|
1090
|
-
serialized[position++] = id & 0xff
|
|
1091
|
-
lastEnd = offset
|
|
1080
|
+
let offset = nextId.offset;
|
|
1081
|
+
let id = nextId.id;
|
|
1082
|
+
serialized.copyWithin(offset + distanceToMove, offset, lastEnd);
|
|
1083
|
+
distanceToMove -= 6;
|
|
1084
|
+
let position = offset + distanceToMove;
|
|
1085
|
+
serialized[position++] = 0xd6;
|
|
1086
|
+
serialized[position++] = 0x69; // 'i'
|
|
1087
|
+
serialized[position++] = id >> 24;
|
|
1088
|
+
serialized[position++] = (id >> 16) & 0xff;
|
|
1089
|
+
serialized[position++] = (id >> 8) & 0xff;
|
|
1090
|
+
serialized[position++] = id & 0xff;
|
|
1091
|
+
lastEnd = offset;
|
|
1092
1092
|
}
|
|
1093
|
-
return serialized
|
|
1093
|
+
return serialized;
|
|
1094
1094
|
}
|
|
1095
1095
|
|
|
1096
1096
|
function writeBundles(start, pack, incrementPosition) {
|
|
1097
1097
|
if (bundledStrings.length > 0) {
|
|
1098
|
-
targetView.setUint32(bundledStrings.position + start, position + incrementPosition - bundledStrings.position - start)
|
|
1098
|
+
targetView.setUint32(bundledStrings.position + start, position + incrementPosition - bundledStrings.position - start);
|
|
1099
1099
|
bundledStrings.stringsPosition = position - start;
|
|
1100
|
-
let writeStrings = bundledStrings
|
|
1101
|
-
bundledStrings = null
|
|
1102
|
-
pack(writeStrings[0])
|
|
1103
|
-
pack(writeStrings[1])
|
|
1100
|
+
let writeStrings = bundledStrings;
|
|
1101
|
+
bundledStrings = null;
|
|
1102
|
+
pack(writeStrings[0]);
|
|
1103
|
+
pack(writeStrings[1]);
|
|
1104
1104
|
}
|
|
1105
1105
|
}
|
|
1106
1106
|
|
|
1107
1107
|
export function addExtension(extension) {
|
|
1108
1108
|
if (extension.Class) {
|
|
1109
1109
|
if (!extension.pack && !extension.write)
|
|
1110
|
-
throw new Error('Extension has no pack or write function')
|
|
1110
|
+
throw new Error('Extension has no pack or write function');
|
|
1111
1111
|
if (extension.pack && !extension.type)
|
|
1112
|
-
throw new Error('Extension has no type (numeric code to identify the extension)')
|
|
1113
|
-
extensionClasses.unshift(extension.Class)
|
|
1114
|
-
extensions.unshift(extension)
|
|
1112
|
+
throw new Error('Extension has no type (numeric code to identify the extension)');
|
|
1113
|
+
extensionClasses.unshift(extension.Class);
|
|
1114
|
+
extensions.unshift(extension);
|
|
1115
1115
|
}
|
|
1116
|
-
unpackAddExtension(extension)
|
|
1116
|
+
unpackAddExtension(extension);
|
|
1117
1117
|
}
|
|
1118
1118
|
function prepareStructures(structures, packr) {
|
|
1119
1119
|
structures.isCompatible = (existingStructures) => {
|
|
1120
|
-
let compatible = !existingStructures || ((packr.lastNamedStructuresLength || 0) === existingStructures.length)
|
|
1120
|
+
let compatible = !existingStructures || ((packr.lastNamedStructuresLength || 0) === existingStructures.length);
|
|
1121
1121
|
if (!compatible) // we want to merge these existing structures immediately since we already have it and we are in the right transaction
|
|
1122
1122
|
packr._mergeStructures(existingStructures);
|
|
1123
1123
|
return compatible;
|
|
1124
|
-
}
|
|
1125
|
-
return structures
|
|
1126
|
-
}
|
|
1127
|
-
export function setWriteStructSlots(writeSlots, makeStructures) {
|
|
1128
|
-
writeStructSlots = writeSlots;
|
|
1129
|
-
prepareStructures = makeStructures;
|
|
1124
|
+
};
|
|
1125
|
+
return structures;
|
|
1130
1126
|
}
|
|
1131
1127
|
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
export const
|
|
1139
|
-
export const
|
|
1140
|
-
export const
|
|
1141
|
-
export
|
|
1128
|
+
// Marker for downstream libraries (e.g. structon) to detect that this Packr
|
|
1129
|
+
// supports per-instance struct-encoding hooks (this._writeStruct,
|
|
1130
|
+
// this._prepareStructures). See `pack` for the dispatch.
|
|
1131
|
+
Packr.SUPPORTS_STRUCT_HOOKS = true;
|
|
1132
|
+
|
|
1133
|
+
let defaultPackr = new Packr({ useRecords: false });
|
|
1134
|
+
export const pack = defaultPackr.pack;
|
|
1135
|
+
export const encode = defaultPackr.pack;
|
|
1136
|
+
export const Encoder = Packr;
|
|
1137
|
+
export { FLOAT32_OPTIONS } from './unpack.js';
|
|
1138
|
+
import { FLOAT32_OPTIONS } from './unpack.js';
|
|
1139
|
+
export const { NEVER, ALWAYS, DECIMAL_ROUND, DECIMAL_FIT } = FLOAT32_OPTIONS;
|
|
1140
|
+
export const REUSE_BUFFER_MODE = 512;
|
|
1141
|
+
export const RESET_BUFFER_MODE = 1024;
|
|
1142
|
+
export const RESERVE_START_SPACE = 2048;
|