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