json-as 1.2.4 → 1.2.6
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/.prettierrc +3 -0
- package/README.md +2 -0
- package/assembly/custom/util.ts +70 -24
- package/assembly/deserialize/simd/string.ts +7 -5
- package/assembly/deserialize/simple/arbitrary.ts +12 -5
- package/assembly/deserialize/simple/array/arbitrary.ts +24 -7
- package/assembly/deserialize/simple/array/array.ts +8 -2
- package/assembly/deserialize/simple/array/bool.ts +8 -2
- package/assembly/deserialize/simple/array/box.ts +8 -2
- package/assembly/deserialize/simple/array/float.ts +8 -2
- 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 +42 -6
- package/assembly/deserialize/simple/array/string.ts +8 -2
- package/assembly/deserialize/simple/array/struct.ts +26 -6
- package/assembly/deserialize/simple/array.ts +5 -1
- package/assembly/deserialize/simple/bool.ts +6 -2
- package/assembly/deserialize/simple/integer.ts +4 -1
- package/assembly/deserialize/simple/map.ts +85 -17
- package/assembly/deserialize/simple/object.ts +64 -12
- package/assembly/deserialize/simple/raw.ts +4 -1
- package/assembly/deserialize/simple/set.ts +37 -11
- package/assembly/deserialize/simple/staticarray/array.ts +12 -3
- package/assembly/deserialize/simple/staticarray/bool.ts +6 -2
- package/assembly/deserialize/simple/staticarray/float.ts +12 -3
- package/assembly/deserialize/simple/staticarray/integer.ts +6 -2
- package/assembly/deserialize/simple/staticarray/string.ts +12 -4
- package/assembly/deserialize/simple/staticarray/struct.ts +30 -7
- package/assembly/deserialize/simple/staticarray.ts +11 -3
- package/assembly/deserialize/simple/string.ts +9 -3
- package/assembly/deserialize/simple/struct.ts +104 -16
- package/assembly/deserialize/swar/string.ts +13 -10
- package/assembly/index.d.ts +5 -3
- package/assembly/index.ts +183 -87
- package/assembly/serialize/simd/string.ts +71 -70
- package/assembly/serialize/simple/raw.ts +5 -1
- package/assembly/serialize/simple/string.ts +9 -10
- package/assembly/serialize/swar/string.ts +35 -33
- package/assembly/test.ts +28 -22
- package/assembly/tsconfig.json +16 -1
- package/assembly/util/concat.ts +5 -1
- package/assembly/util/masks.ts +5 -6
- package/assembly/util/snp.ts +4 -1
- package/assembly/util/swar.ts +5 -7
- package/eslint.config.js +34 -51
- package/lib/as-bs.ts +23 -19
- package/package.json +7 -6
- package/tools/assemblyscript-eslint-local.js +29 -0
- package/tools/assemblyscript-eslint.js +29 -0
- 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.map +1 -1
- package/transform/lib/index.js +694 -152
- 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 +9 -4
- 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 +21 -8
- 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/transform/tsconfig.json +2 -6
- package/.claude/settings.local.json +0 -9
package/.prettierrc
ADDED
package/README.md
CHANGED
|
@@ -420,6 +420,8 @@ The following charts compare JSON-AS (both SWAR and SIMD variants) against JavaS
|
|
|
420
420
|
|
|
421
421
|
> Note: I have focused on extensively optimizing serialization. I used to have deserialization be highly unsafe and extremely fast, but I've since doubled down on safety for deserialization which has negatively affected performance. I will be optimizing soon.
|
|
422
422
|
|
|
423
|
+
> Note on Token: I am currently working on optimizing the token deserialization process. This reflects the *future* performance of this library.
|
|
424
|
+
|
|
423
425
|
### Performance Tuning
|
|
424
426
|
|
|
425
427
|
Instead of using flags for setting options, `json-as` is configured by environmental variables.
|
package/assembly/custom/util.ts
CHANGED
|
@@ -15,7 +15,11 @@
|
|
|
15
15
|
* @param str - Any number. Can include scientific notation.
|
|
16
16
|
*/
|
|
17
17
|
// @ts-ignore: Decorator
|
|
18
|
-
@inline export function snip_fast<T extends number>(
|
|
18
|
+
@inline export function snip_fast<T extends number>(
|
|
19
|
+
str: string,
|
|
20
|
+
len: u32 = 0,
|
|
21
|
+
offset: u32 = 0,
|
|
22
|
+
): T {
|
|
19
23
|
if (isSigned<T>()) {
|
|
20
24
|
const firstChar: u32 = load<u16>(changetype<usize>(str));
|
|
21
25
|
if (firstChar == 48) return 0 as T;
|
|
@@ -35,19 +39,31 @@
|
|
|
35
39
|
// The first char (f) is E or e
|
|
36
40
|
// We push the offset up by two and apply the notation.
|
|
37
41
|
if (load<u16>(changetype<usize>(str) + <usize>offset + 2) == 45) {
|
|
38
|
-
return -(
|
|
42
|
+
return -(
|
|
43
|
+
val /
|
|
44
|
+
10 ** (__atoi_fast<u32>(str, offset + 6, offset + 8) - 1)
|
|
45
|
+
) as T;
|
|
39
46
|
} else {
|
|
40
47
|
// Inlined this operation instead of using a loop
|
|
41
|
-
return -(
|
|
48
|
+
return -(
|
|
49
|
+
val *
|
|
50
|
+
10 ** (__atoi_fast<u32>(str, offset + 2, offset + 4) + 1)
|
|
51
|
+
) as T;
|
|
42
52
|
}
|
|
43
53
|
} else if (high > 57) {
|
|
44
54
|
// The first char (f) is E or e
|
|
45
55
|
// We push the offset up by two and apply the notation.
|
|
46
56
|
if (load<u16>(changetype<usize>(str) + <usize>offset + 4) == 45) {
|
|
47
|
-
return -(
|
|
57
|
+
return -(
|
|
58
|
+
val /
|
|
59
|
+
10 ** (__atoi_fast<u32>(str, offset + 6, offset + 8) - 1)
|
|
60
|
+
) as T;
|
|
48
61
|
} else {
|
|
49
62
|
// Inlined this operation instead of using a loop
|
|
50
|
-
return -(
|
|
63
|
+
return -(
|
|
64
|
+
val *
|
|
65
|
+
10 ** (__atoi_fast<u32>(str, offset + 4, offset + 6) + 1)
|
|
66
|
+
) as T;
|
|
51
67
|
}
|
|
52
68
|
} else {
|
|
53
69
|
val = (val * 100 + (low - 48) * 10 + (high - 48)) as T;
|
|
@@ -62,10 +78,16 @@
|
|
|
62
78
|
// The first char (f) is E or e
|
|
63
79
|
// We push the offset up by two and apply the notation.
|
|
64
80
|
if (load<u16>(changetype<usize>(str) + <usize>offset + 2) == 45) {
|
|
65
|
-
return -(
|
|
81
|
+
return -(
|
|
82
|
+
val /
|
|
83
|
+
10 ** (__atoi_fast<u32>(str, offset + 6, offset + 8) - 1)
|
|
84
|
+
) as T;
|
|
66
85
|
} else {
|
|
67
86
|
// Inlined this operation instead of using a loop
|
|
68
|
-
return -(
|
|
87
|
+
return -(
|
|
88
|
+
val *
|
|
89
|
+
10 ** (__atoi_fast<u32>(str, offset + 2, offset + 4) + 1)
|
|
90
|
+
) as T;
|
|
69
91
|
}
|
|
70
92
|
} else {
|
|
71
93
|
val = (val * 10 + (ch - 48)) as T;
|
|
@@ -84,17 +106,21 @@
|
|
|
84
106
|
// The first char (f) is E or e
|
|
85
107
|
// We push the offset up by two and apply the notation.
|
|
86
108
|
if (load<u16>(changetype<usize>(str) + <usize>offset + 2) == 45) {
|
|
87
|
-
return (val /
|
|
109
|
+
return (val /
|
|
110
|
+
10 ** (__atoi_fast<u32>(str, offset + 6, offset + 8) - 1)) as T;
|
|
88
111
|
} else {
|
|
89
112
|
// Inlined this operation instead of using a loop
|
|
90
|
-
return (val *
|
|
113
|
+
return (val *
|
|
114
|
+
10 ** (__atoi_fast<u32>(str, offset + 2, offset + 4) + 1)) as T;
|
|
91
115
|
}
|
|
92
116
|
} else if (high > 57) {
|
|
93
117
|
if (load<u16>(changetype<usize>(str) + <usize>offset + 4) == 45) {
|
|
94
|
-
return (val /
|
|
118
|
+
return (val /
|
|
119
|
+
10 ** (__atoi_fast<u32>(str, offset + 6, offset + 8) - 1)) as T;
|
|
95
120
|
} else {
|
|
96
121
|
// Inlined this operation instead of using a loop
|
|
97
|
-
return (val *
|
|
122
|
+
return (val *
|
|
123
|
+
10 ** (__atoi_fast<u32>(str, offset + 4, offset + 6) + 1)) as T;
|
|
98
124
|
}
|
|
99
125
|
} else {
|
|
100
126
|
// Optimized with multiplications and shifts.
|
|
@@ -109,10 +135,12 @@
|
|
|
109
135
|
// e is 101 and E is 69.
|
|
110
136
|
if (ch > 57) {
|
|
111
137
|
if (load<u16>(changetype<usize>(str) + <usize>offset + 2) == 45) {
|
|
112
|
-
val = (val /
|
|
138
|
+
val = (val /
|
|
139
|
+
10 ** (__atoi_fast<u32>(str, offset + 6, offset + 8) - 1)) as T;
|
|
113
140
|
} else {
|
|
114
141
|
// Inlined this operation instead of using a loop
|
|
115
|
-
val = (val *
|
|
142
|
+
val = (val *
|
|
143
|
+
10 ** (__atoi_fast<u32>(str, offset + 2, offset + 4) + 1)) as T;
|
|
116
144
|
}
|
|
117
145
|
return val as T;
|
|
118
146
|
} else {
|
|
@@ -137,17 +165,21 @@
|
|
|
137
165
|
// The first char (f) is E or e
|
|
138
166
|
// We push the offset up by two and apply the notation.
|
|
139
167
|
if (load<u16>(changetype<usize>(str) + <usize>offset + 2) == 45) {
|
|
140
|
-
return (val /
|
|
168
|
+
return (val /
|
|
169
|
+
10 ** (__atoi_fast<u32>(str, offset + 6, offset + 8) - 1)) as T;
|
|
141
170
|
} else {
|
|
142
171
|
// Inlined this operation instead of using a loop
|
|
143
|
-
return (val *
|
|
172
|
+
return (val *
|
|
173
|
+
10 ** (__atoi_fast<u32>(str, offset + 2, offset + 4) + 1)) as T;
|
|
144
174
|
}
|
|
145
175
|
} else if (high > 57) {
|
|
146
176
|
if (load<u16>(changetype<usize>(str) + <usize>offset + 4) == 45) {
|
|
147
|
-
return (val /
|
|
177
|
+
return (val /
|
|
178
|
+
10 ** (__atoi_fast<u32>(str, offset + 6, offset + 8) - 1)) as T;
|
|
148
179
|
} else {
|
|
149
180
|
// Inlined this operation instead of using a loop
|
|
150
|
-
return (val *
|
|
181
|
+
return (val *
|
|
182
|
+
10 ** (__atoi_fast<u32>(str, offset + 4, offset + 6) + 1)) as T;
|
|
151
183
|
}
|
|
152
184
|
} else {
|
|
153
185
|
// Optimized with multiplications and shifts.
|
|
@@ -162,10 +194,12 @@
|
|
|
162
194
|
// e is 101 and E is 69.
|
|
163
195
|
if (ch > 57) {
|
|
164
196
|
if (load<u16>(changetype<usize>(str) + <usize>offset + 2) == 45) {
|
|
165
|
-
return (val /
|
|
197
|
+
return (val /
|
|
198
|
+
10 ** (__atoi_fast<u32>(str, offset + 6, offset + 8) - 1)) as T;
|
|
166
199
|
} else {
|
|
167
200
|
// Inlined this operation instead of using a loop
|
|
168
|
-
return (val *
|
|
201
|
+
return (val *
|
|
202
|
+
10 ** (__atoi_fast<u32>(str, offset + 2, offset + 4) + 1)) as T;
|
|
169
203
|
}
|
|
170
204
|
} else {
|
|
171
205
|
val = (val * 10 + (ch - 48)) as T;
|
|
@@ -180,7 +214,11 @@
|
|
|
180
214
|
*/
|
|
181
215
|
|
|
182
216
|
// @ts-ignore
|
|
183
|
-
@inline export function __atoi_fast<T extends number>(
|
|
217
|
+
@inline export function __atoi_fast<T extends number>(
|
|
218
|
+
str: string,
|
|
219
|
+
start: u32 = 0,
|
|
220
|
+
end: u32 = 0,
|
|
221
|
+
): T {
|
|
184
222
|
// @ts-ignore
|
|
185
223
|
let val: T = 0;
|
|
186
224
|
if (!end) end = start + u32(str.length << 1);
|
|
@@ -189,18 +227,21 @@
|
|
|
189
227
|
if (load<u16>(changetype<usize>(str) + <usize>start) == 45) {
|
|
190
228
|
start += 2;
|
|
191
229
|
for (; start < end; start += 2) {
|
|
192
|
-
val = (val * 10 +
|
|
230
|
+
val = (val * 10 +
|
|
231
|
+
(load<u16>(changetype<usize>(str) + <usize>start) - 48)) as T;
|
|
193
232
|
}
|
|
194
233
|
return -val as T;
|
|
195
234
|
} else {
|
|
196
235
|
for (; start < end; start += 2) {
|
|
197
|
-
val = (val * 10 +
|
|
236
|
+
val = (val * 10 +
|
|
237
|
+
(load<u16>(changetype<usize>(str) + <usize>start) - 48)) as T;
|
|
198
238
|
}
|
|
199
239
|
return val as T;
|
|
200
240
|
}
|
|
201
241
|
} else {
|
|
202
242
|
for (; start < end; start += 2) {
|
|
203
|
-
val = (val * 10 +
|
|
243
|
+
val = (val * 10 +
|
|
244
|
+
(load<u16>(changetype<usize>(str) + <usize>start) - 48)) as T;
|
|
204
245
|
}
|
|
205
246
|
return val as T;
|
|
206
247
|
}
|
|
@@ -267,7 +308,12 @@
|
|
|
267
308
|
}
|
|
268
309
|
|
|
269
310
|
// @ts-ignore
|
|
270
|
-
@inline export function containsCodePoint(
|
|
311
|
+
@inline export function containsCodePoint(
|
|
312
|
+
str: string,
|
|
313
|
+
code: u32,
|
|
314
|
+
start: i32,
|
|
315
|
+
end: i32,
|
|
316
|
+
): bool {
|
|
271
317
|
for (let i = start; i <= end; i++) {
|
|
272
318
|
if (unsafeCharCodeAt(str, i) == code) return true;
|
|
273
319
|
}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { bs } from "../../../lib/as-bs";
|
|
2
2
|
import { BACK_SLASH } from "../../custom/chars";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
DESERIALIZE_ESCAPE_TABLE,
|
|
5
|
+
ESCAPE_HEX_TABLE,
|
|
6
|
+
} from "../../globals/tables";
|
|
4
7
|
import { hex4_to_u16_swar } from "../../util/swar";
|
|
5
8
|
|
|
6
9
|
// @ts-expect-error: @lazy is a valid decorator
|
|
7
|
-
@lazy const SPLAT_5C = i16x8.splat(
|
|
10
|
+
@lazy const SPLAT_5C = i16x8.splat(0x5c); // \
|
|
8
11
|
|
|
9
12
|
// Overflow Pattern for Unicode Escapes (READ)
|
|
10
13
|
// \u0001 0 \u0001__| + 0
|
|
@@ -52,7 +55,6 @@ import { hex4_to_u16_swar } from "../../util/swar";
|
|
|
52
55
|
// -------\n 14 -------*| + 0
|
|
53
56
|
// Formula: overflow = lane - 14
|
|
54
57
|
|
|
55
|
-
|
|
56
58
|
/**
|
|
57
59
|
* Deserializes strings back into into their original form using SIMD operations
|
|
58
60
|
* @param src string to deserialize
|
|
@@ -96,7 +98,7 @@ export function deserializeString_SIMD(srcStart: usize, srcEnd: usize): string {
|
|
|
96
98
|
if (code !== 0x75) {
|
|
97
99
|
// Short escapes (\n \t \" \\)
|
|
98
100
|
const escaped = load<u16>(DESERIALIZE_ESCAPE_TABLE + code);
|
|
99
|
-
mask &= mask - i32(escaped ===
|
|
101
|
+
mask &= mask - i32(escaped === 0x5c);
|
|
100
102
|
store<u16>(bs.offset, escaped);
|
|
101
103
|
store<v128>(bs.offset, load<v128>(srcIdx, 4), 2);
|
|
102
104
|
|
|
@@ -135,7 +137,7 @@ export function deserializeString_SIMD(srcStart: usize, srcEnd: usize): string {
|
|
|
135
137
|
srcStart += 2;
|
|
136
138
|
|
|
137
139
|
// Early exit
|
|
138
|
-
if (block !==
|
|
140
|
+
if (block !== 0x5c) {
|
|
139
141
|
bs.offset += 2;
|
|
140
142
|
continue;
|
|
141
143
|
}
|
|
@@ -6,18 +6,25 @@ import { deserializeString } from "./string";
|
|
|
6
6
|
import { deserializeObject } from "./object";
|
|
7
7
|
import { BRACE_LEFT, BRACKET_LEFT, CHAR_N, QUOTE } from "../../custom/chars";
|
|
8
8
|
|
|
9
|
-
export function deserializeArbitrary(
|
|
9
|
+
export function deserializeArbitrary(
|
|
10
|
+
srcStart: usize,
|
|
11
|
+
srcEnd: usize,
|
|
12
|
+
dst: usize,
|
|
13
|
+
): JSON.Value {
|
|
10
14
|
const firstChar = load<u16>(srcStart);
|
|
11
15
|
if (firstChar == QUOTE) {
|
|
12
16
|
return JSON.Value.from(deserializeString(srcStart, srcEnd));
|
|
13
|
-
} else if (firstChar == BRACE_LEFT)
|
|
14
|
-
|
|
17
|
+
} else if (firstChar == BRACE_LEFT)
|
|
18
|
+
return JSON.Value.from(deserializeObject(srcStart, srcEnd, 0));
|
|
19
|
+
else if (firstChar - 48 <= 9 || firstChar == 45)
|
|
20
|
+
return JSON.Value.from(deserializeFloat<f64>(srcStart, srcEnd));
|
|
15
21
|
else if (firstChar == BRACKET_LEFT) {
|
|
16
22
|
return JSON.Value.from(deserializeArray<JSON.Value[]>(srcStart, srcEnd, 0));
|
|
17
|
-
} else if (firstChar == 116 || firstChar == 102)
|
|
23
|
+
} else if (firstChar == 116 || firstChar == 102)
|
|
24
|
+
return JSON.Value.from(deserializeBoolean(srcStart, srcEnd));
|
|
18
25
|
else if (firstChar == CHAR_N) {
|
|
19
26
|
const value = JSON.Value.from<usize>(0);
|
|
20
27
|
return value;
|
|
21
28
|
}
|
|
22
29
|
return unreachable();
|
|
23
|
-
}
|
|
30
|
+
}
|
|
@@ -1,10 +1,27 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
BACK_SLASH,
|
|
3
|
+
BRACE_LEFT,
|
|
4
|
+
BRACE_RIGHT,
|
|
5
|
+
BRACKET_LEFT,
|
|
6
|
+
BRACKET_RIGHT,
|
|
7
|
+
CHAR_F,
|
|
8
|
+
CHAR_N,
|
|
9
|
+
CHAR_T,
|
|
10
|
+
COMMA,
|
|
11
|
+
QUOTE,
|
|
12
|
+
} from "../../../custom/chars";
|
|
2
13
|
import { JSON } from "../../../";
|
|
3
14
|
import { isSpace } from "util/string";
|
|
4
15
|
import { ptrToStr } from "../../../util/ptrToStr";
|
|
5
16
|
|
|
6
|
-
export function deserializeArbitraryArray(
|
|
7
|
-
|
|
17
|
+
export function deserializeArbitraryArray(
|
|
18
|
+
srcStart: usize,
|
|
19
|
+
srcEnd: usize,
|
|
20
|
+
dst: usize,
|
|
21
|
+
): JSON.Value[] {
|
|
22
|
+
const out = changetype<JSON.Value[]>(
|
|
23
|
+
dst || changetype<usize>(instantiate<JSON.Value[]>()),
|
|
24
|
+
);
|
|
8
25
|
let lastIndex: usize = 0;
|
|
9
26
|
let depth: u32 = 0;
|
|
10
27
|
// if (load<u16>(srcStart) != BRACKET_LEFT)
|
|
@@ -70,8 +87,8 @@ export function deserializeArbitraryArray(srcStart: usize, srcEnd: usize, dst: u
|
|
|
70
87
|
if (code == BRACE_RIGHT) {
|
|
71
88
|
if (--depth == 0) {
|
|
72
89
|
// @ts-ignore: type
|
|
73
|
-
out.push(JSON.__deserialize<JSON.Value>(lastIndex, srcStart));
|
|
74
|
-
// console.log("Value (object): " + ptrToStr(lastIndex, srcStart));
|
|
90
|
+
out.push(JSON.__deserialize<JSON.Value>(lastIndex, srcStart + 2));
|
|
91
|
+
// console.log("Value (object): " + ptrToStr(lastIndex, srcStart + 2));
|
|
75
92
|
while (isSpace(load<u16>((srcStart += 2)))) {
|
|
76
93
|
/* empty */
|
|
77
94
|
}
|
|
@@ -89,8 +106,8 @@ export function deserializeArbitraryArray(srcStart: usize, srcEnd: usize, dst: u
|
|
|
89
106
|
if (code == BRACKET_RIGHT) {
|
|
90
107
|
if (--depth == 0) {
|
|
91
108
|
// @ts-ignore: type
|
|
92
|
-
out.push(JSON.__deserialize<JSON.Value>(lastIndex, srcStart));
|
|
93
|
-
// console.log("Value (array): " + ptrToStr(lastIndex, srcStart));
|
|
109
|
+
out.push(JSON.__deserialize<JSON.Value>(lastIndex, srcStart + 2));
|
|
110
|
+
// console.log("Value (array): " + ptrToStr(lastIndex, srcStart + 2));
|
|
94
111
|
while (isSpace(load<u16>((srcStart += 2)))) {
|
|
95
112
|
/* empty */
|
|
96
113
|
}
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { BRACKET_LEFT, BRACKET_RIGHT } from "../../../custom/chars";
|
|
2
2
|
import { JSON } from "../../../";
|
|
3
3
|
|
|
4
|
-
export function deserializeArrayArray<T extends unknown[][]>(
|
|
5
|
-
|
|
4
|
+
export function deserializeArrayArray<T extends unknown[][]>(
|
|
5
|
+
srcStart: usize,
|
|
6
|
+
srcEnd: usize,
|
|
7
|
+
dst: usize,
|
|
8
|
+
): T {
|
|
9
|
+
const out = changetype<nonnull<T>>(
|
|
10
|
+
dst || changetype<usize>(instantiate<T>()),
|
|
11
|
+
);
|
|
6
12
|
let lastIndex: usize = 0;
|
|
7
13
|
let depth: u32 = 0;
|
|
8
14
|
srcStart += 2;
|
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
export function deserializeBooleanArray<T extends boolean[]>(
|
|
2
|
-
|
|
1
|
+
export function deserializeBooleanArray<T extends boolean[]>(
|
|
2
|
+
srcStart: usize,
|
|
3
|
+
srcEnd: usize,
|
|
4
|
+
dst: usize,
|
|
5
|
+
): T {
|
|
6
|
+
const out = changetype<nonnull<T>>(
|
|
7
|
+
dst || changetype<usize>(instantiate<T>()),
|
|
8
|
+
);
|
|
3
9
|
srcStart += 2; // skip [
|
|
4
10
|
while (srcStart < srcEnd) {
|
|
5
11
|
const block = load<u64>(srcStart);
|
|
@@ -2,8 +2,14 @@ import { isSpace } from "../../../util";
|
|
|
2
2
|
import { COMMA, BRACKET_RIGHT } from "../../../custom/chars";
|
|
3
3
|
import { JSON } from "../../..";
|
|
4
4
|
|
|
5
|
-
export function deserializeBoxArray<T extends JSON.Box<any>[]>(
|
|
6
|
-
|
|
5
|
+
export function deserializeBoxArray<T extends JSON.Box<any>[]>(
|
|
6
|
+
srcStart: usize,
|
|
7
|
+
srcEnd: usize,
|
|
8
|
+
dst: usize,
|
|
9
|
+
): T {
|
|
10
|
+
const out = changetype<nonnull<T>>(
|
|
11
|
+
dst || changetype<usize>(instantiate<T>()),
|
|
12
|
+
);
|
|
7
13
|
if (isBoolean<valueof<T>>()) {
|
|
8
14
|
srcStart += 2; // skip [
|
|
9
15
|
while (srcStart < srcEnd) {
|
|
@@ -2,8 +2,14 @@ import { isSpace } from "../../../util";
|
|
|
2
2
|
import { COMMA, BRACKET_RIGHT } from "../../../custom/chars";
|
|
3
3
|
import { JSON } from "../../..";
|
|
4
4
|
|
|
5
|
-
export function deserializeFloatArray<T extends number[]>(
|
|
6
|
-
|
|
5
|
+
export function deserializeFloatArray<T extends number[]>(
|
|
6
|
+
srcStart: usize,
|
|
7
|
+
srcEnd: usize,
|
|
8
|
+
dst: usize,
|
|
9
|
+
): T {
|
|
10
|
+
const out = changetype<nonnull<T>>(
|
|
11
|
+
dst || changetype<usize>(instantiate<T>()),
|
|
12
|
+
);
|
|
7
13
|
let lastIndex: usize = 0;
|
|
8
14
|
while (srcStart < srcEnd) {
|
|
9
15
|
const code = load<u16>(srcStart);
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { atoi, isSpace } from "../../../util";
|
|
2
2
|
import { COMMA, BRACKET_RIGHT } from "../../../custom/chars";
|
|
3
3
|
|
|
4
|
-
export function deserializeIntegerArray<T extends number[]>(
|
|
5
|
-
|
|
4
|
+
export function deserializeIntegerArray<T extends number[]>(
|
|
5
|
+
srcStart: usize,
|
|
6
|
+
srcEnd: usize,
|
|
7
|
+
dst: usize,
|
|
8
|
+
): T {
|
|
9
|
+
const out = changetype<nonnull<T>>(
|
|
10
|
+
dst || changetype<usize>(instantiate<T>()),
|
|
11
|
+
);
|
|
6
12
|
let lastIndex: usize = 0;
|
|
7
13
|
while (srcStart < srcEnd) {
|
|
8
14
|
const code = load<u16>(srcStart);
|
|
@@ -1,19 +1,39 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
BRACE_LEFT,
|
|
3
|
+
BRACE_RIGHT,
|
|
4
|
+
BRACKET_LEFT,
|
|
5
|
+
BRACKET_RIGHT,
|
|
6
|
+
} from "../../../custom/chars";
|
|
2
7
|
import { JSON } from "../../..";
|
|
3
8
|
import { isSpace } from "util/string";
|
|
4
9
|
|
|
5
|
-
export function deserializeMapArray<T extends Map<any, any>[]>(
|
|
6
|
-
|
|
10
|
+
export function deserializeMapArray<T extends Map<any, any>[]>(
|
|
11
|
+
srcStart: usize,
|
|
12
|
+
srcEnd: usize,
|
|
13
|
+
dst: usize,
|
|
14
|
+
): T {
|
|
15
|
+
const out = changetype<nonnull<T>>(
|
|
16
|
+
dst || changetype<usize>(instantiate<T>()),
|
|
17
|
+
);
|
|
7
18
|
let lastIndex: usize = 0;
|
|
8
19
|
let depth: u32 = 0;
|
|
9
20
|
|
|
10
21
|
while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
|
|
11
22
|
while (srcEnd > srcStart && isSpace(load<u16>(srcEnd - 2))) srcEnd -= 2;
|
|
12
23
|
|
|
13
|
-
if (srcStart - srcEnd == 0)
|
|
24
|
+
if (srcStart - srcEnd == 0)
|
|
25
|
+
throw new Error("Input string had zero length or was all whitespace");
|
|
14
26
|
|
|
15
|
-
if (load<u16>(srcStart) != BRACKET_LEFT)
|
|
16
|
-
|
|
27
|
+
if (load<u16>(srcStart) != BRACKET_LEFT)
|
|
28
|
+
throw new Error(
|
|
29
|
+
"Expected '[' at start of object at position " +
|
|
30
|
+
(srcEnd - srcStart).toString(),
|
|
31
|
+
);
|
|
32
|
+
if (load<u16>(srcEnd - 2) != BRACKET_RIGHT)
|
|
33
|
+
throw new Error(
|
|
34
|
+
"Expected ']' at end of object at position " +
|
|
35
|
+
(srcEnd - srcStart).toString(),
|
|
36
|
+
);
|
|
17
37
|
|
|
18
38
|
while (srcStart < srcEnd) {
|
|
19
39
|
const code = load<u16>(srcStart);
|
|
@@ -1,19 +1,39 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
BRACE_LEFT,
|
|
3
|
+
BRACE_RIGHT,
|
|
4
|
+
BRACKET_LEFT,
|
|
5
|
+
BRACKET_RIGHT,
|
|
6
|
+
} from "../../../custom/chars";
|
|
2
7
|
import { JSON } from "../../..";
|
|
3
8
|
import { isSpace } from "util/string";
|
|
4
9
|
|
|
5
|
-
export function deserializeObjectArray<T extends unknown[]>(
|
|
6
|
-
|
|
10
|
+
export function deserializeObjectArray<T extends unknown[]>(
|
|
11
|
+
srcStart: usize,
|
|
12
|
+
srcEnd: usize,
|
|
13
|
+
dst: usize,
|
|
14
|
+
): T {
|
|
15
|
+
const out = changetype<nonnull<T>>(
|
|
16
|
+
dst || changetype<usize>(instantiate<T>()),
|
|
17
|
+
);
|
|
7
18
|
let lastIndex: usize = 0;
|
|
8
19
|
let depth: u32 = 0;
|
|
9
20
|
|
|
10
21
|
while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
|
|
11
22
|
while (srcEnd > srcStart && isSpace(load<u16>(srcEnd - 2))) srcEnd -= 2;
|
|
12
23
|
|
|
13
|
-
if (srcStart - srcEnd == 0)
|
|
24
|
+
if (srcStart - srcEnd == 0)
|
|
25
|
+
throw new Error("Input string had zero length or was all whitespace");
|
|
14
26
|
|
|
15
|
-
if (load<u16>(srcStart) != BRACKET_LEFT)
|
|
16
|
-
|
|
27
|
+
if (load<u16>(srcStart) != BRACKET_LEFT)
|
|
28
|
+
throw new Error(
|
|
29
|
+
"Expected '[' at start of object at position " +
|
|
30
|
+
(srcEnd - srcStart).toString(),
|
|
31
|
+
);
|
|
32
|
+
if (load<u16>(srcEnd - 2) != BRACKET_RIGHT)
|
|
33
|
+
throw new Error(
|
|
34
|
+
"Expected ']' at end of object at position " +
|
|
35
|
+
(srcEnd - srcStart).toString(),
|
|
36
|
+
);
|
|
17
37
|
|
|
18
38
|
while (srcStart < srcEnd) {
|
|
19
39
|
const code = load<u16>(srcStart);
|
|
@@ -1,11 +1,28 @@
|
|
|
1
1
|
import { isSpace } from "../../../util";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
COMMA,
|
|
4
|
+
BRACKET_RIGHT,
|
|
5
|
+
QUOTE,
|
|
6
|
+
BRACE_LEFT,
|
|
7
|
+
BRACE_RIGHT,
|
|
8
|
+
BRACKET_LEFT,
|
|
9
|
+
BACK_SLASH,
|
|
10
|
+
CHAR_T,
|
|
11
|
+
CHAR_F,
|
|
12
|
+
CHAR_N,
|
|
13
|
+
} from "../../../custom/chars";
|
|
3
14
|
import { JSON } from "../../..";
|
|
4
15
|
import { ptrToStr } from "../../../util/ptrToStr";
|
|
5
16
|
|
|
6
|
-
export function deserializeRawArray(
|
|
17
|
+
export function deserializeRawArray(
|
|
18
|
+
srcStart: usize,
|
|
19
|
+
srcEnd: usize,
|
|
20
|
+
dst: usize,
|
|
21
|
+
): JSON.Raw[] {
|
|
7
22
|
// console.log("data: " + ptrToStr(srcStart, srcEnd));
|
|
8
|
-
const out = changetype<JSON.Raw[]>(
|
|
23
|
+
const out = changetype<JSON.Raw[]>(
|
|
24
|
+
dst || changetype<usize>(instantiate<JSON.Raw[]>()),
|
|
25
|
+
);
|
|
9
26
|
let lastIndex: usize = 0;
|
|
10
27
|
let depth = 0;
|
|
11
28
|
srcStart += 2;
|
|
@@ -48,7 +65,13 @@ export function deserializeRawArray(srcStart: usize, srcEnd: usize, dst: usize):
|
|
|
48
65
|
const code = load<u16>(srcStart);
|
|
49
66
|
if (code == QUOTE) {
|
|
50
67
|
srcStart += 2;
|
|
51
|
-
while (
|
|
68
|
+
while (
|
|
69
|
+
!(
|
|
70
|
+
load<u16>(srcStart) == QUOTE &&
|
|
71
|
+
load<u16>(srcStart - 2) != BACK_SLASH
|
|
72
|
+
)
|
|
73
|
+
)
|
|
74
|
+
srcStart += 2;
|
|
52
75
|
} else if (code == BRACE_RIGHT) {
|
|
53
76
|
if (--depth == 0) {
|
|
54
77
|
// console.log("Value (object): " + ptrToStr(lastIndex, srcStart + 2));
|
|
@@ -67,7 +90,13 @@ export function deserializeRawArray(srcStart: usize, srcEnd: usize, dst: usize):
|
|
|
67
90
|
const code = load<u16>(srcStart);
|
|
68
91
|
if (code == QUOTE) {
|
|
69
92
|
srcStart += 2;
|
|
70
|
-
while (
|
|
93
|
+
while (
|
|
94
|
+
!(
|
|
95
|
+
load<u16>(srcStart) == QUOTE &&
|
|
96
|
+
load<u16>(srcStart - 2) != BACK_SLASH
|
|
97
|
+
)
|
|
98
|
+
)
|
|
99
|
+
srcStart += 2;
|
|
71
100
|
} else if (code == BRACKET_RIGHT) {
|
|
72
101
|
if (--depth == 0) {
|
|
73
102
|
// console.log("Value (array): " + ptrToStr(lastIndex, srcStart + 2));
|
|
@@ -99,7 +128,14 @@ export function deserializeRawArray(srcStart: usize, srcEnd: usize, dst: usize):
|
|
|
99
128
|
} else if (isSpace(code)) {
|
|
100
129
|
srcStart += 2;
|
|
101
130
|
} else {
|
|
102
|
-
throw new Error(
|
|
131
|
+
throw new Error(
|
|
132
|
+
"Unexpected character in JSON object '" +
|
|
133
|
+
String.fromCharCode(code) +
|
|
134
|
+
"' at position " +
|
|
135
|
+
(srcEnd - srcStart).toString() +
|
|
136
|
+
" " +
|
|
137
|
+
ptrToStr(lastIndex, srcStart + 10),
|
|
138
|
+
);
|
|
103
139
|
}
|
|
104
140
|
}
|
|
105
141
|
return out;
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { JSON } from "../../..";
|
|
2
2
|
import { BACK_SLASH, QUOTE } from "../../../custom/chars";
|
|
3
3
|
|
|
4
|
-
export function deserializeStringArray(
|
|
5
|
-
|
|
4
|
+
export function deserializeStringArray(
|
|
5
|
+
srcStart: usize,
|
|
6
|
+
srcEnd: usize,
|
|
7
|
+
dst: usize,
|
|
8
|
+
): string[] {
|
|
9
|
+
const out = changetype<string[]>(
|
|
10
|
+
dst || changetype<usize>(instantiate<string[]>()),
|
|
11
|
+
);
|
|
6
12
|
let lastPos: usize = 2;
|
|
7
13
|
let inString = false;
|
|
8
14
|
while (srcStart < srcEnd) {
|
|
@@ -1,19 +1,39 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
BRACE_LEFT,
|
|
3
|
+
BRACE_RIGHT,
|
|
4
|
+
BRACKET_LEFT,
|
|
5
|
+
BRACKET_RIGHT,
|
|
6
|
+
} from "../../../custom/chars";
|
|
2
7
|
import { JSON } from "../../..";
|
|
3
8
|
import { isSpace } from "util/string";
|
|
4
9
|
|
|
5
|
-
export function deserializeStructArray<T extends unknown[]>(
|
|
6
|
-
|
|
10
|
+
export function deserializeStructArray<T extends unknown[]>(
|
|
11
|
+
srcStart: usize,
|
|
12
|
+
srcEnd: usize,
|
|
13
|
+
dst: usize,
|
|
14
|
+
): T {
|
|
15
|
+
const out = changetype<nonnull<T>>(
|
|
16
|
+
dst || changetype<usize>(instantiate<T>()),
|
|
17
|
+
);
|
|
7
18
|
let lastIndex: usize = 0;
|
|
8
19
|
let depth: u32 = 0;
|
|
9
20
|
|
|
10
21
|
while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
|
|
11
22
|
while (srcEnd > srcStart && isSpace(load<u16>(srcEnd - 2))) srcEnd -= 2;
|
|
12
23
|
|
|
13
|
-
if (srcStart - srcEnd == 0)
|
|
24
|
+
if (srcStart - srcEnd == 0)
|
|
25
|
+
throw new Error("Input string had zero length or was all whitespace");
|
|
14
26
|
|
|
15
|
-
if (load<u16>(srcStart) != BRACKET_LEFT)
|
|
16
|
-
|
|
27
|
+
if (load<u16>(srcStart) != BRACKET_LEFT)
|
|
28
|
+
throw new Error(
|
|
29
|
+
"Expected '[' at start of object at position " +
|
|
30
|
+
(srcEnd - srcStart).toString(),
|
|
31
|
+
);
|
|
32
|
+
if (load<u16>(srcEnd - 2) != BRACKET_RIGHT)
|
|
33
|
+
throw new Error(
|
|
34
|
+
"Expected ']' at end of object at position " +
|
|
35
|
+
(srcEnd - srcStart).toString(),
|
|
36
|
+
);
|
|
17
37
|
|
|
18
38
|
while (srcStart < srcEnd) {
|
|
19
39
|
const code = load<u16>(srcStart);
|