@andrew_l/tl-pack 0.2.15 → 0.2.16
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 +196 -0
- package/dist/index.cjs +10 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -2
- package/dist/index.d.mts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/dist/shared/tl-pack.BEGh3J6q.d.cts +477 -0
- package/dist/shared/tl-pack.BEGh3J6q.d.mts +477 -0
- package/dist/shared/tl-pack.BEGh3J6q.d.ts +477 -0
- package/dist/shared/{tl-pack.DfL54MjP.cjs → tl-pack.CaWRi9zF.cjs} +1363 -933
- package/dist/shared/tl-pack.CaWRi9zF.cjs.map +1 -0
- package/dist/shared/{tl-pack.CkwM-fIb.mjs → tl-pack.CxheH0R_.mjs} +1363 -935
- package/dist/shared/tl-pack.CxheH0R_.mjs.map +1 -0
- package/dist/stream.cjs +5 -5
- package/dist/stream.d.cts +2 -1
- package/dist/stream.d.mts +2 -1
- package/dist/stream.d.ts +2 -1
- package/dist/stream.mjs +1 -1
- package/package.json +2 -2
- package/dist/shared/tl-pack.C2PEqnNg.d.cts +0 -200
- package/dist/shared/tl-pack.C2PEqnNg.d.mts +0 -200
- package/dist/shared/tl-pack.C2PEqnNg.d.ts +0 -200
- package/dist/shared/tl-pack.CkwM-fIb.mjs.map +0 -1
- package/dist/shared/tl-pack.DfL54MjP.cjs.map +0 -1
|
@@ -31,6 +31,7 @@ var CORE_TYPES = /* @__PURE__ */ ((CORE_TYPES2) => {
|
|
|
31
31
|
CORE_TYPES2[CORE_TYPES2["Repeat"] = 20] = "Repeat";
|
|
32
32
|
CORE_TYPES2[CORE_TYPES2["Checksum"] = 21] = "Checksum";
|
|
33
33
|
CORE_TYPES2[CORE_TYPES2["GZIP"] = 25] = "GZIP";
|
|
34
|
+
CORE_TYPES2[CORE_TYPES2["Structure"] = 26] = "Structure";
|
|
34
35
|
return CORE_TYPES2;
|
|
35
36
|
})(CORE_TYPES || {});
|
|
36
37
|
const MAX_BUFFER_SIZE = 2144337920;
|
|
@@ -85,1072 +86,1499 @@ class Dictionary {
|
|
|
85
86
|
}
|
|
86
87
|
}
|
|
87
88
|
|
|
88
|
-
const
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
89
|
+
const noop = Symbol();
|
|
90
|
+
const NO_CONSTRUCTOR = /* @__PURE__ */ new Set([
|
|
91
|
+
CORE_TYPES.BoolFalse,
|
|
92
|
+
CORE_TYPES.BoolTrue,
|
|
93
|
+
CORE_TYPES.Null
|
|
94
|
+
]);
|
|
95
|
+
const SUPPORT_COMPRESSION = /* @__PURE__ */ new Set([CORE_TYPES.String]);
|
|
96
|
+
const NOOP_DICTIONARY$1 = new Dictionary();
|
|
97
|
+
class BinaryWriter {
|
|
98
|
+
withGzip;
|
|
99
|
+
target;
|
|
100
|
+
dictionary;
|
|
101
|
+
dictionaryExtended;
|
|
102
|
+
extensions;
|
|
103
|
+
structures;
|
|
104
|
+
_last;
|
|
105
|
+
offsetChecksum;
|
|
106
|
+
_repeat;
|
|
107
|
+
offset;
|
|
108
|
+
constructor({
|
|
109
|
+
gzip = false,
|
|
110
|
+
dictionary = NOOP_DICTIONARY$1,
|
|
111
|
+
extensions,
|
|
112
|
+
structures
|
|
113
|
+
} = {}) {
|
|
114
|
+
this.offset = 0;
|
|
115
|
+
this.offsetChecksum = 0;
|
|
116
|
+
this.extensions = /* @__PURE__ */ new Map();
|
|
117
|
+
this.structures = /* @__PURE__ */ new Map();
|
|
118
|
+
this.withGzip = gzip;
|
|
119
|
+
this.target = byteArrayAllocate(8192);
|
|
120
|
+
this._last = noop;
|
|
121
|
+
if (extensions) {
|
|
122
|
+
for (const ext of extensions) {
|
|
123
|
+
this.extensions.set(ext.token, ext);
|
|
120
124
|
}
|
|
121
|
-
return CORE_TYPES.Double;
|
|
122
125
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
return CORE_TYPES.Date;
|
|
127
|
-
}
|
|
128
|
-
if (Array.isArray(value)) {
|
|
129
|
-
return CORE_TYPES.Vector;
|
|
130
|
-
}
|
|
131
|
-
if (toolkit.isPlainObject(value)) {
|
|
132
|
-
return CORE_TYPES.Map;
|
|
126
|
+
if (structures) {
|
|
127
|
+
for (const struct of structures) {
|
|
128
|
+
this.structures.set(struct.extension.token, struct);
|
|
133
129
|
}
|
|
134
130
|
}
|
|
131
|
+
if (Array.isArray(dictionary)) {
|
|
132
|
+
this.dictionary = new Dictionary(dictionary);
|
|
133
|
+
} else {
|
|
134
|
+
this.dictionary = dictionary;
|
|
135
|
+
}
|
|
136
|
+
this.dictionaryExtended = new Dictionary(void 0, this.dictionary.size);
|
|
135
137
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
138
|
+
/**
|
|
139
|
+
* Reset internal state
|
|
140
|
+
*/
|
|
141
|
+
reset() {
|
|
142
|
+
this.offset = 0;
|
|
143
|
+
this.offsetChecksum = 0;
|
|
144
|
+
this._last = noop;
|
|
145
|
+
this._repeat = void 0;
|
|
146
|
+
this.dictionaryExtended = new Dictionary(void 0, this.dictionary.size);
|
|
147
|
+
return this;
|
|
142
148
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
unit -= 65536;
|
|
166
|
-
units.push(unit >>> 10 & 1023 | 55296);
|
|
167
|
-
unit = 56320 | unit & 1023;
|
|
168
|
-
}
|
|
169
|
-
units.push(unit);
|
|
149
|
+
allocate(size) {
|
|
150
|
+
const position = this.offset + size;
|
|
151
|
+
if (this.safeEnd < position) {
|
|
152
|
+
this.makeRoom(position);
|
|
153
|
+
}
|
|
154
|
+
return this;
|
|
155
|
+
}
|
|
156
|
+
makeRoom(end) {
|
|
157
|
+
let start = 0;
|
|
158
|
+
let newSize = 0;
|
|
159
|
+
let target = this.target;
|
|
160
|
+
if (end > 16777216) {
|
|
161
|
+
if (end - start > MAX_BUFFER_SIZE)
|
|
162
|
+
throw new Error(
|
|
163
|
+
"Packed buffer would be larger than maximum buffer size"
|
|
164
|
+
);
|
|
165
|
+
newSize = Math.min(
|
|
166
|
+
MAX_BUFFER_SIZE,
|
|
167
|
+
Math.round(
|
|
168
|
+
Math.max((end - start) * (end > 67108864 ? 1.25 : 2), 4194304) / 4096
|
|
169
|
+
) * 4096
|
|
170
|
+
);
|
|
170
171
|
} else {
|
|
171
|
-
|
|
172
|
+
newSize = (Math.max(end - start << 2, target.length - 1) >> 12) + 1 << 12;
|
|
172
173
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
174
|
+
const newBuffer = byteArrayAllocate(newSize);
|
|
175
|
+
end = Math.min(end, target.length);
|
|
176
|
+
newBuffer.set(target.slice(start, end));
|
|
177
|
+
this.target = newBuffer;
|
|
178
|
+
}
|
|
179
|
+
get safeEnd() {
|
|
180
|
+
return this.target.length - 10;
|
|
181
|
+
}
|
|
182
|
+
getBuffer() {
|
|
183
|
+
return this.target.subarray(0, this.offset);
|
|
184
|
+
}
|
|
185
|
+
writeByte(value) {
|
|
186
|
+
this.allocate(1);
|
|
187
|
+
this.target[this.offset++] = value;
|
|
188
|
+
return this;
|
|
189
|
+
}
|
|
190
|
+
writeBool(value) {
|
|
191
|
+
if (value) {
|
|
192
|
+
this.writeByte(CORE_TYPES.BoolTrue);
|
|
193
|
+
} else {
|
|
194
|
+
this.writeByte(CORE_TYPES.BoolFalse);
|
|
176
195
|
}
|
|
196
|
+
return this;
|
|
177
197
|
}
|
|
178
|
-
|
|
179
|
-
|
|
198
|
+
writeNull() {
|
|
199
|
+
this.writeByte(CORE_TYPES.Null);
|
|
200
|
+
return this;
|
|
180
201
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
let a = target[offset++];
|
|
189
|
-
if ((a & 128) > 1) {
|
|
190
|
-
offset -= 1;
|
|
191
|
-
return;
|
|
192
|
-
}
|
|
193
|
-
return fromCharCode(a);
|
|
194
|
-
}
|
|
202
|
+
writeInt32(value, signed = true) {
|
|
203
|
+
this.allocate(4);
|
|
204
|
+
if (signed) {
|
|
205
|
+
this.target[this.offset++] = value;
|
|
206
|
+
this.target[this.offset++] = value >> 8;
|
|
207
|
+
this.target[this.offset++] = value >> 16;
|
|
208
|
+
this.target[this.offset++] = value >> 24;
|
|
195
209
|
} else {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
if (length < 3) return fromCharCode(a, b);
|
|
203
|
-
let c = target[offset++];
|
|
204
|
-
if ((c & 128) > 0) {
|
|
205
|
-
offset -= 3;
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
return fromCharCode(a, b, c);
|
|
210
|
+
this.target[this.offset++] = value;
|
|
211
|
+
this.target[this.offset++] = value >> 8;
|
|
212
|
+
this.target[this.offset++] = value >> 16;
|
|
213
|
+
this.target[this.offset++] = value >> 24;
|
|
209
214
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
offset
|
|
217
|
-
|
|
215
|
+
return this;
|
|
216
|
+
}
|
|
217
|
+
writeInt16(value, signed = true) {
|
|
218
|
+
this.allocate(2);
|
|
219
|
+
if (signed) {
|
|
220
|
+
this.target[this.offset++] = value;
|
|
221
|
+
this.target[this.offset++] = value >> 8;
|
|
222
|
+
} else {
|
|
223
|
+
this.target[this.offset++] = value;
|
|
224
|
+
this.target[this.offset++] = value >> 8;
|
|
218
225
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
226
|
+
return this;
|
|
227
|
+
}
|
|
228
|
+
writeInt8(value, signed = true) {
|
|
229
|
+
this.allocate(1);
|
|
230
|
+
this.target[this.offset++] = value;
|
|
231
|
+
return this;
|
|
232
|
+
}
|
|
233
|
+
writeFloat(value) {
|
|
234
|
+
this.allocate(4);
|
|
235
|
+
float32[0] = value;
|
|
236
|
+
this.writeInt32(int32[0]);
|
|
237
|
+
return this;
|
|
238
|
+
}
|
|
239
|
+
writeDouble(value) {
|
|
240
|
+
this.allocate(8);
|
|
241
|
+
float64[0] = value;
|
|
242
|
+
this.writeInt32(int32[0], false);
|
|
243
|
+
this.writeInt32(int32[1], false);
|
|
244
|
+
return this;
|
|
245
|
+
}
|
|
246
|
+
writeDate(value) {
|
|
247
|
+
let timestamp = 0;
|
|
248
|
+
if (value instanceof Date) {
|
|
249
|
+
timestamp = value.getTime();
|
|
250
|
+
} else if (typeof value === "number") {
|
|
251
|
+
timestamp = value;
|
|
252
|
+
}
|
|
253
|
+
this.writeDouble(timestamp);
|
|
254
|
+
return this;
|
|
255
|
+
}
|
|
256
|
+
writeString(value) {
|
|
257
|
+
const strLength = value.length;
|
|
258
|
+
let start = this.offset;
|
|
259
|
+
let require = strLength << 2;
|
|
260
|
+
if (require < 254) {
|
|
261
|
+
require += 1;
|
|
262
|
+
this.offset += 1;
|
|
243
263
|
} else {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
264
|
+
require += 4;
|
|
265
|
+
this.offset += 4;
|
|
266
|
+
}
|
|
267
|
+
this.allocate(require);
|
|
268
|
+
const bytes = utf8Write(this.target, value, this.offset);
|
|
269
|
+
if (require < 254) {
|
|
270
|
+
this.target[start++] = bytes;
|
|
271
|
+
} else {
|
|
272
|
+
this.target[start++] = 254;
|
|
273
|
+
this.target[start++] = bytes % 256;
|
|
274
|
+
this.target[start++] = (bytes >> 8) % 256;
|
|
275
|
+
this.target[start++] = (bytes >> 16) % 256;
|
|
276
|
+
}
|
|
277
|
+
this.offset += bytes;
|
|
278
|
+
return this;
|
|
279
|
+
}
|
|
280
|
+
writeChecksum(withConstructor = true) {
|
|
281
|
+
const bytes = this.target.slice(this.offsetChecksum, this.offset);
|
|
282
|
+
let sum = 0;
|
|
283
|
+
for (const val of bytes) {
|
|
284
|
+
sum += val;
|
|
285
|
+
}
|
|
286
|
+
if (withConstructor) {
|
|
287
|
+
this.writeByte(CORE_TYPES.Checksum);
|
|
288
|
+
}
|
|
289
|
+
this.writeInt32(sum);
|
|
290
|
+
this.offsetChecksum = this.offset;
|
|
291
|
+
return this;
|
|
292
|
+
}
|
|
293
|
+
writeBytes(value) {
|
|
294
|
+
const length = value.length;
|
|
295
|
+
this.writeLength(length);
|
|
296
|
+
this.allocate(length);
|
|
297
|
+
this.target.set(value, this.offset);
|
|
298
|
+
this.offset += length;
|
|
299
|
+
return this;
|
|
300
|
+
}
|
|
301
|
+
writeLength(value) {
|
|
302
|
+
if (value < 254) {
|
|
303
|
+
this.allocate(1);
|
|
304
|
+
this.target[this.offset++] = value;
|
|
305
|
+
} else {
|
|
306
|
+
this.allocate(4);
|
|
307
|
+
this.target[this.offset++] = 254;
|
|
308
|
+
this.target[this.offset++] = value % 256;
|
|
309
|
+
this.target[this.offset++] = (value >> 8) % 256;
|
|
310
|
+
this.target[this.offset++] = (value >> 16) % 256;
|
|
311
|
+
}
|
|
312
|
+
return this;
|
|
313
|
+
}
|
|
314
|
+
writeVector(value) {
|
|
315
|
+
const length = value.length;
|
|
316
|
+
this.writeLength(length);
|
|
317
|
+
for (let i = 0; i < length; i++) {
|
|
318
|
+
if (value[i] === void 0) {
|
|
319
|
+
this.writeNull();
|
|
276
320
|
} else {
|
|
277
|
-
|
|
278
|
-
let j = target[offset++];
|
|
279
|
-
let k = target[offset++];
|
|
280
|
-
let l = target[offset++];
|
|
281
|
-
if ((i & 128) > 0 || (j & 128) > 0 || (k & 128) > 0 || (l & 128) > 0) {
|
|
282
|
-
offset -= 12;
|
|
283
|
-
return;
|
|
284
|
-
}
|
|
285
|
-
if (length < 14) {
|
|
286
|
-
if (length === 12)
|
|
287
|
-
return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l);
|
|
288
|
-
else {
|
|
289
|
-
let m = target[offset++];
|
|
290
|
-
if ((m & 128) > 0) {
|
|
291
|
-
offset -= 13;
|
|
292
|
-
return;
|
|
293
|
-
}
|
|
294
|
-
return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m);
|
|
295
|
-
}
|
|
296
|
-
} else {
|
|
297
|
-
let m = target[offset++];
|
|
298
|
-
let n = target[offset++];
|
|
299
|
-
if ((m & 128) > 0 || (n & 128) > 0) {
|
|
300
|
-
offset -= 14;
|
|
301
|
-
return;
|
|
302
|
-
}
|
|
303
|
-
if (length < 15)
|
|
304
|
-
return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m, n);
|
|
305
|
-
let o = target[offset++];
|
|
306
|
-
if ((o & 128) > 0) {
|
|
307
|
-
offset -= 15;
|
|
308
|
-
return;
|
|
309
|
-
}
|
|
310
|
-
return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o);
|
|
311
|
-
}
|
|
321
|
+
this.writeObject(value[i]);
|
|
312
322
|
}
|
|
313
323
|
}
|
|
324
|
+
return this;
|
|
314
325
|
}
|
|
315
|
-
|
|
316
|
-
const
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
target[strPosition++] = c1 >> 6 & 63 | 128;
|
|
335
|
-
target[strPosition++] = c1 & 63 | 128;
|
|
326
|
+
writeMap(object) {
|
|
327
|
+
for (const key in object) {
|
|
328
|
+
if (object[key] === void 0) continue;
|
|
329
|
+
this._last = noop;
|
|
330
|
+
this.wireDictionary(key);
|
|
331
|
+
this.writeObject(object[key]);
|
|
332
|
+
}
|
|
333
|
+
this.writeByte(CORE_TYPES.None);
|
|
334
|
+
return this;
|
|
335
|
+
}
|
|
336
|
+
wireDictionary(value) {
|
|
337
|
+
let idx = null;
|
|
338
|
+
idx = this.dictionary.getIndex(value);
|
|
339
|
+
if (idx === null) {
|
|
340
|
+
idx = this.dictionaryExtended.getIndex(value);
|
|
341
|
+
}
|
|
342
|
+
if (idx === null) {
|
|
343
|
+
this.dictionaryExtended.maybeInsert(value);
|
|
344
|
+
this.writeCore(CORE_TYPES.DictValue, value);
|
|
336
345
|
} else {
|
|
337
|
-
|
|
338
|
-
target[strPosition++] = c1 >> 6 & 63 | 128;
|
|
339
|
-
target[strPosition++] = c1 & 63 | 128;
|
|
346
|
+
this.writeCore(CORE_TYPES.DictIndex, idx);
|
|
340
347
|
}
|
|
348
|
+
return this;
|
|
341
349
|
}
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
offset;
|
|
355
|
-
length;
|
|
356
|
-
/**
|
|
357
|
-
* Small utility class to read binary data.
|
|
358
|
-
*/
|
|
359
|
-
constructor(data, options) {
|
|
360
|
-
this.target = data;
|
|
350
|
+
writeStructure(value) {
|
|
351
|
+
const ctor = value.constructor;
|
|
352
|
+
this.writeInt32(ctor.extension.token, false);
|
|
353
|
+
ctor.extension.encode.call(this, value.value);
|
|
354
|
+
return this;
|
|
355
|
+
}
|
|
356
|
+
writeGzip(value) {
|
|
357
|
+
const compressed = pako__default.deflateRaw(value, { level: 9 });
|
|
358
|
+
this.writeBytes(compressed);
|
|
359
|
+
return this;
|
|
360
|
+
}
|
|
361
|
+
encode(value) {
|
|
361
362
|
this.offset = 0;
|
|
362
|
-
this.
|
|
363
|
-
this.
|
|
364
|
-
this.
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
363
|
+
this.offsetChecksum = 0;
|
|
364
|
+
this._last = noop;
|
|
365
|
+
this._repeat = void 0;
|
|
366
|
+
this.target = byteArrayAllocate(256);
|
|
367
|
+
this.writeObject(value);
|
|
368
|
+
return this.getBuffer();
|
|
369
|
+
}
|
|
370
|
+
startDynamicVector() {
|
|
371
|
+
this.writeByte(CORE_TYPES.VectorDynamic);
|
|
372
|
+
return this;
|
|
373
|
+
}
|
|
374
|
+
endDynamicVector() {
|
|
375
|
+
this.writeByte(CORE_TYPES.None);
|
|
376
|
+
return this;
|
|
377
|
+
}
|
|
378
|
+
_writeCustom(value) {
|
|
379
|
+
const start = this.offset;
|
|
380
|
+
this.allocate(1);
|
|
381
|
+
this.offset++;
|
|
382
|
+
let edgeExt;
|
|
383
|
+
for (const ext of this.extensions.values()) {
|
|
384
|
+
if (ext.token === -1) {
|
|
385
|
+
edgeExt = ext;
|
|
386
|
+
continue;
|
|
387
|
+
}
|
|
388
|
+
ext.encode.call(this, value);
|
|
389
|
+
const processed = start + 1 < this.offset;
|
|
390
|
+
if (processed) {
|
|
391
|
+
const end = this.offset;
|
|
392
|
+
this.offset = start;
|
|
393
|
+
this.writeByte(ext.token);
|
|
394
|
+
this.offset = end;
|
|
395
|
+
return true;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
this.offset = start;
|
|
399
|
+
if (edgeExt) {
|
|
400
|
+
edgeExt.encode.call(this, value);
|
|
401
|
+
return start < this.offset;
|
|
402
|
+
}
|
|
403
|
+
return false;
|
|
404
|
+
}
|
|
405
|
+
writeObject(value) {
|
|
406
|
+
if (value === void 0) return this;
|
|
407
|
+
const constructorId = coreType(value);
|
|
408
|
+
if (constructorId === CORE_TYPES.None) {
|
|
409
|
+
if (this._writeCustom(value)) {
|
|
410
|
+
return this;
|
|
411
|
+
}
|
|
412
|
+
throw new TypeError(`Invalid core type of ${value}`);
|
|
369
413
|
}
|
|
370
|
-
if (
|
|
371
|
-
this.
|
|
372
|
-
} else if (options.dictionary instanceof Dictionary) {
|
|
373
|
-
this.dictionary = options.dictionary;
|
|
374
|
-
} else if (Array.isArray(options.dictionary)) {
|
|
375
|
-
this.dictionary = new Dictionary(options.dictionary);
|
|
414
|
+
if (this._last === value) {
|
|
415
|
+
this.writeRepeat();
|
|
376
416
|
} else {
|
|
377
|
-
this.
|
|
417
|
+
this._last = value;
|
|
418
|
+
this._repeat = void 0;
|
|
419
|
+
this.writeCore(constructorId, value);
|
|
378
420
|
}
|
|
379
|
-
|
|
421
|
+
return this;
|
|
380
422
|
}
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
423
|
+
writeObjectGzip(value) {
|
|
424
|
+
const writer = new BinaryWriter();
|
|
425
|
+
writer.extensions = this.extensions;
|
|
426
|
+
writer.dictionary = this.dictionary;
|
|
427
|
+
writer.structures = this.structures;
|
|
428
|
+
writer.dictionaryExtended = this.dictionaryExtended;
|
|
429
|
+
writer.writeObject(value);
|
|
430
|
+
this.writeCore(CORE_TYPES.GZIP, writer.getBuffer());
|
|
431
|
+
return this;
|
|
385
432
|
}
|
|
386
|
-
|
|
387
|
-
this.
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
433
|
+
writeCore(constructorId, value) {
|
|
434
|
+
if (this.withGzip && SUPPORT_COMPRESSION.has(constructorId)) {
|
|
435
|
+
this.writeObjectGzip(value);
|
|
436
|
+
return this;
|
|
437
|
+
} else if (!NO_CONSTRUCTOR.has(constructorId)) {
|
|
438
|
+
this.writeByte(constructorId);
|
|
391
439
|
}
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
440
|
+
switch (constructorId) {
|
|
441
|
+
case CORE_TYPES.Structure: {
|
|
442
|
+
return this.writeStructure(value);
|
|
443
|
+
}
|
|
444
|
+
case CORE_TYPES.Binary: {
|
|
445
|
+
return this.writeBytes(value);
|
|
446
|
+
}
|
|
447
|
+
case CORE_TYPES.GZIP: {
|
|
448
|
+
return this.writeGzip(value);
|
|
449
|
+
}
|
|
450
|
+
case CORE_TYPES.DictIndex: {
|
|
451
|
+
return this.writeLength(value);
|
|
452
|
+
}
|
|
453
|
+
case CORE_TYPES.DictValue: {
|
|
454
|
+
return this.writeString(value);
|
|
455
|
+
}
|
|
456
|
+
case CORE_TYPES.BoolFalse: {
|
|
457
|
+
return this.writeBool(value);
|
|
458
|
+
}
|
|
459
|
+
case CORE_TYPES.BoolTrue: {
|
|
460
|
+
return this.writeBool(value);
|
|
461
|
+
}
|
|
462
|
+
case CORE_TYPES.Date: {
|
|
463
|
+
return this.writeDate(value);
|
|
464
|
+
}
|
|
465
|
+
case CORE_TYPES.Int32: {
|
|
466
|
+
return this.writeInt32(value);
|
|
467
|
+
}
|
|
468
|
+
case CORE_TYPES.Int16: {
|
|
469
|
+
return this.writeInt16(value);
|
|
470
|
+
}
|
|
471
|
+
case CORE_TYPES.Int8: {
|
|
472
|
+
return this.writeInt8(value);
|
|
473
|
+
}
|
|
474
|
+
case CORE_TYPES.UInt32: {
|
|
475
|
+
return this.writeInt32(value, false);
|
|
476
|
+
}
|
|
477
|
+
case CORE_TYPES.UInt16: {
|
|
478
|
+
return this.writeInt16(value, false);
|
|
479
|
+
}
|
|
480
|
+
case CORE_TYPES.UInt8: {
|
|
481
|
+
return this.writeInt8(value, false);
|
|
482
|
+
}
|
|
483
|
+
case CORE_TYPES.Double: {
|
|
484
|
+
return this.writeDouble(value);
|
|
485
|
+
}
|
|
486
|
+
case CORE_TYPES.Float: {
|
|
487
|
+
return this.writeFloat(value);
|
|
488
|
+
}
|
|
489
|
+
case CORE_TYPES.Null: {
|
|
490
|
+
return this.writeNull();
|
|
491
|
+
}
|
|
492
|
+
case CORE_TYPES.String: {
|
|
493
|
+
if (value.length <= 16) {
|
|
494
|
+
this.offset--;
|
|
495
|
+
return this.wireDictionary(value);
|
|
496
|
+
}
|
|
497
|
+
return this.writeString(value);
|
|
498
|
+
}
|
|
499
|
+
case CORE_TYPES.Vector: {
|
|
500
|
+
return this.writeVector(value);
|
|
501
|
+
}
|
|
502
|
+
case CORE_TYPES.Map: {
|
|
503
|
+
return this.writeMap(value);
|
|
504
|
+
}
|
|
399
505
|
}
|
|
400
|
-
return this
|
|
506
|
+
return this;
|
|
401
507
|
}
|
|
402
|
-
|
|
403
|
-
this.
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
this._last = this._last << 24 >> 24;
|
|
508
|
+
writeRepeat() {
|
|
509
|
+
if (!this._repeat) {
|
|
510
|
+
this.writeByte(CORE_TYPES.Repeat);
|
|
511
|
+
this._repeat = { count: 0, offset: this.offset };
|
|
407
512
|
}
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
* @returns {number}
|
|
413
|
-
*/
|
|
414
|
-
readFloat() {
|
|
415
|
-
this.assertRead(4);
|
|
416
|
-
int32[0] = this.readInt32();
|
|
417
|
-
this._last = float32[0];
|
|
418
|
-
return this._last;
|
|
513
|
+
this.offset = this._repeat.offset;
|
|
514
|
+
this._repeat.count++;
|
|
515
|
+
this.writeLength(this._repeat.count);
|
|
516
|
+
return this;
|
|
419
517
|
}
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
const CONSTRUCTOR_OPTIONAL = 1644261036;
|
|
521
|
+
const CONSTRUCTOR_OPTIONAL_NULL = 570519212;
|
|
522
|
+
const TYPE_HANDLERS = {
|
|
523
|
+
["unknown"]: {
|
|
524
|
+
encode: function(value, key) {
|
|
525
|
+
this.writeObject(value[key]);
|
|
526
|
+
},
|
|
527
|
+
decode: function(result, key) {
|
|
528
|
+
result[key] = this.readObject();
|
|
529
|
+
},
|
|
530
|
+
estimatedSizeBytes: 0
|
|
531
|
+
},
|
|
532
|
+
[CORE_TYPES.Map]: {
|
|
533
|
+
encode: function(value, key) {
|
|
534
|
+
this.writeMap(value[key]);
|
|
535
|
+
},
|
|
536
|
+
decode: function(result, key) {
|
|
537
|
+
result[key] = this.readMap(false);
|
|
538
|
+
},
|
|
539
|
+
estimatedSizeBytes: 0
|
|
540
|
+
},
|
|
541
|
+
[CORE_TYPES.Binary]: {
|
|
542
|
+
encode: function(value, key) {
|
|
543
|
+
this.writeBytes(value[key]);
|
|
544
|
+
},
|
|
545
|
+
decode: function(result, key) {
|
|
546
|
+
result[key] = this.readBytes();
|
|
547
|
+
},
|
|
548
|
+
estimatedSizeBytes: 0
|
|
549
|
+
},
|
|
550
|
+
[CORE_TYPES.Vector]: {
|
|
551
|
+
encode: function(value, key) {
|
|
552
|
+
this.writeVector(value[key]);
|
|
553
|
+
},
|
|
554
|
+
decode: function(result, key) {
|
|
555
|
+
result[key] = this.readVector(false);
|
|
556
|
+
},
|
|
557
|
+
estimatedSizeBytes: 0
|
|
558
|
+
},
|
|
559
|
+
[Boolean.name]: {
|
|
560
|
+
encode: function(value, key) {
|
|
561
|
+
this.writeBool(value[key]);
|
|
562
|
+
},
|
|
563
|
+
decode: function(result, key) {
|
|
564
|
+
result[key] = this.readBool();
|
|
565
|
+
},
|
|
566
|
+
estimatedSizeBytes: 1
|
|
567
|
+
},
|
|
568
|
+
[CORE_TYPES.Int8]: {
|
|
569
|
+
encode: function(value, key) {
|
|
570
|
+
this.writeInt8(value[key], true);
|
|
571
|
+
},
|
|
572
|
+
decode: function(result, key) {
|
|
573
|
+
result[key] = this.readInt8(true);
|
|
574
|
+
},
|
|
575
|
+
estimatedSizeBytes: 1
|
|
576
|
+
},
|
|
577
|
+
[CORE_TYPES.Int16]: {
|
|
578
|
+
encode: function(value, key) {
|
|
579
|
+
this.writeInt16(value[key], true);
|
|
580
|
+
},
|
|
581
|
+
decode: function(result, key) {
|
|
582
|
+
result[key] = this.readInt16(true);
|
|
583
|
+
},
|
|
584
|
+
estimatedSizeBytes: 2
|
|
585
|
+
},
|
|
586
|
+
[CORE_TYPES.Int32]: {
|
|
587
|
+
encode: function(value, key) {
|
|
588
|
+
this.writeInt32(value[key], true);
|
|
589
|
+
},
|
|
590
|
+
decode: function(result, key) {
|
|
591
|
+
result[key] = this.readInt32(true);
|
|
592
|
+
},
|
|
593
|
+
estimatedSizeBytes: 4
|
|
594
|
+
},
|
|
595
|
+
[CORE_TYPES.UInt8]: {
|
|
596
|
+
encode: function(value, key) {
|
|
597
|
+
this.writeInt8(value[key], false);
|
|
598
|
+
},
|
|
599
|
+
decode: function(result, key) {
|
|
600
|
+
result[key] = this.readInt8(false);
|
|
601
|
+
},
|
|
602
|
+
estimatedSizeBytes: 1
|
|
603
|
+
},
|
|
604
|
+
[CORE_TYPES.UInt16]: {
|
|
605
|
+
encode: function(value, key) {
|
|
606
|
+
this.writeInt16(value[key], false);
|
|
607
|
+
},
|
|
608
|
+
decode: function(result, key) {
|
|
609
|
+
result[key] = this.readInt16(false);
|
|
610
|
+
},
|
|
611
|
+
estimatedSizeBytes: 2
|
|
612
|
+
},
|
|
613
|
+
[CORE_TYPES.UInt32]: {
|
|
614
|
+
encode: function(value, key) {
|
|
615
|
+
this.writeInt32(value[key], false);
|
|
616
|
+
},
|
|
617
|
+
decode: function(result, key) {
|
|
618
|
+
result[key] = this.readInt32(false);
|
|
619
|
+
},
|
|
620
|
+
estimatedSizeBytes: 4
|
|
621
|
+
},
|
|
622
|
+
[CORE_TYPES.Double]: {
|
|
623
|
+
encode: function(value, key) {
|
|
624
|
+
this.writeDouble(value[key]);
|
|
625
|
+
},
|
|
626
|
+
decode: function(result, key) {
|
|
627
|
+
result[key] = this.readDouble();
|
|
628
|
+
},
|
|
629
|
+
estimatedSizeBytes: 8
|
|
630
|
+
},
|
|
631
|
+
[CORE_TYPES.Date]: {
|
|
632
|
+
encode: function(value, key) {
|
|
633
|
+
this.writeDate(value[key]);
|
|
634
|
+
},
|
|
635
|
+
decode: function(result, key) {
|
|
636
|
+
result[key] = this.readDate();
|
|
637
|
+
},
|
|
638
|
+
estimatedSizeBytes: 8
|
|
639
|
+
},
|
|
640
|
+
[CORE_TYPES.String]: {
|
|
641
|
+
encode: function(value, key) {
|
|
642
|
+
this.writeString(value[key]);
|
|
643
|
+
},
|
|
644
|
+
decode: function(result, key) {
|
|
645
|
+
result[key] = this.readString();
|
|
646
|
+
},
|
|
647
|
+
estimatedSizeBytes: 0
|
|
430
648
|
}
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
649
|
+
};
|
|
650
|
+
TYPE_HANDLERS[Number.name] = TYPE_HANDLERS[CORE_TYPES.Double];
|
|
651
|
+
TYPE_HANDLERS[String.name] = TYPE_HANDLERS[CORE_TYPES.String];
|
|
652
|
+
TYPE_HANDLERS[Object.name] = TYPE_HANDLERS[CORE_TYPES.Map];
|
|
653
|
+
TYPE_HANDLERS[Uint8Array.name] = TYPE_HANDLERS[CORE_TYPES.Binary];
|
|
654
|
+
TYPE_HANDLERS[Array.name] = TYPE_HANDLERS[CORE_TYPES.Vector];
|
|
655
|
+
TYPE_HANDLERS[Date.name] = TYPE_HANDLERS[CORE_TYPES.Date];
|
|
656
|
+
function compileStructure(name, version, properties, checksum) {
|
|
657
|
+
const encodeFns = [];
|
|
658
|
+
const decodeFns = [];
|
|
659
|
+
const structures = [];
|
|
660
|
+
const structureId = toolkit.crc32(name) >>> 0;
|
|
661
|
+
let estimatedSizeBytes = 1;
|
|
662
|
+
encodeFns.push(function() {
|
|
663
|
+
this.writeByte(version);
|
|
664
|
+
});
|
|
665
|
+
decodeFns.push(function() {
|
|
666
|
+
const ver = this.readByte();
|
|
667
|
+
toolkit.assert.ok(
|
|
668
|
+
version === ver,
|
|
669
|
+
`Structure ${structureId} version mismatch: expected ${version}, got ${ver}`
|
|
670
|
+
);
|
|
671
|
+
});
|
|
672
|
+
const entries = Object.entries(properties);
|
|
673
|
+
const entriesLength = entries.length;
|
|
674
|
+
for (let i = 0; i < entriesLength; i++) {
|
|
675
|
+
const [key, prop] = entries[i];
|
|
676
|
+
const isRequired = prop.required === true;
|
|
677
|
+
const isArray = Array.isArray(prop.type);
|
|
678
|
+
const propType = Array.isArray(prop.type) ? prop.type[0] : prop.type;
|
|
679
|
+
if (isStructureType(propType)) {
|
|
680
|
+
encodeFns.push(
|
|
681
|
+
createStructureEncoder(key, propType, isRequired, isArray)
|
|
441
682
|
);
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
const
|
|
449
|
-
if (
|
|
450
|
-
|
|
451
|
-
|
|
683
|
+
decodeFns.push(createStructureDecoder(key, isRequired, isArray));
|
|
684
|
+
estimatedSizeBytes += propType.estimatedSizeBytes;
|
|
685
|
+
structures.push(propType);
|
|
686
|
+
continue;
|
|
687
|
+
}
|
|
688
|
+
const typeName = propType?.name || (propType === null ? "unknown" : propType);
|
|
689
|
+
const handler = TYPE_HANDLERS[typeName];
|
|
690
|
+
if (handler) {
|
|
691
|
+
encodeFns.push(
|
|
692
|
+
createBoundEncoder(handler.encode, key, isRequired, isArray)
|
|
693
|
+
);
|
|
694
|
+
decodeFns.push(
|
|
695
|
+
createBoundDecoder(handler.decode, key, isRequired, isArray)
|
|
696
|
+
);
|
|
697
|
+
estimatedSizeBytes += handler.estimatedSizeBytes;
|
|
698
|
+
} else {
|
|
699
|
+
throw new Error(`Unsupported property type: ${typeName || "unknown"}`);
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
if (checksum) {
|
|
703
|
+
estimatedSizeBytes += 4;
|
|
704
|
+
encodeFns.push(function() {
|
|
705
|
+
this.writeChecksum(false);
|
|
706
|
+
});
|
|
707
|
+
decodeFns.push(function() {
|
|
708
|
+
this.readChecksum(false);
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
const compiled = {
|
|
712
|
+
id: structureId,
|
|
713
|
+
encodeFns,
|
|
714
|
+
decodeFns,
|
|
715
|
+
structures,
|
|
716
|
+
estimatedSizeBytes
|
|
717
|
+
};
|
|
718
|
+
return compiled;
|
|
719
|
+
}
|
|
720
|
+
function isStructureType(type) {
|
|
721
|
+
return type?.prototype && Structure.prototype.isPrototypeOf(type.prototype);
|
|
722
|
+
}
|
|
723
|
+
function createStructureEncoder(key, StructureCtor, isRequired, isArray) {
|
|
724
|
+
return function(value) {
|
|
725
|
+
const hasValue = value[key] !== void 0 && value[key] !== null;
|
|
726
|
+
if (!hasValue) {
|
|
727
|
+
toolkit.assert.ok(!isRequired, `Required property "${key}" is missing or null`);
|
|
728
|
+
if (value[key] === null) {
|
|
729
|
+
this.writeInt32(CONSTRUCTOR_OPTIONAL_NULL);
|
|
730
|
+
} else {
|
|
731
|
+
this.writeInt32(CONSTRUCTOR_OPTIONAL);
|
|
732
|
+
}
|
|
733
|
+
} else if (isArray) {
|
|
734
|
+
const arr = value[key];
|
|
735
|
+
toolkit.assert.array(arr, `Expected property "${key}" to be array.`);
|
|
736
|
+
this.writeLength(arr.length);
|
|
737
|
+
for (let idx = 0; idx < arr.length; idx++) {
|
|
738
|
+
this.writeStructure(
|
|
739
|
+
arr[idx] instanceof Structure ? arr[idx] : new StructureCtor(arr[idx])
|
|
740
|
+
);
|
|
741
|
+
}
|
|
742
|
+
} else {
|
|
743
|
+
this.writeStructure(
|
|
744
|
+
value[key] instanceof Structure ? value[key] : new StructureCtor(value[key])
|
|
452
745
|
);
|
|
453
746
|
}
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
}
|
|
466
|
-
throw new Error(`Invalid boolean code ${value.toString(16)}`);
|
|
467
|
-
}
|
|
468
|
-
readLength() {
|
|
469
|
-
const firstByte = this.readByte();
|
|
470
|
-
if (firstByte === 254) {
|
|
471
|
-
return this.readByte() | this.readByte() << 8 | this.readByte() << 16;
|
|
747
|
+
};
|
|
748
|
+
}
|
|
749
|
+
function createStructureDecoder(key, isRequired, isArray) {
|
|
750
|
+
return function(result) {
|
|
751
|
+
let shouldRead = true;
|
|
752
|
+
if (!isRequired) {
|
|
753
|
+
shouldRead = !readMaybeInt32(this, CONSTRUCTOR_OPTIONAL);
|
|
754
|
+
if (shouldRead && readMaybeInt32(this, CONSTRUCTOR_OPTIONAL_NULL)) {
|
|
755
|
+
result[key] = null;
|
|
756
|
+
return;
|
|
757
|
+
}
|
|
472
758
|
}
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
759
|
+
if (shouldRead) {
|
|
760
|
+
if (isArray) {
|
|
761
|
+
const length = this.readLength();
|
|
762
|
+
const arrResult = Array.from({ length });
|
|
763
|
+
for (let idx = 0; idx < length; idx++) {
|
|
764
|
+
arrResult[idx] = this.readStructure(false);
|
|
765
|
+
}
|
|
766
|
+
result[key] = arrResult;
|
|
767
|
+
} else {
|
|
768
|
+
result[key] = this.readStructure(false);
|
|
769
|
+
}
|
|
479
770
|
}
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
return bytes;
|
|
489
|
-
}
|
|
490
|
-
/**
|
|
491
|
-
* Reads encoded string.
|
|
492
|
-
*/
|
|
493
|
-
readString() {
|
|
494
|
-
const length = this.readLength();
|
|
495
|
-
this.assertRead(length);
|
|
496
|
-
const result = utf8Read(this.target, length, this.offset);
|
|
497
|
-
this.offset += length;
|
|
498
|
-
this._last = result;
|
|
499
|
-
return result;
|
|
500
|
-
}
|
|
501
|
-
/**
|
|
502
|
-
* Reads a boolean value.
|
|
503
|
-
*/
|
|
504
|
-
readBool() {
|
|
505
|
-
const value = this.readByte();
|
|
506
|
-
if (value === CORE_TYPES.BoolTrue) {
|
|
507
|
-
return true;
|
|
508
|
-
} else if (value === CORE_TYPES.BoolFalse) {
|
|
509
|
-
return false;
|
|
510
|
-
} else {
|
|
511
|
-
throw new Error(`Invalid boolean code ${value.toString(16)}`);
|
|
771
|
+
};
|
|
772
|
+
}
|
|
773
|
+
function readMaybeInt32(reader, expectedValue) {
|
|
774
|
+
let result = false;
|
|
775
|
+
if (reader.length >= reader.offset + 4) {
|
|
776
|
+
result = reader.readInt32() === expectedValue;
|
|
777
|
+
if (!result) {
|
|
778
|
+
reader.offset -= 4;
|
|
512
779
|
}
|
|
513
780
|
}
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
* Reads a object.
|
|
524
|
-
*/
|
|
525
|
-
readObject() {
|
|
526
|
-
if (this._repeat) {
|
|
527
|
-
if (this._repeat.pool > 0) {
|
|
528
|
-
--this._repeat.pool;
|
|
529
|
-
return this._repeat.value;
|
|
781
|
+
return result;
|
|
782
|
+
}
|
|
783
|
+
function createBoundEncoder(encodeFn, key, isRequired, isArray) {
|
|
784
|
+
return function(value) {
|
|
785
|
+
const hasValue = value[key] !== void 0 && value[key] !== null;
|
|
786
|
+
if (!hasValue) {
|
|
787
|
+
toolkit.assert.ok(!isRequired, `Required property "${key}" is missing or null`);
|
|
788
|
+
if (value[key] === null) {
|
|
789
|
+
this.writeInt32(CONSTRUCTOR_OPTIONAL_NULL);
|
|
530
790
|
} else {
|
|
531
|
-
this.
|
|
791
|
+
this.writeInt32(CONSTRUCTOR_OPTIONAL);
|
|
792
|
+
}
|
|
793
|
+
} else if (isArray) {
|
|
794
|
+
const arr = value[key];
|
|
795
|
+
toolkit.assert.array(arr, `Expected property "${key}" to be array.`);
|
|
796
|
+
this.writeLength(arr.length);
|
|
797
|
+
for (let idx = 0; idx < arr.length; idx++) {
|
|
798
|
+
encodeFn.call(this, arr, idx);
|
|
532
799
|
}
|
|
533
|
-
}
|
|
534
|
-
const constructorId = this.readByte();
|
|
535
|
-
const ext = this.extensions.get(constructorId);
|
|
536
|
-
let value;
|
|
537
|
-
if (ext) {
|
|
538
|
-
value = ext.decode.call(this);
|
|
539
800
|
} else {
|
|
540
|
-
|
|
801
|
+
encodeFn.call(this, value, key);
|
|
541
802
|
}
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
readGzip() {
|
|
553
|
-
return pako__default.inflateRaw(this.readBytes());
|
|
554
|
-
}
|
|
555
|
-
readCore(constructorId) {
|
|
556
|
-
switch (constructorId) {
|
|
557
|
-
case CORE_TYPES.None:
|
|
558
|
-
return this.readObject();
|
|
559
|
-
case CORE_TYPES.GZIP:
|
|
560
|
-
return this.readObjectGzip();
|
|
561
|
-
case CORE_TYPES.BoolTrue:
|
|
562
|
-
return true;
|
|
563
|
-
case CORE_TYPES.BoolFalse:
|
|
564
|
-
return false;
|
|
565
|
-
case CORE_TYPES.Vector:
|
|
566
|
-
return this.readVector(false);
|
|
567
|
-
case CORE_TYPES.VectorDynamic:
|
|
568
|
-
return this.readVectorDynamic(false);
|
|
569
|
-
case CORE_TYPES.Null:
|
|
570
|
-
return null;
|
|
571
|
-
case CORE_TYPES.Binary:
|
|
572
|
-
return this.readBytes();
|
|
573
|
-
case CORE_TYPES.String:
|
|
574
|
-
return this.readString();
|
|
575
|
-
case CORE_TYPES.Date:
|
|
576
|
-
return this.readDate();
|
|
577
|
-
case CORE_TYPES.Int32:
|
|
578
|
-
return this.readInt32();
|
|
579
|
-
case CORE_TYPES.Int16:
|
|
580
|
-
return this.readInt16();
|
|
581
|
-
case CORE_TYPES.Int8:
|
|
582
|
-
return this.readInt8();
|
|
583
|
-
case CORE_TYPES.UInt32:
|
|
584
|
-
return this.readInt32(false);
|
|
585
|
-
case CORE_TYPES.UInt16:
|
|
586
|
-
return this.readInt16(false);
|
|
587
|
-
case CORE_TYPES.UInt8:
|
|
588
|
-
return this.readInt8(false);
|
|
589
|
-
case CORE_TYPES.Float:
|
|
590
|
-
return this.readFloat();
|
|
591
|
-
case CORE_TYPES.Double:
|
|
592
|
-
return this.readDouble();
|
|
593
|
-
case CORE_TYPES.Map:
|
|
594
|
-
return this.readMap(false);
|
|
595
|
-
case CORE_TYPES.Checksum:
|
|
596
|
-
return void this.readChecksum(false);
|
|
597
|
-
case CORE_TYPES.DictIndex: {
|
|
598
|
-
const idx = this.readLength();
|
|
599
|
-
return this.getDictionaryValue(idx);
|
|
803
|
+
};
|
|
804
|
+
}
|
|
805
|
+
function createBoundDecoder(decodeFn, key, isRequired, isArray) {
|
|
806
|
+
return function(result) {
|
|
807
|
+
let shouldRead = true;
|
|
808
|
+
if (!isRequired) {
|
|
809
|
+
shouldRead = !readMaybeInt32(this, CONSTRUCTOR_OPTIONAL);
|
|
810
|
+
if (shouldRead && readMaybeInt32(this, CONSTRUCTOR_OPTIONAL_NULL)) {
|
|
811
|
+
result[key] = null;
|
|
812
|
+
return;
|
|
600
813
|
}
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
814
|
+
}
|
|
815
|
+
if (shouldRead) {
|
|
816
|
+
if (isArray) {
|
|
817
|
+
const length = this.readLength();
|
|
818
|
+
const arrResult = Array.from({ length });
|
|
819
|
+
for (let idx = 0; idx < length; idx++) {
|
|
820
|
+
decodeFn.call(this, arrResult, idx);
|
|
821
|
+
}
|
|
822
|
+
result[key] = arrResult;
|
|
823
|
+
} else {
|
|
824
|
+
decodeFn.call(this, result, key);
|
|
605
825
|
}
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
826
|
+
}
|
|
827
|
+
};
|
|
828
|
+
}
|
|
829
|
+
function defineStructure({
|
|
830
|
+
name,
|
|
831
|
+
properties,
|
|
832
|
+
version,
|
|
833
|
+
checksum = false
|
|
834
|
+
}) {
|
|
835
|
+
const compiled = compileStructure(name, version, properties, checksum);
|
|
836
|
+
return class DefinedStructure extends Structure {
|
|
837
|
+
static estimatedSizeBytes = compiled.estimatedSizeBytes;
|
|
838
|
+
static structures = compiled.structures;
|
|
839
|
+
static extension = {
|
|
840
|
+
token: compiled.id,
|
|
841
|
+
encode(value) {
|
|
842
|
+
const fns = compiled.encodeFns;
|
|
843
|
+
const length = fns.length;
|
|
844
|
+
for (let i = 0; i < length; i++) {
|
|
845
|
+
fns[i].call(this, value);
|
|
846
|
+
}
|
|
847
|
+
},
|
|
848
|
+
decode() {
|
|
849
|
+
const result = {};
|
|
850
|
+
const fns = compiled.decodeFns;
|
|
851
|
+
const length = fns.length;
|
|
852
|
+
for (let i = 0; i < length; i++) {
|
|
853
|
+
fns[i].call(this, result);
|
|
854
|
+
}
|
|
855
|
+
return result;
|
|
610
856
|
}
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
857
|
+
};
|
|
858
|
+
};
|
|
859
|
+
}
|
|
860
|
+
class Structure {
|
|
861
|
+
value;
|
|
862
|
+
constructor(value) {
|
|
863
|
+
this.value = value;
|
|
864
|
+
}
|
|
865
|
+
toBuffer(options) {
|
|
866
|
+
const ctor = this.constructor;
|
|
867
|
+
const writer = new BinaryWriter(options);
|
|
868
|
+
ctor.extension.encode.call(writer, this.value);
|
|
869
|
+
return writer.getBuffer();
|
|
870
|
+
}
|
|
871
|
+
static fromBuffer(buffer, options = {}) {
|
|
872
|
+
const reader = new BinaryReader(buffer, {
|
|
873
|
+
...options,
|
|
874
|
+
structures: options.structures ? this.structures.concat(options.structures) : this.structures
|
|
875
|
+
});
|
|
876
|
+
return this.extension.decode.call(reader);
|
|
877
|
+
}
|
|
878
|
+
static estimatedSizeBytes = -1;
|
|
879
|
+
static structures = [];
|
|
880
|
+
static extension = {
|
|
881
|
+
token: CORE_TYPES.Binary,
|
|
882
|
+
encode: toolkit.noop,
|
|
883
|
+
decode: toolkit.noop
|
|
884
|
+
};
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
const encoder = new TextEncoder();
|
|
888
|
+
const decoder = new TextDecoder();
|
|
889
|
+
const fromCharCode = String.fromCharCode;
|
|
890
|
+
const int32 = new Int32Array(2);
|
|
891
|
+
const float32 = new Float32Array(int32.buffer);
|
|
892
|
+
const float64 = new Float64Array(int32.buffer);
|
|
893
|
+
function byteArrayAllocate(length) {
|
|
894
|
+
return new Uint8Array(length);
|
|
895
|
+
}
|
|
896
|
+
function coreType(value) {
|
|
897
|
+
if (value instanceof Structure) {
|
|
898
|
+
return CORE_TYPES.Structure;
|
|
899
|
+
} else if (value instanceof Uint8Array) {
|
|
900
|
+
return CORE_TYPES.Binary;
|
|
615
901
|
}
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
value = this.dictionary.getValue(index);
|
|
902
|
+
switch (typeof value) {
|
|
903
|
+
case "string": {
|
|
904
|
+
return CORE_TYPES.String;
|
|
620
905
|
}
|
|
621
|
-
|
|
622
|
-
value
|
|
906
|
+
case "boolean": {
|
|
907
|
+
return value ? CORE_TYPES.BoolTrue : CORE_TYPES.BoolFalse;
|
|
623
908
|
}
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
909
|
+
case "number": {
|
|
910
|
+
if (Math.trunc(value) === value) {
|
|
911
|
+
if (value >= 0 && value <= 255) {
|
|
912
|
+
return CORE_TYPES.UInt8;
|
|
913
|
+
} else if (value >= 0 && value <= 65535) {
|
|
914
|
+
return CORE_TYPES.UInt16;
|
|
915
|
+
} else if (value >= 0 && value <= 4294967295) {
|
|
916
|
+
return CORE_TYPES.UInt32;
|
|
917
|
+
} else if (value >= -128 && value <= 127) {
|
|
918
|
+
return CORE_TYPES.Int8;
|
|
919
|
+
} else if (value >= -32768 && value <= 32767) {
|
|
920
|
+
return CORE_TYPES.Int16;
|
|
921
|
+
} else if (value >= -2147483648 && value <= 2147483647) {
|
|
922
|
+
return CORE_TYPES.Int32;
|
|
923
|
+
}
|
|
634
924
|
}
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
925
|
+
return CORE_TYPES.Double;
|
|
926
|
+
}
|
|
927
|
+
case "object": {
|
|
928
|
+
if (value === null) return CORE_TYPES.Null;
|
|
929
|
+
if (value instanceof Date) {
|
|
930
|
+
return CORE_TYPES.Date;
|
|
639
931
|
}
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
break;
|
|
932
|
+
if (Array.isArray(value)) {
|
|
933
|
+
return CORE_TYPES.Vector;
|
|
643
934
|
}
|
|
644
|
-
|
|
645
|
-
|
|
935
|
+
if (toolkit.isPlainObject(value)) {
|
|
936
|
+
return CORE_TYPES.Map;
|
|
646
937
|
}
|
|
647
938
|
}
|
|
648
|
-
return key;
|
|
649
939
|
}
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
940
|
+
return CORE_TYPES.None;
|
|
941
|
+
}
|
|
942
|
+
function utf8Read(target, length, offset) {
|
|
943
|
+
let result;
|
|
944
|
+
if (length < 16) {
|
|
945
|
+
if (result = utf8ReadShort(target, length, offset)) return result;
|
|
946
|
+
}
|
|
947
|
+
if (length > 64 && decoder)
|
|
948
|
+
return decoder.decode(target.subarray(offset, offset += length));
|
|
949
|
+
const end = offset + length;
|
|
950
|
+
const units = [];
|
|
951
|
+
result = "";
|
|
952
|
+
while (offset < end) {
|
|
953
|
+
const byte1 = target[offset++];
|
|
954
|
+
if ((byte1 & 128) === 0) {
|
|
955
|
+
units.push(byte1);
|
|
956
|
+
} else if ((byte1 & 224) === 192) {
|
|
957
|
+
const byte2 = target[offset++] & 63;
|
|
958
|
+
units.push((byte1 & 31) << 6 | byte2);
|
|
959
|
+
} else if ((byte1 & 240) === 224) {
|
|
960
|
+
const byte2 = target[offset++] & 63;
|
|
961
|
+
const byte3 = target[offset++] & 63;
|
|
962
|
+
units.push((byte1 & 31) << 12 | byte2 << 6 | byte3);
|
|
963
|
+
} else if ((byte1 & 248) === 240) {
|
|
964
|
+
const byte2 = target[offset++] & 63;
|
|
965
|
+
const byte3 = target[offset++] & 63;
|
|
966
|
+
const byte4 = target[offset++] & 63;
|
|
967
|
+
let unit = (byte1 & 7) << 18 | byte2 << 12 | byte3 << 6 | byte4;
|
|
968
|
+
if (unit > 65535) {
|
|
969
|
+
unit -= 65536;
|
|
970
|
+
units.push(unit >>> 10 & 1023 | 55296);
|
|
971
|
+
unit = 56320 | unit & 1023;
|
|
972
|
+
}
|
|
973
|
+
units.push(unit);
|
|
974
|
+
} else {
|
|
975
|
+
units.push(byte1);
|
|
653
976
|
}
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
temp[key] = this.readObject();
|
|
658
|
-
key = this.readDictionary();
|
|
977
|
+
if (units.length >= 4096) {
|
|
978
|
+
result += fromCharCode.apply(String, units);
|
|
979
|
+
units.length = 0;
|
|
659
980
|
}
|
|
660
|
-
return temp;
|
|
661
981
|
}
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
this._last = void 0;
|
|
665
|
-
this._lastObject = void 0;
|
|
666
|
-
this._repeat = void 0;
|
|
667
|
-
this.offset = 0;
|
|
668
|
-
this._checksumOffset = 0;
|
|
669
|
-
this.length = value.length;
|
|
670
|
-
return this.readObject();
|
|
982
|
+
if (units.length > 0) {
|
|
983
|
+
result += fromCharCode.apply(String, units);
|
|
671
984
|
}
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
if (
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
985
|
+
return result;
|
|
986
|
+
}
|
|
987
|
+
function utf8ReadShort(target, length, offset) {
|
|
988
|
+
if (length < 4) {
|
|
989
|
+
if (length < 2) {
|
|
990
|
+
if (length === 0) return "";
|
|
991
|
+
else {
|
|
992
|
+
let a = target[offset++];
|
|
993
|
+
if ((a & 128) > 1) {
|
|
994
|
+
offset -= 1;
|
|
995
|
+
return;
|
|
996
|
+
}
|
|
997
|
+
return fromCharCode(a);
|
|
998
|
+
}
|
|
999
|
+
} else {
|
|
1000
|
+
let a = target[offset++];
|
|
1001
|
+
let b = target[offset++];
|
|
1002
|
+
if ((a & 128) > 0 || (b & 128) > 0) {
|
|
1003
|
+
offset -= 2;
|
|
1004
|
+
return;
|
|
1005
|
+
}
|
|
1006
|
+
if (length < 3) return fromCharCode(a, b);
|
|
1007
|
+
let c = target[offset++];
|
|
1008
|
+
if ((c & 128) > 0) {
|
|
1009
|
+
offset -= 3;
|
|
1010
|
+
return;
|
|
1011
|
+
}
|
|
1012
|
+
return fromCharCode(a, b, c);
|
|
683
1013
|
}
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
1014
|
+
} else {
|
|
1015
|
+
let a = target[offset++];
|
|
1016
|
+
let b = target[offset++];
|
|
1017
|
+
let c = target[offset++];
|
|
1018
|
+
let d = target[offset++];
|
|
1019
|
+
if ((a & 128) > 0 || (b & 128) > 0 || (c & 128) > 0 || (d & 128) > 0) {
|
|
1020
|
+
offset -= 4;
|
|
1021
|
+
return;
|
|
692
1022
|
}
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
1023
|
+
if (length < 6) {
|
|
1024
|
+
if (length === 4) return fromCharCode(a, b, c, d);
|
|
1025
|
+
else {
|
|
1026
|
+
let e = target[offset++];
|
|
1027
|
+
if ((e & 128) > 0) {
|
|
1028
|
+
offset -= 5;
|
|
1029
|
+
return;
|
|
1030
|
+
}
|
|
1031
|
+
return fromCharCode(a, b, c, d, e);
|
|
700
1032
|
}
|
|
701
|
-
|
|
702
|
-
let
|
|
703
|
-
|
|
704
|
-
|
|
1033
|
+
} else if (length < 8) {
|
|
1034
|
+
let e = target[offset++];
|
|
1035
|
+
let f = target[offset++];
|
|
1036
|
+
if ((e & 128) > 0 || (f & 128) > 0) {
|
|
1037
|
+
offset -= 6;
|
|
1038
|
+
return;
|
|
1039
|
+
}
|
|
1040
|
+
if (length < 7) return fromCharCode(a, b, c, d, e, f);
|
|
1041
|
+
let g = target[offset++];
|
|
1042
|
+
if ((g & 128) > 0) {
|
|
1043
|
+
offset -= 7;
|
|
1044
|
+
return;
|
|
1045
|
+
}
|
|
1046
|
+
return fromCharCode(a, b, c, d, e, f, g);
|
|
1047
|
+
} else {
|
|
1048
|
+
let e = target[offset++];
|
|
1049
|
+
let f = target[offset++];
|
|
1050
|
+
let g = target[offset++];
|
|
1051
|
+
let h = target[offset++];
|
|
1052
|
+
if ((e & 128) > 0 || (f & 128) > 0 || (g & 128) > 0 || (h & 128) > 0) {
|
|
1053
|
+
offset -= 8;
|
|
1054
|
+
return;
|
|
1055
|
+
}
|
|
1056
|
+
if (length < 10) {
|
|
1057
|
+
if (length === 8) return fromCharCode(a, b, c, d, e, f, g, h);
|
|
1058
|
+
else {
|
|
1059
|
+
let i = target[offset++];
|
|
1060
|
+
if ((i & 128) > 0) {
|
|
1061
|
+
offset -= 9;
|
|
1062
|
+
return;
|
|
1063
|
+
}
|
|
1064
|
+
return fromCharCode(a, b, c, d, e, f, g, h, i);
|
|
1065
|
+
}
|
|
1066
|
+
} else if (length < 12) {
|
|
1067
|
+
let i = target[offset++];
|
|
1068
|
+
let j = target[offset++];
|
|
1069
|
+
if ((i & 128) > 0 || (j & 128) > 0) {
|
|
1070
|
+
offset -= 10;
|
|
1071
|
+
return;
|
|
1072
|
+
}
|
|
1073
|
+
if (length < 11) return fromCharCode(a, b, c, d, e, f, g, h, i, j);
|
|
1074
|
+
let k = target[offset++];
|
|
1075
|
+
if ((k & 128) > 0) {
|
|
1076
|
+
offset -= 11;
|
|
1077
|
+
return;
|
|
1078
|
+
}
|
|
1079
|
+
return fromCharCode(a, b, c, d, e, f, g, h, i, j, k);
|
|
705
1080
|
} else {
|
|
706
|
-
|
|
1081
|
+
let i = target[offset++];
|
|
1082
|
+
let j = target[offset++];
|
|
1083
|
+
let k = target[offset++];
|
|
1084
|
+
let l = target[offset++];
|
|
1085
|
+
if ((i & 128) > 0 || (j & 128) > 0 || (k & 128) > 0 || (l & 128) > 0) {
|
|
1086
|
+
offset -= 12;
|
|
1087
|
+
return;
|
|
1088
|
+
}
|
|
1089
|
+
if (length < 14) {
|
|
1090
|
+
if (length === 12)
|
|
1091
|
+
return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l);
|
|
1092
|
+
else {
|
|
1093
|
+
let m = target[offset++];
|
|
1094
|
+
if ((m & 128) > 0) {
|
|
1095
|
+
offset -= 13;
|
|
1096
|
+
return;
|
|
1097
|
+
}
|
|
1098
|
+
return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m);
|
|
1099
|
+
}
|
|
1100
|
+
} else {
|
|
1101
|
+
let m = target[offset++];
|
|
1102
|
+
let n = target[offset++];
|
|
1103
|
+
if ((m & 128) > 0 || (n & 128) > 0) {
|
|
1104
|
+
offset -= 14;
|
|
1105
|
+
return;
|
|
1106
|
+
}
|
|
1107
|
+
if (length < 15)
|
|
1108
|
+
return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m, n);
|
|
1109
|
+
let o = target[offset++];
|
|
1110
|
+
if ((o & 128) > 0) {
|
|
1111
|
+
offset -= 15;
|
|
1112
|
+
return;
|
|
1113
|
+
}
|
|
1114
|
+
return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o);
|
|
1115
|
+
}
|
|
707
1116
|
}
|
|
708
|
-
temp.push(value);
|
|
709
|
-
}
|
|
710
|
-
if (!complete) {
|
|
711
|
-
const err = new Error(`DynamicVector incomplete.`);
|
|
712
|
-
err.incomplete = true;
|
|
713
|
-
Error.captureStackTrace(err, this.readDictionary);
|
|
714
|
-
throw err;
|
|
715
1117
|
}
|
|
716
|
-
this._last = temp;
|
|
717
|
-
return temp;
|
|
718
1118
|
}
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
if (
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
1119
|
+
}
|
|
1120
|
+
const utf8Write = function(target, value, offset) {
|
|
1121
|
+
return value.length < 64 ? utf8WriteShort(target, value, offset) : encoder.encodeInto(value, target.subarray(offset)).written;
|
|
1122
|
+
};
|
|
1123
|
+
const utf8WriteShort = (target, value, offset) => {
|
|
1124
|
+
let i, c1, c2, strPosition = offset;
|
|
1125
|
+
const strLength = value.length;
|
|
1126
|
+
for (i = 0; i < strLength; i++) {
|
|
1127
|
+
c1 = value.charCodeAt(i);
|
|
1128
|
+
if (c1 < 128) {
|
|
1129
|
+
target[strPosition++] = c1;
|
|
1130
|
+
} else if (c1 < 2048) {
|
|
1131
|
+
target[strPosition++] = c1 >> 6 | 192;
|
|
1132
|
+
target[strPosition++] = c1 & 63 | 128;
|
|
1133
|
+
} else if ((c1 & 64512) === 55296 && ((c2 = value.charCodeAt(i + 1)) & 64512) === 56320) {
|
|
1134
|
+
c1 = 65536 + ((c1 & 1023) << 10) + (c2 & 1023);
|
|
1135
|
+
i++;
|
|
1136
|
+
target[strPosition++] = c1 >> 18 | 240;
|
|
1137
|
+
target[strPosition++] = c1 >> 12 & 63 | 128;
|
|
1138
|
+
target[strPosition++] = c1 >> 6 & 63 | 128;
|
|
1139
|
+
target[strPosition++] = c1 & 63 | 128;
|
|
1140
|
+
} else {
|
|
1141
|
+
target[strPosition++] = c1 >> 12 | 224;
|
|
1142
|
+
target[strPosition++] = c1 >> 6 & 63 | 128;
|
|
1143
|
+
target[strPosition++] = c1 & 63 | 128;
|
|
734
1144
|
}
|
|
735
|
-
this._checksumOffset = this.offset;
|
|
736
|
-
}
|
|
737
|
-
/**
|
|
738
|
-
* Tells the current position on the stream.
|
|
739
|
-
*/
|
|
740
|
-
tellPosition() {
|
|
741
|
-
return this.offset;
|
|
742
|
-
}
|
|
743
|
-
/**
|
|
744
|
-
* Sets the current position on the stream.
|
|
745
|
-
*/
|
|
746
|
-
setPosition(position) {
|
|
747
|
-
this.offset = position;
|
|
748
|
-
}
|
|
749
|
-
/**
|
|
750
|
-
* Seeks the stream position given an offset from the current position.
|
|
751
|
-
* The offset may be negative.
|
|
752
|
-
*/
|
|
753
|
-
seek(offset) {
|
|
754
|
-
this.offset += offset;
|
|
755
1145
|
}
|
|
756
|
-
|
|
1146
|
+
return strPosition - offset;
|
|
1147
|
+
};
|
|
757
1148
|
|
|
758
|
-
const
|
|
759
|
-
|
|
760
|
-
CORE_TYPES.BoolFalse,
|
|
761
|
-
CORE_TYPES.BoolTrue,
|
|
762
|
-
CORE_TYPES.Null
|
|
763
|
-
]);
|
|
764
|
-
const SUPPORT_COMPRESSION = /* @__PURE__ */ new Set([CORE_TYPES.String]);
|
|
765
|
-
class BinaryWriter {
|
|
766
|
-
withGzip;
|
|
1149
|
+
const NOOP_DICTIONARY = new Dictionary();
|
|
1150
|
+
class BinaryReader {
|
|
767
1151
|
target;
|
|
1152
|
+
_last;
|
|
1153
|
+
_lastObject;
|
|
768
1154
|
dictionary;
|
|
769
1155
|
dictionaryExtended;
|
|
770
1156
|
extensions;
|
|
771
|
-
|
|
772
|
-
_checksumOffset;
|
|
1157
|
+
structures;
|
|
773
1158
|
_repeat;
|
|
1159
|
+
_checksumOffset;
|
|
774
1160
|
offset;
|
|
775
|
-
|
|
1161
|
+
length;
|
|
1162
|
+
/**
|
|
1163
|
+
* Small utility class to read binary data.
|
|
1164
|
+
*/
|
|
1165
|
+
constructor(data, {
|
|
1166
|
+
dictionary = NOOP_DICTIONARY,
|
|
1167
|
+
extensions,
|
|
1168
|
+
structures
|
|
1169
|
+
} = {}) {
|
|
1170
|
+
this.target = data;
|
|
776
1171
|
this.offset = 0;
|
|
777
1172
|
this._checksumOffset = 0;
|
|
1173
|
+
this.length = data.length;
|
|
778
1174
|
this.extensions = /* @__PURE__ */ new Map();
|
|
779
|
-
this.
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
options.extensions.forEach((ext) => {
|
|
1175
|
+
this.structures = /* @__PURE__ */ new Map();
|
|
1176
|
+
if (extensions) {
|
|
1177
|
+
for (const ext of extensions) {
|
|
783
1178
|
this.extensions.set(ext.token, ext);
|
|
784
|
-
}
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
if (structures) {
|
|
1182
|
+
for (const struct of structures) {
|
|
1183
|
+
this.structures.set(struct.extension.token, struct);
|
|
1184
|
+
}
|
|
785
1185
|
}
|
|
786
|
-
if (
|
|
787
|
-
this.dictionary = new Dictionary();
|
|
788
|
-
} else if (options.dictionary instanceof Dictionary) {
|
|
789
|
-
this.dictionary = options.dictionary;
|
|
790
|
-
} else if (Array.isArray(options.dictionary)) {
|
|
791
|
-
this.dictionary = new Dictionary(options.dictionary);
|
|
1186
|
+
if (Array.isArray(dictionary)) {
|
|
1187
|
+
this.dictionary = new Dictionary(dictionary);
|
|
792
1188
|
} else {
|
|
793
|
-
this.dictionary =
|
|
1189
|
+
this.dictionary = dictionary;
|
|
794
1190
|
}
|
|
795
1191
|
this.dictionaryExtended = new Dictionary(void 0, this.dictionary.size);
|
|
796
1192
|
}
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
1193
|
+
readByte() {
|
|
1194
|
+
this.assertRead(1);
|
|
1195
|
+
this._last = this.target[this.offset++];
|
|
1196
|
+
return this._last;
|
|
1197
|
+
}
|
|
1198
|
+
readInt32(signed = true) {
|
|
1199
|
+
this.assertRead(4);
|
|
1200
|
+
this._last = this.target[this.offset++] | this.target[this.offset++] << 8 | this.target[this.offset++] << 16 | this.target[this.offset++] << 24;
|
|
1201
|
+
if (!signed) {
|
|
1202
|
+
this._last = this._last >>> 0;
|
|
801
1203
|
}
|
|
802
|
-
return this;
|
|
1204
|
+
return this._last;
|
|
803
1205
|
}
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
if (end - start > MAX_BUFFER_SIZE)
|
|
810
|
-
throw new Error(
|
|
811
|
-
"Packed buffer would be larger than maximum buffer size"
|
|
812
|
-
);
|
|
813
|
-
newSize = Math.min(
|
|
814
|
-
MAX_BUFFER_SIZE,
|
|
815
|
-
Math.round(
|
|
816
|
-
Math.max((end - start) * (end > 67108864 ? 1.25 : 2), 4194304) / 4096
|
|
817
|
-
) * 4096
|
|
818
|
-
);
|
|
819
|
-
} else {
|
|
820
|
-
newSize = (Math.max(end - start << 2, target.length - 1) >> 12) + 1 << 12;
|
|
1206
|
+
readInt16(signed = true) {
|
|
1207
|
+
this.assertRead(2);
|
|
1208
|
+
this._last = this.target[this.offset++] | this.target[this.offset++] << 8;
|
|
1209
|
+
if (signed) {
|
|
1210
|
+
this._last = this._last << 16 >> 16;
|
|
821
1211
|
}
|
|
822
|
-
|
|
823
|
-
end = Math.min(end, target.length);
|
|
824
|
-
newBuffer.set(target.slice(start, end));
|
|
825
|
-
this.target = newBuffer;
|
|
1212
|
+
return this._last;
|
|
826
1213
|
}
|
|
827
|
-
|
|
828
|
-
|
|
1214
|
+
readInt8(signed = true) {
|
|
1215
|
+
this.assertRead(1);
|
|
1216
|
+
this._last = this.target[this.offset++];
|
|
1217
|
+
if (signed) {
|
|
1218
|
+
this._last = this._last << 24 >> 24;
|
|
1219
|
+
}
|
|
1220
|
+
return this._last;
|
|
829
1221
|
}
|
|
830
|
-
|
|
831
|
-
|
|
1222
|
+
/**
|
|
1223
|
+
* Reads a real floating point (4 bytes) value.
|
|
1224
|
+
* @returns {number}
|
|
1225
|
+
*/
|
|
1226
|
+
readFloat() {
|
|
1227
|
+
this.assertRead(4);
|
|
1228
|
+
int32[0] = this.readInt32();
|
|
1229
|
+
this._last = float32[0];
|
|
1230
|
+
return this._last;
|
|
832
1231
|
}
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
1232
|
+
/**
|
|
1233
|
+
* Reads a real floating point (8 bytes) value.
|
|
1234
|
+
* @returns {BigInteger}
|
|
1235
|
+
*/
|
|
1236
|
+
readDouble() {
|
|
1237
|
+
this.assertRead(8);
|
|
1238
|
+
int32[0] = this.readInt32();
|
|
1239
|
+
int32[1] = this.readInt32();
|
|
1240
|
+
this._last = float64[0];
|
|
1241
|
+
return this._last;
|
|
837
1242
|
}
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
1243
|
+
/**
|
|
1244
|
+
* Throws error if provided length cannot be read from buffer
|
|
1245
|
+
* @param length {number}
|
|
1246
|
+
*/
|
|
1247
|
+
assertRead(length) {
|
|
1248
|
+
if (this.length < this.offset + +length) {
|
|
1249
|
+
const left = this.target.length - this.offset;
|
|
1250
|
+
const result = this.target.subarray(this.offset, this.offset + left);
|
|
1251
|
+
const err = new Error(
|
|
1252
|
+
`No more data left to read (need ${length}, got ${left}: ${result}); last read ${this._last}`
|
|
1253
|
+
);
|
|
1254
|
+
err.incomplete = true;
|
|
1255
|
+
Error.captureStackTrace(err, this.assertRead);
|
|
1256
|
+
throw err;
|
|
843
1257
|
}
|
|
844
|
-
return this;
|
|
845
1258
|
}
|
|
846
|
-
|
|
847
|
-
this.
|
|
848
|
-
|
|
1259
|
+
assertConstructor(constructorId) {
|
|
1260
|
+
const byte = this.readByte();
|
|
1261
|
+
if (byte !== constructorId) {
|
|
1262
|
+
throw new Error(
|
|
1263
|
+
`Invalid constructor code, expected = ${CORE_TYPES[constructorId]}, got = ${CORE_TYPES[byte] || byte}, offset = ${this.offset - 1}`
|
|
1264
|
+
);
|
|
1265
|
+
}
|
|
849
1266
|
}
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
this.target[this.offset++] = value >> 16;
|
|
861
|
-
this.target[this.offset++] = value >> 24;
|
|
1267
|
+
/**
|
|
1268
|
+
* Gets the byte array representing the current buffer as a whole.
|
|
1269
|
+
*/
|
|
1270
|
+
getBuffer() {
|
|
1271
|
+
return this.target;
|
|
1272
|
+
}
|
|
1273
|
+
readNull() {
|
|
1274
|
+
const value = this.readByte();
|
|
1275
|
+
if (value === CORE_TYPES.Null) {
|
|
1276
|
+
return null;
|
|
862
1277
|
}
|
|
863
|
-
|
|
1278
|
+
throw new Error(`Invalid boolean code ${value.toString(16)}`);
|
|
864
1279
|
}
|
|
865
|
-
|
|
866
|
-
this.
|
|
867
|
-
if (
|
|
868
|
-
this.
|
|
869
|
-
this.target[this.offset++] = value >> 8;
|
|
870
|
-
} else {
|
|
871
|
-
this.target[this.offset++] = value;
|
|
872
|
-
this.target[this.offset++] = value >> 8;
|
|
1280
|
+
readLength() {
|
|
1281
|
+
const firstByte = this.readByte();
|
|
1282
|
+
if (firstByte === 254) {
|
|
1283
|
+
return this.readByte() | this.readByte() << 8 | this.readByte() << 16;
|
|
873
1284
|
}
|
|
874
|
-
return
|
|
1285
|
+
return firstByte;
|
|
875
1286
|
}
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
this.
|
|
879
|
-
|
|
1287
|
+
readAll() {
|
|
1288
|
+
const result = [];
|
|
1289
|
+
while (this.length > this.offset) {
|
|
1290
|
+
result.push(this.readObject());
|
|
1291
|
+
}
|
|
1292
|
+
return result;
|
|
880
1293
|
}
|
|
881
|
-
|
|
882
|
-
this.
|
|
883
|
-
|
|
884
|
-
this.
|
|
885
|
-
|
|
1294
|
+
readBytes() {
|
|
1295
|
+
const length = this.readLength();
|
|
1296
|
+
this.assertRead(length);
|
|
1297
|
+
const bytes = this.target.subarray(this.offset, this.offset + length);
|
|
1298
|
+
this.offset += bytes.length;
|
|
1299
|
+
this._last = bytes;
|
|
1300
|
+
return bytes;
|
|
886
1301
|
}
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
this.
|
|
892
|
-
|
|
1302
|
+
/**
|
|
1303
|
+
* Reads encoded string.
|
|
1304
|
+
*/
|
|
1305
|
+
readString() {
|
|
1306
|
+
const length = this.readLength();
|
|
1307
|
+
this.assertRead(length);
|
|
1308
|
+
const result = utf8Read(this.target, length, this.offset);
|
|
1309
|
+
this.offset += length;
|
|
1310
|
+
this._last = result;
|
|
1311
|
+
return result;
|
|
893
1312
|
}
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
1313
|
+
/**
|
|
1314
|
+
* Reads a boolean value.
|
|
1315
|
+
*/
|
|
1316
|
+
readBool() {
|
|
1317
|
+
const value = this.readByte();
|
|
1318
|
+
if (value === CORE_TYPES.BoolTrue) {
|
|
1319
|
+
return true;
|
|
1320
|
+
} else if (value === CORE_TYPES.BoolFalse) {
|
|
1321
|
+
return false;
|
|
1322
|
+
} else {
|
|
1323
|
+
throw new Error(`Invalid boolean code ${value.toString(16)}`);
|
|
900
1324
|
}
|
|
901
|
-
this.writeDouble(timestamp);
|
|
902
|
-
return this;
|
|
903
1325
|
}
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
1326
|
+
/**
|
|
1327
|
+
* Reads and converts Unix time
|
|
1328
|
+
* into a Javascript {Date} object.
|
|
1329
|
+
*/
|
|
1330
|
+
readDate() {
|
|
1331
|
+
const value = this.readDouble();
|
|
1332
|
+
return new Date(value);
|
|
1333
|
+
}
|
|
1334
|
+
readStructure(checkConstructor = true) {
|
|
1335
|
+
if (checkConstructor) {
|
|
1336
|
+
this.assertConstructor(CORE_TYPES.Structure);
|
|
914
1337
|
}
|
|
915
|
-
this.
|
|
916
|
-
const
|
|
917
|
-
if (
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
this.target[start++] = bytes % 256;
|
|
922
|
-
this.target[start++] = (bytes >> 8) % 256;
|
|
923
|
-
this.target[start++] = (bytes >> 16) % 256;
|
|
1338
|
+
const structureId = this.readInt32(false);
|
|
1339
|
+
const struct = this.structures.get(structureId);
|
|
1340
|
+
if (!struct) {
|
|
1341
|
+
throw new Error(
|
|
1342
|
+
`Unknown structure id = ${structureId}, offset = ${this.offset - 1}`
|
|
1343
|
+
);
|
|
924
1344
|
}
|
|
925
|
-
this
|
|
926
|
-
return this;
|
|
1345
|
+
return struct.extension.decode.call(this);
|
|
927
1346
|
}
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
1347
|
+
/**
|
|
1348
|
+
* Reads a object.
|
|
1349
|
+
*/
|
|
1350
|
+
readObject() {
|
|
1351
|
+
if (this._repeat) {
|
|
1352
|
+
if (this._repeat.pool > 0) {
|
|
1353
|
+
--this._repeat.pool;
|
|
1354
|
+
return this._repeat.value;
|
|
1355
|
+
} else {
|
|
1356
|
+
this._repeat = void 0;
|
|
1357
|
+
}
|
|
933
1358
|
}
|
|
934
|
-
|
|
935
|
-
|
|
1359
|
+
const constructorId = this.readByte();
|
|
1360
|
+
const ext = this.extensions.get(constructorId);
|
|
1361
|
+
let value;
|
|
1362
|
+
if (ext) {
|
|
1363
|
+
value = ext.decode.call(this);
|
|
1364
|
+
} else {
|
|
1365
|
+
value = this._lastObject = this.readCore(constructorId);
|
|
936
1366
|
}
|
|
937
|
-
|
|
938
|
-
this._checksumOffset = this.offset;
|
|
939
|
-
return this;
|
|
1367
|
+
return value;
|
|
940
1368
|
}
|
|
941
|
-
|
|
942
|
-
const
|
|
943
|
-
|
|
944
|
-
this.
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
return
|
|
1369
|
+
readObjectGzip() {
|
|
1370
|
+
const bytes = this.readGzip();
|
|
1371
|
+
const reader = new BinaryReader(bytes);
|
|
1372
|
+
reader.extensions = this.extensions;
|
|
1373
|
+
reader.dictionary = this.dictionary;
|
|
1374
|
+
reader.dictionaryExtended = this.dictionaryExtended;
|
|
1375
|
+
return reader.readObject();
|
|
948
1376
|
}
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
1377
|
+
readGzip() {
|
|
1378
|
+
return pako__default.inflateRaw(this.readBytes());
|
|
1379
|
+
}
|
|
1380
|
+
readCore(constructorId) {
|
|
1381
|
+
switch (constructorId) {
|
|
1382
|
+
case CORE_TYPES.None:
|
|
1383
|
+
return this.readObject();
|
|
1384
|
+
case CORE_TYPES.GZIP:
|
|
1385
|
+
return this.readObjectGzip();
|
|
1386
|
+
case CORE_TYPES.BoolTrue:
|
|
1387
|
+
return true;
|
|
1388
|
+
case CORE_TYPES.BoolFalse:
|
|
1389
|
+
return false;
|
|
1390
|
+
case CORE_TYPES.Vector:
|
|
1391
|
+
return this.readVector(false);
|
|
1392
|
+
case CORE_TYPES.VectorDynamic:
|
|
1393
|
+
return this.readVectorDynamic(false);
|
|
1394
|
+
case CORE_TYPES.Null:
|
|
1395
|
+
return null;
|
|
1396
|
+
case CORE_TYPES.Binary:
|
|
1397
|
+
return this.readBytes();
|
|
1398
|
+
case CORE_TYPES.String:
|
|
1399
|
+
return this.readString();
|
|
1400
|
+
case CORE_TYPES.Date:
|
|
1401
|
+
return this.readDate();
|
|
1402
|
+
case CORE_TYPES.Int32:
|
|
1403
|
+
return this.readInt32();
|
|
1404
|
+
case CORE_TYPES.Int16:
|
|
1405
|
+
return this.readInt16();
|
|
1406
|
+
case CORE_TYPES.Int8:
|
|
1407
|
+
return this.readInt8();
|
|
1408
|
+
case CORE_TYPES.UInt32:
|
|
1409
|
+
return this.readInt32(false);
|
|
1410
|
+
case CORE_TYPES.UInt16:
|
|
1411
|
+
return this.readInt16(false);
|
|
1412
|
+
case CORE_TYPES.UInt8:
|
|
1413
|
+
return this.readInt8(false);
|
|
1414
|
+
case CORE_TYPES.Float:
|
|
1415
|
+
return this.readFloat();
|
|
1416
|
+
case CORE_TYPES.Double:
|
|
1417
|
+
return this.readDouble();
|
|
1418
|
+
case CORE_TYPES.Map:
|
|
1419
|
+
return this.readMap(false);
|
|
1420
|
+
case CORE_TYPES.Checksum:
|
|
1421
|
+
return void this.readChecksum(false);
|
|
1422
|
+
case CORE_TYPES.Structure:
|
|
1423
|
+
return this.readStructure(false);
|
|
1424
|
+
case CORE_TYPES.DictIndex: {
|
|
1425
|
+
const idx = this.readLength();
|
|
1426
|
+
return this.getDictionaryValue(idx);
|
|
1427
|
+
}
|
|
1428
|
+
case CORE_TYPES.DictValue: {
|
|
1429
|
+
const value = this.readString();
|
|
1430
|
+
this.dictionaryExtended.maybeInsert(value);
|
|
1431
|
+
return value;
|
|
1432
|
+
}
|
|
1433
|
+
case CORE_TYPES.Repeat: {
|
|
1434
|
+
const size = this.readLength();
|
|
1435
|
+
this._repeat = { pool: size - 1, value: this._lastObject };
|
|
1436
|
+
return this._lastObject;
|
|
1437
|
+
}
|
|
959
1438
|
}
|
|
960
|
-
|
|
1439
|
+
throw new Error(
|
|
1440
|
+
`Invalid constructor = ${CORE_TYPES[constructorId] || constructorId}, offset = ${this.offset - 1}`
|
|
1441
|
+
);
|
|
961
1442
|
}
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
this.
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
1443
|
+
getDictionaryValue(index) {
|
|
1444
|
+
let value = null;
|
|
1445
|
+
if (this.dictionary) {
|
|
1446
|
+
value = this.dictionary.getValue(index);
|
|
1447
|
+
}
|
|
1448
|
+
if (value === null) {
|
|
1449
|
+
value = this.dictionaryExtended.getValue(index);
|
|
1450
|
+
}
|
|
1451
|
+
return value;
|
|
1452
|
+
}
|
|
1453
|
+
readDictionary() {
|
|
1454
|
+
const constructorId = this.readByte();
|
|
1455
|
+
let key = null;
|
|
1456
|
+
switch (constructorId) {
|
|
1457
|
+
case CORE_TYPES.DictIndex: {
|
|
1458
|
+
const idx = this.readLength();
|
|
1459
|
+
key = this.getDictionaryValue(idx);
|
|
1460
|
+
break;
|
|
1461
|
+
}
|
|
1462
|
+
case CORE_TYPES.DictValue: {
|
|
1463
|
+
key = this.readString();
|
|
1464
|
+
this.dictionaryExtended.maybeInsert(key);
|
|
1465
|
+
break;
|
|
1466
|
+
}
|
|
1467
|
+
case CORE_TYPES.None: {
|
|
1468
|
+
key = null;
|
|
1469
|
+
break;
|
|
1470
|
+
}
|
|
1471
|
+
default: {
|
|
1472
|
+
this.seek(-1);
|
|
970
1473
|
}
|
|
971
1474
|
}
|
|
972
|
-
return
|
|
973
|
-
}
|
|
974
|
-
writeMap(object) {
|
|
975
|
-
for (const key in object) {
|
|
976
|
-
if (object[key] === void 0) continue;
|
|
977
|
-
this._last = noop;
|
|
978
|
-
this.wireDictionary(key);
|
|
979
|
-
this.writeObject(object[key]);
|
|
980
|
-
}
|
|
981
|
-
this.writeByte(CORE_TYPES.None);
|
|
982
|
-
return this;
|
|
1475
|
+
return key;
|
|
983
1476
|
}
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
idx = this.dictionary.getIndex(value);
|
|
988
|
-
}
|
|
989
|
-
if (idx === null) {
|
|
990
|
-
idx = this.dictionaryExtended.getIndex(value);
|
|
1477
|
+
readMap(checkConstructor = true) {
|
|
1478
|
+
if (checkConstructor) {
|
|
1479
|
+
this.assertConstructor(CORE_TYPES.Map);
|
|
991
1480
|
}
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
this.
|
|
1481
|
+
const temp = {};
|
|
1482
|
+
let key = this.readDictionary();
|
|
1483
|
+
while (key !== null) {
|
|
1484
|
+
temp[key] = this.readObject();
|
|
1485
|
+
key = this.readDictionary();
|
|
997
1486
|
}
|
|
998
|
-
return
|
|
999
|
-
}
|
|
1000
|
-
writeGzip(value) {
|
|
1001
|
-
const compressed = pako__default.deflateRaw(value, { level: 9 });
|
|
1002
|
-
this.writeBytes(compressed);
|
|
1003
|
-
return this;
|
|
1487
|
+
return temp;
|
|
1004
1488
|
}
|
|
1005
|
-
|
|
1489
|
+
decode(value) {
|
|
1490
|
+
this.target = value;
|
|
1491
|
+
this._last = void 0;
|
|
1492
|
+
this._lastObject = void 0;
|
|
1493
|
+
this._repeat = void 0;
|
|
1006
1494
|
this.offset = 0;
|
|
1007
1495
|
this._checksumOffset = 0;
|
|
1008
|
-
this.
|
|
1009
|
-
this.
|
|
1010
|
-
this.target = byteArrayAllocate(256);
|
|
1011
|
-
this.writeObject(value);
|
|
1012
|
-
return this.getBuffer();
|
|
1013
|
-
}
|
|
1014
|
-
startDynamicVector() {
|
|
1015
|
-
this.writeByte(CORE_TYPES.VectorDynamic);
|
|
1016
|
-
return this;
|
|
1496
|
+
this.length = value.length;
|
|
1497
|
+
return this.readObject();
|
|
1017
1498
|
}
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1499
|
+
/**
|
|
1500
|
+
* Reads a vector (a list) of objects.
|
|
1501
|
+
*/
|
|
1502
|
+
readVector(checkConstructor = true) {
|
|
1503
|
+
if (checkConstructor) {
|
|
1504
|
+
this.assertConstructor(CORE_TYPES.Vector);
|
|
1505
|
+
}
|
|
1506
|
+
const count = this.readLength();
|
|
1507
|
+
const temp = [];
|
|
1508
|
+
for (let i = 0; i < count; i++) {
|
|
1509
|
+
temp.push(this.readObject());
|
|
1510
|
+
}
|
|
1511
|
+
return temp;
|
|
1021
1512
|
}
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1513
|
+
/**
|
|
1514
|
+
* Reads a vector (a list) of objects.
|
|
1515
|
+
*/
|
|
1516
|
+
readVectorDynamic(checkConstructor = true) {
|
|
1517
|
+
if (checkConstructor) {
|
|
1518
|
+
this.assertConstructor(CORE_TYPES.VectorDynamic);
|
|
1519
|
+
}
|
|
1520
|
+
const temp = [];
|
|
1521
|
+
let complete = false;
|
|
1522
|
+
while (this.length > this.offset) {
|
|
1523
|
+
const constructorId = this.readByte();
|
|
1524
|
+
if (constructorId === CORE_TYPES.None) {
|
|
1525
|
+
complete = true;
|
|
1526
|
+
break;
|
|
1031
1527
|
}
|
|
1032
|
-
ext.
|
|
1033
|
-
|
|
1034
|
-
if (
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
this.
|
|
1038
|
-
this.offset = end;
|
|
1039
|
-
return true;
|
|
1528
|
+
const ext = this.extensions.get(constructorId);
|
|
1529
|
+
let value;
|
|
1530
|
+
if (ext) {
|
|
1531
|
+
value = ext.decode.call(this);
|
|
1532
|
+
} else {
|
|
1533
|
+
value = this.readCore(constructorId);
|
|
1040
1534
|
}
|
|
1535
|
+
temp.push(value);
|
|
1041
1536
|
}
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1537
|
+
if (!complete) {
|
|
1538
|
+
const err = new Error(`DynamicVector incomplete.`);
|
|
1539
|
+
err.incomplete = true;
|
|
1540
|
+
Error.captureStackTrace(err, this.readDictionary);
|
|
1541
|
+
throw err;
|
|
1046
1542
|
}
|
|
1047
|
-
|
|
1543
|
+
this._last = temp;
|
|
1544
|
+
return temp;
|
|
1048
1545
|
}
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
if (this._writeCustom(value)) {
|
|
1054
|
-
return this;
|
|
1055
|
-
}
|
|
1056
|
-
throw new TypeError(`Invalid core type of ${value}`);
|
|
1546
|
+
readChecksum(checkConstructor = true) {
|
|
1547
|
+
const offset = this.offset;
|
|
1548
|
+
if (checkConstructor) {
|
|
1549
|
+
this.assertConstructor(CORE_TYPES.Checksum);
|
|
1057
1550
|
}
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
this.writeCore(constructorId, value);
|
|
1551
|
+
const bytes = this.target.slice(this._checksumOffset, offset);
|
|
1552
|
+
const checksum = this.readInt32();
|
|
1553
|
+
let sum = 0;
|
|
1554
|
+
for (const val of bytes) {
|
|
1555
|
+
sum += val;
|
|
1064
1556
|
}
|
|
1065
|
-
|
|
1557
|
+
if (checksum - sum !== 0) {
|
|
1558
|
+
throw new Error(
|
|
1559
|
+
`Invalid checksum = ${checksum - sum}, offset = ${offset}`
|
|
1560
|
+
);
|
|
1561
|
+
}
|
|
1562
|
+
this._checksumOffset = this.offset;
|
|
1066
1563
|
}
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
writer.writeObject(value);
|
|
1073
|
-
this.writeCore(CORE_TYPES.GZIP, writer.getBuffer());
|
|
1074
|
-
return this;
|
|
1564
|
+
/**
|
|
1565
|
+
* Tells the current position on the stream.
|
|
1566
|
+
*/
|
|
1567
|
+
tellPosition() {
|
|
1568
|
+
return this.offset;
|
|
1075
1569
|
}
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
this.writeByte(constructorId);
|
|
1082
|
-
}
|
|
1083
|
-
switch (constructorId) {
|
|
1084
|
-
case CORE_TYPES.GZIP: {
|
|
1085
|
-
return this.writeGzip(value);
|
|
1086
|
-
}
|
|
1087
|
-
case CORE_TYPES.DictIndex: {
|
|
1088
|
-
return this.writeLength(value);
|
|
1089
|
-
}
|
|
1090
|
-
case CORE_TYPES.DictValue: {
|
|
1091
|
-
return this.writeString(value);
|
|
1092
|
-
}
|
|
1093
|
-
case CORE_TYPES.BoolFalse: {
|
|
1094
|
-
return this.writeBool(value);
|
|
1095
|
-
}
|
|
1096
|
-
case CORE_TYPES.BoolTrue: {
|
|
1097
|
-
return this.writeBool(value);
|
|
1098
|
-
}
|
|
1099
|
-
case CORE_TYPES.Date: {
|
|
1100
|
-
return this.writeDate(value);
|
|
1101
|
-
}
|
|
1102
|
-
case CORE_TYPES.Int32: {
|
|
1103
|
-
return this.writeInt32(value);
|
|
1104
|
-
}
|
|
1105
|
-
case CORE_TYPES.Int16: {
|
|
1106
|
-
return this.writeInt16(value);
|
|
1107
|
-
}
|
|
1108
|
-
case CORE_TYPES.Int8: {
|
|
1109
|
-
return this.writeInt8(value);
|
|
1110
|
-
}
|
|
1111
|
-
case CORE_TYPES.UInt32: {
|
|
1112
|
-
return this.writeInt32(value, false);
|
|
1113
|
-
}
|
|
1114
|
-
case CORE_TYPES.UInt16: {
|
|
1115
|
-
return this.writeInt16(value, false);
|
|
1116
|
-
}
|
|
1117
|
-
case CORE_TYPES.UInt8: {
|
|
1118
|
-
return this.writeInt8(value, false);
|
|
1119
|
-
}
|
|
1120
|
-
case CORE_TYPES.Double: {
|
|
1121
|
-
return this.writeDouble(value);
|
|
1122
|
-
}
|
|
1123
|
-
case CORE_TYPES.Float: {
|
|
1124
|
-
return this.writeFloat(value);
|
|
1125
|
-
}
|
|
1126
|
-
case CORE_TYPES.Null: {
|
|
1127
|
-
return this.writeNull();
|
|
1128
|
-
}
|
|
1129
|
-
case CORE_TYPES.String: {
|
|
1130
|
-
if (value.length <= 16) {
|
|
1131
|
-
this.offset--;
|
|
1132
|
-
return this.wireDictionary(value);
|
|
1133
|
-
}
|
|
1134
|
-
return this.writeString(value);
|
|
1135
|
-
}
|
|
1136
|
-
case CORE_TYPES.Vector: {
|
|
1137
|
-
return this.writeVector(value);
|
|
1138
|
-
}
|
|
1139
|
-
case CORE_TYPES.Map: {
|
|
1140
|
-
return this.writeMap(value);
|
|
1141
|
-
}
|
|
1142
|
-
}
|
|
1143
|
-
return this;
|
|
1570
|
+
/**
|
|
1571
|
+
* Sets the current position on the stream.
|
|
1572
|
+
*/
|
|
1573
|
+
setPosition(position) {
|
|
1574
|
+
this.offset = position;
|
|
1144
1575
|
}
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
this.offset
|
|
1151
|
-
this._repeat.count++;
|
|
1152
|
-
this.writeLength(this._repeat.count);
|
|
1153
|
-
return this;
|
|
1576
|
+
/**
|
|
1577
|
+
* Seeks the stream position given an offset from the current position.
|
|
1578
|
+
* The offset may be negative.
|
|
1579
|
+
*/
|
|
1580
|
+
seek(offset) {
|
|
1581
|
+
this.offset += offset;
|
|
1154
1582
|
}
|
|
1155
1583
|
}
|
|
1156
1584
|
|
|
@@ -1158,5 +1586,7 @@ exports.BinaryReader = BinaryReader;
|
|
|
1158
1586
|
exports.BinaryWriter = BinaryWriter;
|
|
1159
1587
|
exports.CORE_TYPES = CORE_TYPES;
|
|
1160
1588
|
exports.MAX_BUFFER_SIZE = MAX_BUFFER_SIZE;
|
|
1589
|
+
exports.Structure = Structure;
|
|
1161
1590
|
exports.createDictionary = createDictionary;
|
|
1162
|
-
|
|
1591
|
+
exports.defineStructure = defineStructure;
|
|
1592
|
+
//# sourceMappingURL=tl-pack.CaWRi9zF.cjs.map
|