json-as 1.3.5 → 1.3.7
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/CHANGELOG.md +17 -1
- package/assembly/deserialize/helpers/uint.ts +4 -1
- package/assembly/deserialize/index/arbitrary.ts +5 -1
- package/assembly/deserialize/index/array.ts +13 -3
- package/assembly/deserialize/index/integer.ts +68 -1
- package/assembly/deserialize/index/string.ts +4 -1
- package/assembly/deserialize/index/typedarray.ts +13 -3
- package/assembly/deserialize/index/unsigned.ts +78 -1
- package/assembly/deserialize/simd/array/integer.ts +327 -50
- package/assembly/deserialize/simd/integer.ts +233 -0
- package/assembly/deserialize/simd/string.ts +45 -11
- package/assembly/deserialize/simple/arbitrary.ts +11 -4
- package/assembly/deserialize/simple/array/arbitrary.ts +24 -5
- package/assembly/deserialize/simple/array/array.ts +8 -2
- package/assembly/deserialize/simple/array/bool.ts +38 -7
- package/assembly/deserialize/simple/array/box.ts +8 -2
- package/assembly/deserialize/simple/array/float.ts +36 -9
- package/assembly/deserialize/simple/array/generic.ts +12 -4
- package/assembly/deserialize/simple/array/integer.ts +8 -2
- package/assembly/deserialize/simple/array/map.ts +26 -6
- package/assembly/deserialize/simple/array/object.ts +26 -6
- package/assembly/deserialize/simple/array/raw.ts +34 -7
- package/assembly/deserialize/simple/array/string.ts +8 -2
- package/assembly/deserialize/simple/array/struct.ts +26 -6
- package/assembly/deserialize/simple/array.ts +13 -3
- package/assembly/deserialize/simple/bool.ts +6 -2
- package/assembly/deserialize/simple/float.ts +6 -1
- package/assembly/deserialize/simple/integer.ts +10 -2
- package/assembly/deserialize/simple/map.ts +95 -22
- package/assembly/deserialize/simple/object.ts +63 -14
- package/assembly/deserialize/simple/raw.ts +4 -1
- package/assembly/deserialize/simple/set.ts +59 -14
- package/assembly/deserialize/simple/staticarray/string.ts +11 -3
- package/assembly/deserialize/simple/staticarray.ts +64 -14
- package/assembly/deserialize/simple/string.ts +5 -92
- package/assembly/deserialize/simple/struct.ts +5 -1
- package/assembly/deserialize/simple/typedarray.ts +16 -3
- package/assembly/deserialize/simple/unsigned.ts +10 -15
- package/assembly/deserialize/swar/array/arbitrary.ts +5 -1
- package/assembly/deserialize/swar/array/array.ts +30 -6
- package/assembly/deserialize/swar/array/bool.ts +22 -4
- package/assembly/deserialize/swar/array/box.ts +5 -1
- package/assembly/deserialize/swar/array/float.ts +15 -3
- package/assembly/deserialize/swar/array/generic.ts +24 -7
- package/assembly/deserialize/swar/array/integer.ts +328 -84
- package/assembly/deserialize/swar/array/map.ts +5 -1
- package/assembly/deserialize/swar/array/object.ts +27 -7
- package/assembly/deserialize/swar/array/raw.ts +5 -1
- package/assembly/deserialize/swar/array/shared.ts +36 -11
- package/assembly/deserialize/swar/array/string.ts +20 -4
- package/assembly/deserialize/swar/array/struct.ts +27 -7
- package/assembly/deserialize/swar/array.ts +19 -4
- package/assembly/deserialize/swar/integer.ts +246 -0
- package/assembly/deserialize/swar/string.ts +98 -194
- package/assembly/index.d.ts +3 -1
- package/assembly/index.ts +312 -81
- package/assembly/serialize/index/float.ts +5 -1
- package/assembly/serialize/index/typedarray.ts +25 -7
- package/assembly/serialize/simd/string.ts +6 -2
- package/assembly/serialize/simple/array.ts +179 -1
- package/assembly/serialize/simple/float.ts +4 -1
- package/assembly/serialize/simple/integer.ts +9 -9
- package/assembly/serialize/simple/map.ts +6 -2
- package/assembly/serialize/simple/raw.ts +5 -1
- package/assembly/serialize/simple/set.ts +6 -1
- package/assembly/serialize/simple/staticarray.ts +6 -1
- package/assembly/serialize/simple/string.ts +0 -1
- package/assembly/serialize/simple/typedarray.ts +10 -3
- package/assembly/serialize/swar/string.ts +25 -8
- package/assembly/tsconfig.json +1 -21
- package/assembly/util/atoi-fast.ts +81 -0
- package/assembly/util/concat.ts +5 -1
- package/assembly/util/dragonbox-cache.ts +443 -2
- package/assembly/util/dragonbox.ts +43 -14
- package/assembly/util/itoa-fast.ts +230 -0
- package/assembly/util/masks.ts +18 -1
- package/assembly/util/parsefloat-fast.ts +167 -0
- package/assembly/util/simd-int.ts +191 -0
- package/assembly/util/snp.ts +4 -1
- package/assembly/util/swar-int.ts +248 -0
- package/assembly/util/swar.ts +13 -3
- package/lib/as-bs.ts +13 -5
- package/package.json +12 -4
- package/transform/lib/builder.d.ts.map +1 -1
- package/transform/lib/builder.js +13 -5
- package/transform/lib/builder.js.map +1 -1
- package/transform/lib/index.d.ts +1 -0
- package/transform/lib/index.d.ts.map +1 -1
- package/transform/lib/index.js +1030 -241
- package/transform/lib/index.js.map +1 -1
- package/transform/lib/linkers/alias.d.ts.map +1 -1
- package/transform/lib/linkers/alias.js.map +1 -1
- package/transform/lib/linkers/custom.d.ts.map +1 -1
- package/transform/lib/linkers/custom.js +3 -2
- package/transform/lib/linkers/custom.js.map +1 -1
- package/transform/lib/linkers/imports.d.ts.map +1 -1
- package/transform/lib/linkers/imports.js.map +1 -1
- package/transform/lib/types.d.ts.map +1 -1
- package/transform/lib/types.js +54 -16
- package/transform/lib/types.js.map +1 -1
- package/transform/lib/util.d.ts.map +1 -1
- package/transform/lib/util.js +1 -1
- package/transform/lib/util.js.map +1 -1
- package/transform/lib/visitor.d.ts.map +1 -1
- package/transform/lib/visitor.js +2 -1
- package/transform/lib/visitor.js.map +1 -1
- package/assembly/custom/util.ts +0 -310
package/assembly/index.ts
CHANGED
|
@@ -17,12 +17,30 @@ import { serializeSet } from "./serialize/index/set";
|
|
|
17
17
|
import { deserializeSet } from "./deserialize/index/set";
|
|
18
18
|
import { serializeStaticArray } from "./serialize/index/staticarray";
|
|
19
19
|
import { deserializeStaticArray } from "./deserialize/index/staticarray";
|
|
20
|
-
import {
|
|
20
|
+
import {
|
|
21
|
+
BRACE_LEFT,
|
|
22
|
+
BRACE_RIGHT,
|
|
23
|
+
BRACKET_LEFT,
|
|
24
|
+
BRACKET_RIGHT,
|
|
25
|
+
COMMA,
|
|
26
|
+
NULL_WORD,
|
|
27
|
+
QUOTE,
|
|
28
|
+
NULL_WORD_U64,
|
|
29
|
+
TRUE_WORD_U64,
|
|
30
|
+
FALSE_WORD_U64,
|
|
31
|
+
} from "./custom/chars";
|
|
21
32
|
import { itoa_buffered } from "util/number";
|
|
22
33
|
import { serializeBool } from "./serialize/index/bool";
|
|
23
34
|
import { serializeInteger } from "./serialize/index/integer";
|
|
24
|
-
import {
|
|
25
|
-
|
|
35
|
+
import {
|
|
36
|
+
serializeFloat,
|
|
37
|
+
serializeFloat32,
|
|
38
|
+
serializeFloat64,
|
|
39
|
+
} from "./serialize/index/float";
|
|
40
|
+
import {
|
|
41
|
+
dragonbox_f32_buffered,
|
|
42
|
+
dragonbox_f64_buffered,
|
|
43
|
+
} from "./util/dragonbox";
|
|
26
44
|
import { serializeStruct } from "./serialize/index/struct";
|
|
27
45
|
import { ptrToStr } from "./util/ptrToStr";
|
|
28
46
|
import { atoi, bytes, scanStringEnd } from "./util";
|
|
@@ -33,8 +51,15 @@ import { serializeRaw } from "./serialize/index/raw";
|
|
|
33
51
|
import { deserializeRaw } from "./deserialize/index/raw";
|
|
34
52
|
import { deserializeString } from "./deserialize/index/string";
|
|
35
53
|
import { serializeString } from "./serialize/index/string";
|
|
36
|
-
import {
|
|
37
|
-
|
|
54
|
+
import {
|
|
55
|
+
deserializeArrayBuffer,
|
|
56
|
+
deserializeTypedArray,
|
|
57
|
+
} from "./deserialize/index/typedarray";
|
|
58
|
+
import {
|
|
59
|
+
serializeArrayBufferUnsafe,
|
|
60
|
+
serializeDynamic,
|
|
61
|
+
serializeTypedArray,
|
|
62
|
+
} from "./serialize/index/typedarray";
|
|
38
63
|
|
|
39
64
|
/**
|
|
40
65
|
* Offset of the 'storage' property in the JSON.Value class.
|
|
@@ -71,7 +96,10 @@ export namespace JSON {
|
|
|
71
96
|
* @returns string
|
|
72
97
|
*/
|
|
73
98
|
// @ts-expect-error: inline
|
|
74
|
-
@inline export function stringify<T>(
|
|
99
|
+
@inline export function stringify<T>(
|
|
100
|
+
data: T,
|
|
101
|
+
out: string | null = null,
|
|
102
|
+
): string {
|
|
75
103
|
if (isBoolean<T>()) {
|
|
76
104
|
if (out) {
|
|
77
105
|
if (<bool>data == true) {
|
|
@@ -85,7 +113,12 @@ export namespace JSON {
|
|
|
85
113
|
return out;
|
|
86
114
|
}
|
|
87
115
|
return data ? "true" : "false";
|
|
88
|
-
} else if (
|
|
116
|
+
} else if (
|
|
117
|
+
isInteger<T>() &&
|
|
118
|
+
!isSigned<T>() &&
|
|
119
|
+
nameof<T>() == "usize" &&
|
|
120
|
+
data == 0
|
|
121
|
+
) {
|
|
89
122
|
if (out) {
|
|
90
123
|
out = changetype<string>(__renew(changetype<usize>(out), 8));
|
|
91
124
|
store<u64>(changetype<usize>(out), NULL_WORD_U64);
|
|
@@ -94,15 +127,24 @@ export namespace JSON {
|
|
|
94
127
|
return NULL_WORD;
|
|
95
128
|
} else if (isInteger<T>(data)) {
|
|
96
129
|
if (out) {
|
|
97
|
-
out = changetype<string>(
|
|
130
|
+
out = changetype<string>(
|
|
131
|
+
__renew(changetype<usize>(out), sizeof<T>() << 3),
|
|
132
|
+
);
|
|
98
133
|
|
|
99
134
|
const bytes = itoa_buffered(changetype<usize>(out), data) << 1;
|
|
100
|
-
return (out = changetype<string>(
|
|
135
|
+
return (out = changetype<string>(
|
|
136
|
+
__renew(changetype<usize>(out), bytes),
|
|
137
|
+
));
|
|
101
138
|
}
|
|
102
139
|
return data.toString();
|
|
103
140
|
} else if (isFloat<T>(data)) {
|
|
104
|
-
out = out
|
|
105
|
-
|
|
141
|
+
out = out
|
|
142
|
+
? changetype<string>(__renew(changetype<usize>(out), 64))
|
|
143
|
+
: changetype<string>(__new(64, idof<string>()));
|
|
144
|
+
const bytes =
|
|
145
|
+
(sizeof<T>() == 4
|
|
146
|
+
? dragonbox_f32_buffered(changetype<usize>(out), <f32>data)
|
|
147
|
+
: dragonbox_f64_buffered(changetype<usize>(out), <f64>data)) << 1;
|
|
106
148
|
return changetype<string>(__renew(changetype<usize>(out), bytes));
|
|
107
149
|
} else if (isNullable<T>() && changetype<usize>(data) == <usize>0) {
|
|
108
150
|
if (out) {
|
|
@@ -125,10 +167,16 @@ export namespace JSON {
|
|
|
125
167
|
inline.always(data.__SERIALIZE(changetype<usize>(data)));
|
|
126
168
|
return bs.out<string>();
|
|
127
169
|
} else if (data instanceof Date) {
|
|
128
|
-
out = out
|
|
170
|
+
out = out
|
|
171
|
+
? changetype<string>(__renew(changetype<usize>(out), 52))
|
|
172
|
+
: changetype<string>(__new(52, idof<string>()));
|
|
129
173
|
|
|
130
174
|
store<u16>(changetype<usize>(out), QUOTE);
|
|
131
|
-
memory.copy(
|
|
175
|
+
memory.copy(
|
|
176
|
+
changetype<usize>(out) + 2,
|
|
177
|
+
changetype<usize>(data.toISOString()),
|
|
178
|
+
48,
|
|
179
|
+
);
|
|
132
180
|
store<u16>(changetype<usize>(out), QUOTE, 50);
|
|
133
181
|
return changetype<string>(out);
|
|
134
182
|
} else if (data instanceof Array) {
|
|
@@ -174,7 +222,10 @@ export namespace JSON {
|
|
|
174
222
|
return bs.out<string>();
|
|
175
223
|
} else if (data instanceof ArrayBuffer) {
|
|
176
224
|
const dataStart = changetype<usize>(data);
|
|
177
|
-
serializeArrayBufferUnsafe(
|
|
225
|
+
serializeArrayBufferUnsafe(
|
|
226
|
+
dataStart,
|
|
227
|
+
changetype<OBJECT>(dataStart - TOTAL_OVERHEAD).rtSize,
|
|
228
|
+
);
|
|
178
229
|
return bs.out<string>();
|
|
179
230
|
} else if (data instanceof Set) {
|
|
180
231
|
// @ts-expect-error
|
|
@@ -196,7 +247,11 @@ export namespace JSON {
|
|
|
196
247
|
} else if (data instanceof JSON.Box) {
|
|
197
248
|
return JSON.stringify(data.value);
|
|
198
249
|
} else {
|
|
199
|
-
throw new Error(
|
|
250
|
+
throw new Error(
|
|
251
|
+
`Could not serialize data of type '${nameof<T>()}'. ` +
|
|
252
|
+
`If this is a custom class, add the @json decorator: @json class ${nameof<T>()} { ... }. ` +
|
|
253
|
+
`Supported types: primitives, string, Array, StaticArray, TypedArray, ArrayBuffer, Map, Date, and @json decorated classes.`,
|
|
254
|
+
);
|
|
200
255
|
}
|
|
201
256
|
}
|
|
202
257
|
|
|
@@ -215,10 +270,16 @@ export namespace JSON {
|
|
|
215
270
|
if (isBoolean<T>()) {
|
|
216
271
|
return deserializeBoolean(dataPtr, dataPtr + dataSize) as T;
|
|
217
272
|
} else if (isInteger<T>()) {
|
|
218
|
-
return isSigned<T>()
|
|
273
|
+
return isSigned<T>()
|
|
274
|
+
? deserializeInteger<T>(dataPtr, dataPtr + dataSize)
|
|
275
|
+
: deserializeUnsigned<T>(dataPtr, dataPtr + dataSize);
|
|
219
276
|
} else if (isFloat<T>()) {
|
|
220
277
|
return deserializeFloat<T>(dataPtr, dataPtr + dataSize);
|
|
221
|
-
} else if (
|
|
278
|
+
} else if (
|
|
279
|
+
isNullable<T>() &&
|
|
280
|
+
dataSize == 8 &&
|
|
281
|
+
load<u64>(dataPtr) == NULL_WORD_U64
|
|
282
|
+
) {
|
|
222
283
|
return null;
|
|
223
284
|
} else if (isString<T>()) {
|
|
224
285
|
return deserializeString(dataPtr, dataPtr + dataSize) as T;
|
|
@@ -230,12 +291,21 @@ export namespace JSON {
|
|
|
230
291
|
// @ts-expect-error
|
|
231
292
|
return out.__DESERIALIZE_CUSTOM(data);
|
|
232
293
|
// @ts-expect-error: Defined by transform
|
|
233
|
-
} else if (
|
|
234
|
-
|
|
294
|
+
} else if (
|
|
295
|
+
isDefined(type.__DESERIALIZE_SLOW) ||
|
|
296
|
+
isDefined(type.__DESERIALIZE_FAST)
|
|
297
|
+
) {
|
|
298
|
+
const out = changetype<nonnull<T>>(
|
|
299
|
+
__new(offsetof<nonnull<T>>(), idof<nonnull<T>>()),
|
|
300
|
+
);
|
|
235
301
|
// @ts-expect-error: Defined by transform
|
|
236
302
|
if (isDefined(type.__DESERIALIZE_FAST)) {
|
|
237
303
|
// @ts-expect-error: Defined by transform
|
|
238
|
-
if (
|
|
304
|
+
if (
|
|
305
|
+
out.__DESERIALIZE_FAST(dataPtr, dataPtr + dataSize, out) ==
|
|
306
|
+
dataPtr + dataSize
|
|
307
|
+
)
|
|
308
|
+
return out;
|
|
239
309
|
// @ts-expect-error: Defined by transform
|
|
240
310
|
}
|
|
241
311
|
if (isDefined(type.__INITIALIZE)) out.__INITIALIZE();
|
|
@@ -249,40 +319,96 @@ export namespace JSON {
|
|
|
249
319
|
}
|
|
250
320
|
if (type instanceof StaticArray) {
|
|
251
321
|
// @ts-expect-error
|
|
252
|
-
return inline.always(
|
|
322
|
+
return inline.always(
|
|
323
|
+
deserializeStaticArray<nonnull<T>>(dataPtr, dataPtr + dataSize, 0),
|
|
324
|
+
);
|
|
253
325
|
} else if (type instanceof Array) {
|
|
254
326
|
// @ts-expect-error
|
|
255
|
-
return inline.always(
|
|
327
|
+
return inline.always(
|
|
328
|
+
deserializeArray<nonnull<T>>(
|
|
329
|
+
dataPtr,
|
|
330
|
+
dataPtr + dataSize,
|
|
331
|
+
changetype<usize>(instantiate<T>()),
|
|
332
|
+
),
|
|
333
|
+
);
|
|
256
334
|
} else if (type instanceof Int8Array) {
|
|
257
|
-
return deserializeTypedArray<nonnull<T>>(
|
|
335
|
+
return deserializeTypedArray<nonnull<T>>(
|
|
336
|
+
dataPtr,
|
|
337
|
+
dataPtr + dataSize,
|
|
338
|
+
0,
|
|
339
|
+
) as T;
|
|
258
340
|
} else if (type instanceof Uint8Array) {
|
|
259
|
-
return deserializeTypedArray<nonnull<T>>(
|
|
341
|
+
return deserializeTypedArray<nonnull<T>>(
|
|
342
|
+
dataPtr,
|
|
343
|
+
dataPtr + dataSize,
|
|
344
|
+
0,
|
|
345
|
+
) as T;
|
|
260
346
|
} else if (type instanceof Uint8ClampedArray) {
|
|
261
|
-
return deserializeTypedArray<nonnull<T>>(
|
|
347
|
+
return deserializeTypedArray<nonnull<T>>(
|
|
348
|
+
dataPtr,
|
|
349
|
+
dataPtr + dataSize,
|
|
350
|
+
0,
|
|
351
|
+
) as T;
|
|
262
352
|
} else if (type instanceof Int16Array) {
|
|
263
|
-
return deserializeTypedArray<nonnull<T>>(
|
|
353
|
+
return deserializeTypedArray<nonnull<T>>(
|
|
354
|
+
dataPtr,
|
|
355
|
+
dataPtr + dataSize,
|
|
356
|
+
0,
|
|
357
|
+
) as T;
|
|
264
358
|
} else if (type instanceof Uint16Array) {
|
|
265
|
-
return deserializeTypedArray<nonnull<T>>(
|
|
359
|
+
return deserializeTypedArray<nonnull<T>>(
|
|
360
|
+
dataPtr,
|
|
361
|
+
dataPtr + dataSize,
|
|
362
|
+
0,
|
|
363
|
+
) as T;
|
|
266
364
|
} else if (type instanceof Int32Array) {
|
|
267
|
-
return deserializeTypedArray<nonnull<T>>(
|
|
365
|
+
return deserializeTypedArray<nonnull<T>>(
|
|
366
|
+
dataPtr,
|
|
367
|
+
dataPtr + dataSize,
|
|
368
|
+
0,
|
|
369
|
+
) as T;
|
|
268
370
|
} else if (type instanceof Uint32Array) {
|
|
269
|
-
return deserializeTypedArray<nonnull<T>>(
|
|
371
|
+
return deserializeTypedArray<nonnull<T>>(
|
|
372
|
+
dataPtr,
|
|
373
|
+
dataPtr + dataSize,
|
|
374
|
+
0,
|
|
375
|
+
) as T;
|
|
270
376
|
} else if (type instanceof Int64Array) {
|
|
271
|
-
return deserializeTypedArray<nonnull<T>>(
|
|
377
|
+
return deserializeTypedArray<nonnull<T>>(
|
|
378
|
+
dataPtr,
|
|
379
|
+
dataPtr + dataSize,
|
|
380
|
+
0,
|
|
381
|
+
) as T;
|
|
272
382
|
} else if (type instanceof Uint64Array) {
|
|
273
|
-
return deserializeTypedArray<nonnull<T>>(
|
|
383
|
+
return deserializeTypedArray<nonnull<T>>(
|
|
384
|
+
dataPtr,
|
|
385
|
+
dataPtr + dataSize,
|
|
386
|
+
0,
|
|
387
|
+
) as T;
|
|
274
388
|
} else if (type instanceof Float32Array) {
|
|
275
|
-
return deserializeTypedArray<nonnull<T>>(
|
|
389
|
+
return deserializeTypedArray<nonnull<T>>(
|
|
390
|
+
dataPtr,
|
|
391
|
+
dataPtr + dataSize,
|
|
392
|
+
0,
|
|
393
|
+
) as T;
|
|
276
394
|
} else if (type instanceof Float64Array) {
|
|
277
|
-
return deserializeTypedArray<nonnull<T>>(
|
|
395
|
+
return deserializeTypedArray<nonnull<T>>(
|
|
396
|
+
dataPtr,
|
|
397
|
+
dataPtr + dataSize,
|
|
398
|
+
0,
|
|
399
|
+
) as T;
|
|
278
400
|
} else if (type instanceof ArrayBuffer) {
|
|
279
401
|
return deserializeArrayBuffer(dataPtr, dataPtr + dataSize, 0) as T;
|
|
280
402
|
} else if (type instanceof Set) {
|
|
281
403
|
// @ts-expect-error
|
|
282
|
-
return inline.always(
|
|
404
|
+
return inline.always(
|
|
405
|
+
deserializeSet<nonnull<T>>(dataPtr, dataPtr + dataSize, 0),
|
|
406
|
+
);
|
|
283
407
|
} else if (type instanceof Map) {
|
|
284
408
|
// @ts-expect-error
|
|
285
|
-
return inline.always(
|
|
409
|
+
return inline.always(
|
|
410
|
+
deserializeMap<nonnull<T>>(dataPtr, dataPtr + dataSize, 0),
|
|
411
|
+
);
|
|
286
412
|
} else if (type instanceof Date) {
|
|
287
413
|
// @ts-expect-error
|
|
288
414
|
return deserializeDate(dataPtr, dataPtr + dataSize);
|
|
@@ -291,7 +417,9 @@ export namespace JSON {
|
|
|
291
417
|
return deserializeRaw(dataPtr, dataPtr + dataSize);
|
|
292
418
|
} else if (type instanceof JSON.Value) {
|
|
293
419
|
// @ts-expect-error
|
|
294
|
-
return inline.always(
|
|
420
|
+
return inline.always(
|
|
421
|
+
deserializeArbitrary(dataPtr, dataPtr + dataSize, 0),
|
|
422
|
+
);
|
|
295
423
|
} else if (type instanceof JSON.Obj) {
|
|
296
424
|
// @ts-expect-error
|
|
297
425
|
return inline.always(deserializeObject(dataPtr, dataPtr + dataSize, 0));
|
|
@@ -299,7 +427,11 @@ export namespace JSON {
|
|
|
299
427
|
// @ts-expect-error
|
|
300
428
|
return new JSON.Box(parseBox(data, changetype<nonnull<T>>(0).value));
|
|
301
429
|
} else {
|
|
302
|
-
throw new Error(
|
|
430
|
+
throw new Error(
|
|
431
|
+
`Could not deserialize JSON to type '${nameof<T>()}'. ` +
|
|
432
|
+
`If this is a custom class, ensure it has the @json decorator: @json class ${nameof<T>()} { ... }. ` +
|
|
433
|
+
`Input: "${data.length > 50 ? data.slice(0, 50) + "..." : data}"`,
|
|
434
|
+
);
|
|
303
435
|
}
|
|
304
436
|
}
|
|
305
437
|
}
|
|
@@ -450,7 +582,9 @@ export namespace JSON {
|
|
|
450
582
|
* @returns An instance of JSON.Value.
|
|
451
583
|
*/
|
|
452
584
|
@inline static empty(): JSON.Value {
|
|
453
|
-
return changetype<JSON.Value>(
|
|
585
|
+
return changetype<JSON.Value>(
|
|
586
|
+
__new(offsetof<JSON.Value>(), idof<JSON.Value>()),
|
|
587
|
+
);
|
|
454
588
|
}
|
|
455
589
|
|
|
456
590
|
/**
|
|
@@ -460,7 +594,9 @@ export namespace JSON {
|
|
|
460
594
|
*/
|
|
461
595
|
@inline static from<T>(value: T): JSON.Value {
|
|
462
596
|
if (value instanceof JSON.Value) return value;
|
|
463
|
-
const out = changetype<JSON.Value>(
|
|
597
|
+
const out = changetype<JSON.Value>(
|
|
598
|
+
__new(offsetof<JSON.Value>(), idof<JSON.Value>()),
|
|
599
|
+
);
|
|
464
600
|
out.set<T>(value);
|
|
465
601
|
return out;
|
|
466
602
|
}
|
|
@@ -471,12 +607,20 @@ export namespace JSON {
|
|
|
471
607
|
* @returns JSON.Types
|
|
472
608
|
*/
|
|
473
609
|
@inline getType<T>(value: T): JSON.Types {
|
|
474
|
-
if (isNullable<T>() && changetype<usize>(value) === 0)
|
|
610
|
+
if (isNullable<T>() && changetype<usize>(value) === 0)
|
|
611
|
+
return JSON.Types.Null;
|
|
475
612
|
if (isBoolean<T>()) return JSON.Types.Bool;
|
|
476
|
-
if (
|
|
613
|
+
if (
|
|
614
|
+
isInteger<T>() &&
|
|
615
|
+
!isSigned<T>() &&
|
|
616
|
+
changetype<usize>(value) == 0 &&
|
|
617
|
+
nameof<T>() == "usize"
|
|
618
|
+
)
|
|
619
|
+
return JSON.Types.Null;
|
|
477
620
|
if (isString<T>()) return JSON.Types.String;
|
|
478
621
|
// @ts-expect-error: can assume that T is ArrayLike based on previous condition
|
|
479
|
-
if (isArray<T>() && idof<valueof<T>>() == idof<JSON.Value>())
|
|
622
|
+
if (isArray<T>() && idof<valueof<T>>() == idof<JSON.Value>())
|
|
623
|
+
return JSON.Types.Array;
|
|
480
624
|
if (value instanceof JSON.Box) return this.getType(value.value);
|
|
481
625
|
if (value instanceof i8) return JSON.Types.I8;
|
|
482
626
|
if (value instanceof i16) return JSON.Types.I16;
|
|
@@ -489,7 +633,8 @@ export namespace JSON {
|
|
|
489
633
|
if (value instanceof f32) return JSON.Types.F32;
|
|
490
634
|
if (value instanceof f64) return JSON.Types.F64;
|
|
491
635
|
// @ts-expect-error: supplied by transform
|
|
492
|
-
if (isDefined(value.__SERIALIZE) && isManaged<T>(value))
|
|
636
|
+
if (isDefined(value.__SERIALIZE) && isManaged<T>(value))
|
|
637
|
+
return u16(idof<T>()) + JSON.Types.Struct;
|
|
493
638
|
if (value instanceof Int8Array) return JSON.Types.TypedArray;
|
|
494
639
|
if (value instanceof Uint8Array) return JSON.Types.TypedArray;
|
|
495
640
|
if (value instanceof Uint8ClampedArray) return JSON.Types.TypedArray;
|
|
@@ -515,29 +660,56 @@ export namespace JSON {
|
|
|
515
660
|
this.type = this.getType<T>(value);
|
|
516
661
|
|
|
517
662
|
if (value instanceof JSON.Box) this.set(value.value);
|
|
518
|
-
else if (isBoolean<T>())
|
|
519
|
-
|
|
520
|
-
else if (
|
|
521
|
-
|
|
663
|
+
else if (isBoolean<T>())
|
|
664
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
665
|
+
else if (
|
|
666
|
+
isInteger<T>() &&
|
|
667
|
+
!isSigned<T>() &&
|
|
668
|
+
changetype<usize>(value) == 0 &&
|
|
669
|
+
nameof<T>() == "usize"
|
|
670
|
+
)
|
|
671
|
+
store<usize>(changetype<usize>(this), 0, STORAGE);
|
|
672
|
+
else if (isInteger<T>() || isFloat<T>())
|
|
673
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
674
|
+
else if (isNullable<T>() && changetype<usize>(value) === 0)
|
|
675
|
+
store<usize>(changetype<usize>(this), 0, STORAGE);
|
|
522
676
|
else if (isString<T>()) store<T>(changetype<usize>(this), value, STORAGE);
|
|
523
|
-
else if (value instanceof JSON.Raw)
|
|
677
|
+
else if (value instanceof JSON.Raw)
|
|
678
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
524
679
|
// @ts-expect-error: supplied by transform
|
|
525
680
|
else if (isDefined(value.__SERIALIZE) && isManaged<T>(value)) {
|
|
526
681
|
// @ts-expect-error
|
|
527
|
-
if (!JSON.Value.METHODS.has(idof<T>()))
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
else if (value instanceof
|
|
535
|
-
|
|
536
|
-
else if (value instanceof
|
|
537
|
-
|
|
538
|
-
else if (value instanceof
|
|
539
|
-
|
|
540
|
-
else if (value instanceof
|
|
682
|
+
if (!JSON.Value.METHODS.has(idof<T>()))
|
|
683
|
+
JSON.Value.METHODS.set(idof<T>(), value.__SERIALIZE.index);
|
|
684
|
+
store<usize>(
|
|
685
|
+
changetype<usize>(this),
|
|
686
|
+
changetype<usize>(value),
|
|
687
|
+
STORAGE,
|
|
688
|
+
);
|
|
689
|
+
} else if (value instanceof Int8Array)
|
|
690
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
691
|
+
else if (value instanceof Uint8Array)
|
|
692
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
693
|
+
else if (value instanceof Uint8ClampedArray)
|
|
694
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
695
|
+
else if (value instanceof Int16Array)
|
|
696
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
697
|
+
else if (value instanceof Uint16Array)
|
|
698
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
699
|
+
else if (value instanceof Int32Array)
|
|
700
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
701
|
+
else if (value instanceof Uint32Array)
|
|
702
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
703
|
+
else if (value instanceof Int64Array)
|
|
704
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
705
|
+
else if (value instanceof Uint64Array)
|
|
706
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
707
|
+
else if (value instanceof Float32Array)
|
|
708
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
709
|
+
else if (value instanceof Float64Array)
|
|
710
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
711
|
+
else if (value instanceof ArrayBuffer)
|
|
712
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
541
713
|
else if (value instanceof Map) {
|
|
542
714
|
if (idof<T>() !== idof<Map<string, JSON.Value>>()) {
|
|
543
715
|
abort("Maps must be of type Map<string, JSON.Value>!");
|
|
@@ -769,7 +941,9 @@ export namespace JSON {
|
|
|
769
941
|
|
|
770
942
|
const parsed = JSON.parse<JSON.Value>(JSON.stringify(value));
|
|
771
943
|
if (parsed.type != JSON.Types.Object) {
|
|
772
|
-
throw new Error(
|
|
944
|
+
throw new Error(
|
|
945
|
+
"JSON.Obj.from expects a value that serializes to a JSON object",
|
|
946
|
+
);
|
|
773
947
|
}
|
|
774
948
|
return parsed.get<JSON.Obj>();
|
|
775
949
|
}
|
|
@@ -779,7 +953,8 @@ export namespace JSON {
|
|
|
779
953
|
*/
|
|
780
954
|
export class Box<T> {
|
|
781
955
|
constructor(public value: T) {
|
|
782
|
-
if (!isInteger<T>() && !isFloat<T>() && !isBoolean<T>())
|
|
956
|
+
if (!isInteger<T>() && !isFloat<T>() && !isBoolean<T>())
|
|
957
|
+
ERROR("JSON.Box should only hold primitive types!");
|
|
783
958
|
}
|
|
784
959
|
/**
|
|
785
960
|
* Set the internal value of Box to new value
|
|
@@ -802,9 +977,11 @@ export namespace JSON {
|
|
|
802
977
|
* @returns Box<T> | null
|
|
803
978
|
*/
|
|
804
979
|
@inline static fromValue<T>(value: JSON.Value): Box<T> | null {
|
|
805
|
-
if (!(value instanceof JSON.Value))
|
|
980
|
+
if (!(value instanceof JSON.Value))
|
|
981
|
+
throw new Error("value must be of type JSON.Value");
|
|
806
982
|
if (value.type === JSON.Types.Null) return null;
|
|
807
|
-
const v =
|
|
983
|
+
const v =
|
|
984
|
+
value.type === JSON.Types.F64 ? value.get<f64>() : value.get<T>();
|
|
808
985
|
// @ts-expect-error
|
|
809
986
|
return new Box(isInteger<T>() || isFloat<T>() ? <T>v : v);
|
|
810
987
|
}
|
|
@@ -897,7 +1074,10 @@ export namespace JSON {
|
|
|
897
1074
|
serializeTypedArray<Float64Array>(data);
|
|
898
1075
|
} else if (data instanceof ArrayBuffer) {
|
|
899
1076
|
const dataStart = changetype<usize>(data);
|
|
900
|
-
serializeArrayBufferUnsafe(
|
|
1077
|
+
serializeArrayBufferUnsafe(
|
|
1078
|
+
dataStart,
|
|
1079
|
+
changetype<OBJECT>(dataStart - TOTAL_OVERHEAD).rtSize,
|
|
1080
|
+
);
|
|
901
1081
|
} else if (data instanceof Set) {
|
|
902
1082
|
// @ts-expect-error
|
|
903
1083
|
serializeSet(changetype<nonnull<T>>(data));
|
|
@@ -913,7 +1093,11 @@ export namespace JSON {
|
|
|
913
1093
|
} else if (data instanceof JSON.Box) {
|
|
914
1094
|
__serialize(data.value);
|
|
915
1095
|
} else {
|
|
916
|
-
throw new Error(
|
|
1096
|
+
throw new Error(
|
|
1097
|
+
`Could not serialize data of type '${nameof<T>()}'. ` +
|
|
1098
|
+
`If this is a custom class, add the @json decorator: @json class ${nameof<T>()} { ... }. ` +
|
|
1099
|
+
`Supported types: primitives, string, Array, StaticArray, TypedArray, ArrayBuffer, Map, Date, and @json decorated classes.`,
|
|
1100
|
+
);
|
|
917
1101
|
}
|
|
918
1102
|
}
|
|
919
1103
|
|
|
@@ -925,19 +1109,32 @@ export namespace JSON {
|
|
|
925
1109
|
* @param dst - usize
|
|
926
1110
|
* @returns void
|
|
927
1111
|
*/
|
|
928
|
-
export function __deserialize<T>(
|
|
1112
|
+
export function __deserialize<T>(
|
|
1113
|
+
srcStart: usize,
|
|
1114
|
+
srcEnd: usize,
|
|
1115
|
+
dst: usize = 0,
|
|
1116
|
+
): T {
|
|
929
1117
|
if (isBoolean<T>()) {
|
|
930
1118
|
// @ts-expect-error: type
|
|
931
1119
|
return deserializeBoolean(srcStart, srcEnd);
|
|
932
1120
|
} else if (isInteger<T>()) {
|
|
933
|
-
return isSigned<T>()
|
|
1121
|
+
return isSigned<T>()
|
|
1122
|
+
? deserializeInteger<T>(srcStart, srcEnd)
|
|
1123
|
+
: deserializeUnsigned<T>(srcStart, srcEnd);
|
|
934
1124
|
} else if (isFloat<T>()) {
|
|
935
1125
|
return deserializeFloat<T>(srcStart, srcEnd);
|
|
936
1126
|
} else if (isString<T>()) {
|
|
937
|
-
if (srcEnd - srcStart < 4)
|
|
1127
|
+
if (srcEnd - srcStart < 4)
|
|
1128
|
+
throw new Error(
|
|
1129
|
+
"Cannot parse data as string because it was formatted incorrectly!",
|
|
1130
|
+
);
|
|
938
1131
|
|
|
939
1132
|
return deserializeString(srcStart, srcEnd) as T;
|
|
940
|
-
} else if (
|
|
1133
|
+
} else if (
|
|
1134
|
+
isNullable<T>() &&
|
|
1135
|
+
srcEnd - srcStart == 8 &&
|
|
1136
|
+
load<u64>(srcStart) == NULL_WORD_U64
|
|
1137
|
+
) {
|
|
941
1138
|
return null;
|
|
942
1139
|
} else {
|
|
943
1140
|
let type: nonnull<T> = changetype<nonnull<T>>(0);
|
|
@@ -947,12 +1144,18 @@ export namespace JSON {
|
|
|
947
1144
|
// @ts-expect-error: Defined by transform
|
|
948
1145
|
return out.__DESERIALIZE_CUSTOM(ptrToStr(srcStart, srcEnd));
|
|
949
1146
|
// @ts-expect-error: Defined by transform
|
|
950
|
-
} else if (
|
|
951
|
-
|
|
1147
|
+
} else if (
|
|
1148
|
+
isDefined(type.__DESERIALIZE_SLOW) ||
|
|
1149
|
+
isDefined(type.__DESERIALIZE_FAST)
|
|
1150
|
+
) {
|
|
1151
|
+
const out = changetype<nonnull<T>>(
|
|
1152
|
+
dst || __new(offsetof<nonnull<T>>(), idof<nonnull<T>>()),
|
|
1153
|
+
);
|
|
952
1154
|
// @ts-expect-error: Defined by transform
|
|
953
1155
|
if (isDefined(type.__DESERIALIZE_FAST)) {
|
|
954
1156
|
// @ts-expect-error: Defined by transform
|
|
955
|
-
if (out.__DESERIALIZE_FAST(srcStart, srcEnd, out) == srcEnd)
|
|
1157
|
+
if (out.__DESERIALIZE_FAST(srcStart, srcEnd, out) == srcEnd)
|
|
1158
|
+
return out;
|
|
956
1159
|
}
|
|
957
1160
|
// @ts-expect-error: Defined by transform
|
|
958
1161
|
if (isDefined(type.__INITIALIZE)) out.__INITIALIZE();
|
|
@@ -1014,11 +1217,22 @@ export namespace JSON {
|
|
|
1014
1217
|
return deserializeObject(srcStart, srcEnd, 0);
|
|
1015
1218
|
} else if (type instanceof JSON.Box) {
|
|
1016
1219
|
// @ts-expect-error: type
|
|
1017
|
-
return new JSON.Box(
|
|
1220
|
+
return new JSON.Box(
|
|
1221
|
+
deserializeBox(
|
|
1222
|
+
srcStart,
|
|
1223
|
+
srcEnd,
|
|
1224
|
+
dst,
|
|
1225
|
+
changetype<nonnull<T>>(0).value,
|
|
1226
|
+
),
|
|
1227
|
+
);
|
|
1018
1228
|
}
|
|
1019
1229
|
}
|
|
1020
1230
|
const snippet = ptrToStr(srcStart, srcEnd);
|
|
1021
|
-
throw new Error(
|
|
1231
|
+
throw new Error(
|
|
1232
|
+
`Could not deserialize JSON to type '${nameof<T>()}'. ` +
|
|
1233
|
+
`If this is a custom class, ensure it has the @json decorator: @json class ${nameof<T>()} { ... }. ` +
|
|
1234
|
+
`Input: "${snippet.length > 50 ? snippet.slice(0, 50) + "..." : snippet}"`,
|
|
1235
|
+
);
|
|
1022
1236
|
}
|
|
1023
1237
|
export namespace Util {
|
|
1024
1238
|
// @ts-expect-error: decorator
|
|
@@ -1026,7 +1240,10 @@ export namespace JSON {
|
|
|
1026
1240
|
return code == 0x20 || code - 9 <= 4;
|
|
1027
1241
|
}
|
|
1028
1242
|
// @ts-expect-error: decorator
|
|
1029
|
-
@inline export function scanValueEnd(
|
|
1243
|
+
@inline export function scanValueEnd(
|
|
1244
|
+
srcStart: usize,
|
|
1245
|
+
srcEnd: usize,
|
|
1246
|
+
): usize {
|
|
1030
1247
|
if (srcStart >= srcEnd) return 0;
|
|
1031
1248
|
let ptr = srcStart;
|
|
1032
1249
|
while (ptr < srcEnd && isSpace(load<u16>(ptr))) ptr += 2;
|
|
@@ -1061,7 +1278,13 @@ export namespace JSON {
|
|
|
1061
1278
|
|
|
1062
1279
|
while (ptr < srcEnd) {
|
|
1063
1280
|
const code = load<u16>(ptr);
|
|
1064
|
-
if (
|
|
1281
|
+
if (
|
|
1282
|
+
code == COMMA ||
|
|
1283
|
+
code == BRACKET_RIGHT ||
|
|
1284
|
+
code == BRACE_RIGHT ||
|
|
1285
|
+
isSpace(code)
|
|
1286
|
+
)
|
|
1287
|
+
return ptr;
|
|
1065
1288
|
ptr += 2;
|
|
1066
1289
|
}
|
|
1067
1290
|
|
|
@@ -1087,7 +1310,10 @@ export namespace JSON {
|
|
|
1087
1310
|
* @returns - string
|
|
1088
1311
|
*/
|
|
1089
1312
|
// @ts-expect-error: inline
|
|
1090
|
-
@inline export function stringify<T>(
|
|
1313
|
+
@inline export function stringify<T>(
|
|
1314
|
+
data: T,
|
|
1315
|
+
out: string | null = null,
|
|
1316
|
+
): string {
|
|
1091
1317
|
bs.saveState();
|
|
1092
1318
|
JSON.__serialize<T>(data);
|
|
1093
1319
|
const result = bs.cpyOut<string>();
|
|
@@ -1127,7 +1353,12 @@ export enum JSONMode {
|
|
|
1127
1353
|
return JSON.parse<T>(data);
|
|
1128
1354
|
}
|
|
1129
1355
|
// @ts-expect-error: inline
|
|
1130
|
-
@inline function deserializeBox<T>(
|
|
1356
|
+
@inline function deserializeBox<T>(
|
|
1357
|
+
srcStart: usize,
|
|
1358
|
+
srcEnd: usize,
|
|
1359
|
+
dst: usize,
|
|
1360
|
+
ty: T,
|
|
1361
|
+
): T {
|
|
1131
1362
|
return JSON.__deserialize<T>(srcStart, srcEnd, dst);
|
|
1132
1363
|
}
|
|
1133
1364
|
|