json-as 1.3.6 → 1.3.8
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 +45 -0
- package/README.md +1 -1
- package/assembly/deserialize/helpers/uint.ts +4 -1
- package/assembly/deserialize/index/arbitrary.ts +7 -3
- package/assembly/deserialize/index/array.ts +42 -17
- package/assembly/deserialize/index/bool.ts +1 -1
- package/assembly/deserialize/index/date.ts +1 -1
- package/assembly/deserialize/index/float.ts +40 -1
- package/assembly/deserialize/index/integer.ts +68 -1
- package/assembly/deserialize/index/map.ts +1 -1
- package/assembly/deserialize/index/object.ts +1 -1
- package/assembly/deserialize/index/raw.ts +1 -1
- package/assembly/deserialize/index/set.ts +1 -1
- package/assembly/deserialize/index/staticarray.ts +4 -1
- package/assembly/deserialize/index/string.ts +32 -4
- package/assembly/deserialize/index/struct.ts +1 -1
- package/assembly/deserialize/index/typedarray.ts +30 -10
- package/assembly/deserialize/index/unsigned.ts +78 -1
- package/assembly/deserialize/index.ts +1 -0
- package/assembly/deserialize/{simple → naive}/array/arbitrary.ts +24 -5
- package/assembly/deserialize/{simple → naive}/array/array.ts +8 -2
- package/assembly/deserialize/naive/array/bool.ts +68 -0
- package/assembly/deserialize/{simple → naive}/array/box.ts +8 -2
- package/assembly/deserialize/naive/array/float.ts +63 -0
- package/assembly/deserialize/{simple → naive}/array/generic.ts +14 -7
- package/assembly/deserialize/naive/array/integer.ts +86 -0
- package/assembly/deserialize/naive/array/map.ts +47 -0
- package/assembly/deserialize/naive/array/object.ts +47 -0
- package/assembly/deserialize/{simple → naive}/array/raw.ts +34 -7
- package/assembly/deserialize/naive/array/string.ts +69 -0
- package/assembly/deserialize/naive/array/struct.ts +47 -0
- package/assembly/deserialize/{simple → naive}/array.ts +15 -10
- package/assembly/deserialize/{simple → naive}/bool.ts +6 -2
- package/assembly/deserialize/naive/float.ts +135 -0
- package/assembly/deserialize/{simple → naive}/integer.ts +10 -2
- package/assembly/deserialize/{simple → naive}/map.ts +106 -27
- package/assembly/deserialize/{simple → naive}/object.ts +65 -19
- package/assembly/deserialize/{simple → naive}/raw.ts +4 -1
- package/assembly/deserialize/{simple → naive}/set.ts +49 -19
- package/assembly/deserialize/{simple → naive}/staticarray/array.ts +1 -1
- package/assembly/deserialize/{simple → naive}/staticarray/bool.ts +1 -1
- package/assembly/deserialize/{simple → naive}/staticarray/float.ts +1 -1
- package/assembly/deserialize/{simple → naive}/staticarray/integer.ts +1 -1
- package/assembly/deserialize/{simple → naive}/staticarray/string.ts +11 -3
- package/assembly/deserialize/{simple → naive}/staticarray/struct.ts +1 -2
- package/assembly/deserialize/{simple → naive}/staticarray.ts +68 -18
- package/assembly/deserialize/naive/string.ts +199 -0
- package/assembly/deserialize/{simple → naive}/struct.ts +5 -1
- package/assembly/deserialize/{simple → naive}/typedarray.ts +17 -4
- package/assembly/deserialize/{simple → naive}/unsigned.ts +10 -15
- package/assembly/deserialize/simd/array/integer.ts +339 -62
- package/assembly/deserialize/simd/float.ts +303 -0
- package/assembly/deserialize/simd/integer.ts +233 -0
- package/assembly/deserialize/simd/string.ts +266 -107
- package/assembly/deserialize/swar/array/arbitrary.ts +11 -3
- package/assembly/deserialize/swar/array/array.ts +40 -9
- package/assembly/deserialize/swar/array/bool.ts +28 -5
- package/assembly/deserialize/swar/array/box.ts +11 -3
- package/assembly/deserialize/swar/array/float.ts +295 -7
- package/assembly/deserialize/swar/array/generic.ts +28 -7
- package/assembly/deserialize/swar/array/integer.ts +363 -112
- package/assembly/deserialize/swar/array/map.ts +11 -3
- package/assembly/deserialize/swar/array/object.ts +37 -25
- package/assembly/deserialize/swar/array/raw.ts +11 -3
- package/assembly/deserialize/swar/array/shared.ts +63 -14
- package/assembly/deserialize/swar/array/string.ts +140 -7
- package/assembly/deserialize/swar/array/struct.ts +66 -12
- package/assembly/deserialize/swar/array.ts +12 -51
- package/assembly/deserialize/swar/float.ts +304 -0
- package/assembly/deserialize/swar/integer.ts +246 -0
- package/assembly/deserialize/swar/string.ts +213 -294
- package/assembly/deserialize/swar/typedarray.ts +224 -0
- package/assembly/index.d.ts +3 -1
- package/assembly/index.ts +402 -261
- package/assembly/serialize/index/array.ts +1 -1
- package/assembly/serialize/index/bool.ts +1 -1
- package/assembly/serialize/index/date.ts +1 -1
- package/assembly/serialize/index/float.ts +5 -1
- package/assembly/serialize/index/integer.ts +1 -1
- package/assembly/serialize/index/map.ts +1 -1
- package/assembly/serialize/index/raw.ts +1 -1
- package/assembly/serialize/index/set.ts +1 -1
- package/assembly/serialize/index/staticarray.ts +1 -1
- package/assembly/serialize/index/string.ts +1 -1
- package/assembly/serialize/index/struct.ts +1 -1
- package/assembly/serialize/index/typedarray.ts +21 -12
- package/assembly/serialize/index.ts +1 -0
- package/assembly/serialize/naive/array.ts +351 -0
- package/assembly/serialize/{simple → naive}/float.ts +4 -1
- package/assembly/serialize/naive/integer.ts +19 -0
- package/assembly/serialize/{simple → naive}/map.ts +6 -2
- package/assembly/serialize/{simple → naive}/raw.ts +5 -1
- package/assembly/serialize/{simple → naive}/set.ts +6 -1
- package/assembly/serialize/{simple → naive}/staticarray.ts +6 -1
- package/assembly/serialize/{simple → naive}/string.ts +1 -2
- package/assembly/serialize/{simple → naive}/typedarray.ts +10 -3
- package/assembly/serialize/simd/string.ts +6 -2
- package/assembly/serialize/swar/string.ts +15 -141
- 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 +53 -17
- package/assembly/util/itoa-fast.ts +241 -0
- package/assembly/util/masks.ts +18 -1
- package/assembly/util/parsefloat-fast.ts +167 -0
- package/assembly/util/scanValueEnd.ts +78 -0
- package/assembly/util/scientific.ts +132 -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 +27 -6
- package/package.json +15 -11
- 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 +5 -0
- package/transform/lib/index.d.ts.map +1 -1
- package/transform/lib/index.js +1046 -340
- 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/deserialize/simple/arbitrary.ts +0 -23
- package/assembly/deserialize/simple/array/bool.ts +0 -17
- package/assembly/deserialize/simple/array/float.ts +0 -28
- package/assembly/deserialize/simple/array/integer.ts +0 -27
- package/assembly/deserialize/simple/array/map.ts +0 -28
- package/assembly/deserialize/simple/array/object.ts +0 -28
- package/assembly/deserialize/simple/array/string.ts +0 -23
- package/assembly/deserialize/simple/array/struct.ts +0 -28
- package/assembly/deserialize/simple/float.ts +0 -201
- package/assembly/deserialize/simple/string.ts +0 -132
- package/assembly/serialize/simple/arbitrary.ts +0 -79
- package/assembly/serialize/simple/array.ts +0 -86
- package/assembly/serialize/simple/integer.ts +0 -20
- package/assembly/serialize/simple/object.ts +0 -42
- /package/assembly/deserialize/{simple → naive}/date.ts +0 -0
- /package/assembly/serialize/{simple → naive}/bool.ts +0 -0
- /package/assembly/serialize/{simple → naive}/date.ts +0 -0
- /package/assembly/serialize/{simple → naive}/struct.ts +0 -0
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import { JSON } from "../..";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
BRACKET_LEFT,
|
|
4
|
+
BRACKET_RIGHT,
|
|
5
|
+
BRACE_LEFT,
|
|
6
|
+
BRACE_RIGHT,
|
|
7
|
+
CHAR_F,
|
|
8
|
+
CHAR_T,
|
|
9
|
+
COMMA,
|
|
10
|
+
QUOTE,
|
|
11
|
+
} from "../../custom/chars";
|
|
3
12
|
import { isSpace, atoi, scanStringEnd } from "../../util";
|
|
4
13
|
|
|
5
14
|
// @ts-expect-error: Decorator valid here
|
|
@@ -41,16 +50,21 @@ import { isSpace, atoi, scanStringEnd } from "../../util";
|
|
|
41
50
|
return 0;
|
|
42
51
|
}
|
|
43
52
|
|
|
44
|
-
function deserializeSetDirect<T extends Set<any>>(
|
|
45
|
-
|
|
53
|
+
function deserializeSetDirect<T extends Set<any>>(
|
|
54
|
+
srcStart: usize,
|
|
55
|
+
srcEnd: usize,
|
|
56
|
+
out: nonnull<T>,
|
|
57
|
+
): usize {
|
|
58
|
+
if (srcStart >= srcEnd || load<u16>(srcStart) != BRACKET_LEFT)
|
|
59
|
+
throw new Error("Expected '[' at start of set");
|
|
46
60
|
|
|
47
61
|
srcStart += 2;
|
|
48
|
-
|
|
62
|
+
while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
|
|
49
63
|
if (srcStart >= srcEnd) throw new Error("Unterminated set");
|
|
50
64
|
if (load<u16>(srcStart) == BRACKET_RIGHT) return srcStart + 2;
|
|
51
65
|
|
|
52
66
|
while (srcStart < srcEnd) {
|
|
53
|
-
|
|
67
|
+
while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
|
|
54
68
|
const code = load<u16>(srcStart);
|
|
55
69
|
|
|
56
70
|
// @ts-ignore: type
|
|
@@ -80,7 +94,7 @@ function deserializeSetDirect<T extends Set<any>>(srcStart: usize, srcEnd: usize
|
|
|
80
94
|
let ptr = srcStart + 2;
|
|
81
95
|
while (ptr < srcEnd) {
|
|
82
96
|
const next = load<u16>(ptr);
|
|
83
|
-
if (next == COMMA || next == BRACKET_RIGHT ||
|
|
97
|
+
if (next == COMMA || next == BRACKET_RIGHT || isSpace(next)) break;
|
|
84
98
|
ptr += 2;
|
|
85
99
|
}
|
|
86
100
|
// @ts-ignore: type
|
|
@@ -92,7 +106,7 @@ function deserializeSetDirect<T extends Set<any>>(srcStart: usize, srcEnd: usize
|
|
|
92
106
|
let ptr = srcStart + 2;
|
|
93
107
|
while (ptr < srcEnd) {
|
|
94
108
|
const next = load<u16>(ptr);
|
|
95
|
-
if (next == COMMA || next == BRACKET_RIGHT ||
|
|
109
|
+
if (next == COMMA || next == BRACKET_RIGHT || isSpace(next)) break;
|
|
96
110
|
ptr += 2;
|
|
97
111
|
}
|
|
98
112
|
// @ts-ignore: type
|
|
@@ -109,12 +123,12 @@ function deserializeSetDirect<T extends Set<any>>(srcStart: usize, srcEnd: usize
|
|
|
109
123
|
break;
|
|
110
124
|
}
|
|
111
125
|
|
|
112
|
-
|
|
126
|
+
while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
|
|
113
127
|
if (srcStart >= srcEnd) break;
|
|
114
128
|
const next = load<u16>(srcStart);
|
|
115
129
|
if (next == COMMA) {
|
|
116
130
|
srcStart += 2;
|
|
117
|
-
|
|
131
|
+
while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
|
|
118
132
|
continue;
|
|
119
133
|
}
|
|
120
134
|
if (next == BRACKET_RIGHT) return srcStart + 2;
|
|
@@ -124,31 +138,47 @@ function deserializeSetDirect<T extends Set<any>>(srcStart: usize, srcEnd: usize
|
|
|
124
138
|
throw new Error("Failed to parse JSON!");
|
|
125
139
|
}
|
|
126
140
|
|
|
127
|
-
export function deserializeSet<T extends Set<any>>(
|
|
128
|
-
|
|
141
|
+
export function deserializeSet<T extends Set<any>>(
|
|
142
|
+
srcStart: usize,
|
|
143
|
+
srcEnd: usize,
|
|
144
|
+
dst: usize,
|
|
145
|
+
): T {
|
|
146
|
+
const out = changetype<nonnull<T>>(
|
|
147
|
+
dst || changetype<usize>(instantiate<T>()),
|
|
148
|
+
);
|
|
129
149
|
out.clear();
|
|
130
150
|
|
|
131
|
-
while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
|
|
132
151
|
while (srcEnd > srcStart && isSpace(load<u16>(srcEnd - 2))) srcEnd -= 2;
|
|
133
152
|
|
|
134
|
-
if (srcStart >= srcEnd)
|
|
135
|
-
|
|
153
|
+
if (srcStart >= srcEnd)
|
|
154
|
+
throw new Error("Input string had zero length or was all whitespace");
|
|
155
|
+
const end = deserializeSetDirect<T>(srcStart, srcEnd, out);
|
|
136
156
|
if (end != srcEnd) throw new Error("Expected ']' at end of set");
|
|
137
157
|
return out;
|
|
138
158
|
}
|
|
139
159
|
|
|
140
160
|
// @ts-expect-error: Decorator valid here
|
|
141
|
-
@inline
|
|
161
|
+
@inline function deserializeSetBody<T extends Set<any>>(
|
|
162
|
+
srcStart: usize,
|
|
163
|
+
srcEnd: usize,
|
|
164
|
+
out: T,
|
|
165
|
+
): usize {
|
|
142
166
|
changetype<nonnull<T>>(out).clear();
|
|
143
167
|
return deserializeSetDirect<T>(srcStart, srcEnd, changetype<nonnull<T>>(out));
|
|
144
168
|
}
|
|
145
169
|
|
|
146
170
|
// @ts-expect-error: Decorator valid here
|
|
147
|
-
@inline export function deserializeSetField<T extends Set<any>>(
|
|
148
|
-
|
|
171
|
+
@inline export function deserializeSetField<T extends Set<any>>(
|
|
172
|
+
srcStart: usize,
|
|
173
|
+
srcEnd: usize,
|
|
174
|
+
dstObj: usize,
|
|
175
|
+
dstOffset: usize = 0,
|
|
176
|
+
): usize {
|
|
177
|
+
const fieldPtr = dstObj + dstOffset;
|
|
178
|
+
let out = load<T>(fieldPtr);
|
|
149
179
|
if (!changetype<usize>(out)) {
|
|
150
180
|
out = changetype<T>(instantiate<T>());
|
|
151
|
-
store<T>(
|
|
181
|
+
store<T>(fieldPtr, out);
|
|
152
182
|
}
|
|
153
|
-
return
|
|
183
|
+
return deserializeSetBody<T>(srcStart, srcEnd, out);
|
|
154
184
|
}
|
|
@@ -19,7 +19,7 @@ export function deserializeStaticArrayArray<T extends StaticArray<any>>(
|
|
|
19
19
|
ptr += 2;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
const outSize = count
|
|
22
|
+
const outSize = count * sizeof<valueof<T>>();
|
|
23
23
|
const out = changetype<nonnull<T>>(dst || __new(outSize, idof<T>()));
|
|
24
24
|
|
|
25
25
|
// Second pass: populate values
|
|
@@ -20,7 +20,7 @@ export function deserializeStaticArrayBoolean<T extends StaticArray<any>>(
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
// Allocate StaticArray with correct size
|
|
23
|
-
const outSize = count
|
|
23
|
+
const outSize = count * sizeof<valueof<T>>();
|
|
24
24
|
const out = changetype<nonnull<T>>(dst || __new(outSize, idof<T>()));
|
|
25
25
|
|
|
26
26
|
// Second pass: populate values
|
|
@@ -23,7 +23,7 @@ export function deserializeStaticArrayFloat<T extends StaticArray<any>>(
|
|
|
23
23
|
ptr += 2;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
const outSize = count
|
|
26
|
+
const outSize = count * sizeof<valueof<T>>();
|
|
27
27
|
const out = changetype<nonnull<T>>(dst || __new(outSize, idof<T>()));
|
|
28
28
|
|
|
29
29
|
let index = 0;
|
|
@@ -22,7 +22,7 @@ export function deserializeStaticArrayInteger<T extends StaticArray<any>>(
|
|
|
22
22
|
ptr += 2;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
const outSize = count
|
|
25
|
+
const outSize = count * sizeof<valueof<T>>();
|
|
26
26
|
const out = changetype<nonnull<T>>(dst || __new(outSize, idof<T>()));
|
|
27
27
|
|
|
28
28
|
// Second pass: populate values
|
|
@@ -2,7 +2,11 @@ import { JSON } from "../../..";
|
|
|
2
2
|
import { QUOTE } from "../../../custom/chars";
|
|
3
3
|
import { isUnescapedQuote } from "../../../util";
|
|
4
4
|
|
|
5
|
-
export function deserializeStaticArrayString(
|
|
5
|
+
export function deserializeStaticArrayString(
|
|
6
|
+
srcStart: usize,
|
|
7
|
+
srcEnd: usize,
|
|
8
|
+
dst: usize,
|
|
9
|
+
): StaticArray<string> {
|
|
6
10
|
// First pass: count elements using same logic as Array deserializer
|
|
7
11
|
let count: i32 = 0;
|
|
8
12
|
let ptr = srcStart;
|
|
@@ -22,7 +26,9 @@ export function deserializeStaticArrayString(srcStart: usize, srcEnd: usize, dst
|
|
|
22
26
|
|
|
23
27
|
// Allocate StaticArray with correct size
|
|
24
28
|
const outSize = (<usize>count) << alignof<string>();
|
|
25
|
-
const out = changetype<StaticArray<string>>(
|
|
29
|
+
const out = changetype<StaticArray<string>>(
|
|
30
|
+
dst || __new(outSize, idof<StaticArray<string>>()),
|
|
31
|
+
);
|
|
26
32
|
|
|
27
33
|
// Second pass: populate values
|
|
28
34
|
let index = 0;
|
|
@@ -35,7 +41,9 @@ export function deserializeStaticArrayString(srcStart: usize, srcEnd: usize, dst
|
|
|
35
41
|
inString = true;
|
|
36
42
|
lastPos = srcStart;
|
|
37
43
|
} else if (isUnescapedQuote(srcStart)) {
|
|
38
|
-
unchecked(
|
|
44
|
+
unchecked(
|
|
45
|
+
(out[index++] = JSON.__deserialize<string>(lastPos, srcStart + 2)),
|
|
46
|
+
);
|
|
39
47
|
inString = false;
|
|
40
48
|
}
|
|
41
49
|
}
|
|
@@ -12,7 +12,6 @@ export function deserializeStaticArrayStruct<T extends StaticArray<any>>(
|
|
|
12
12
|
srcEnd: usize,
|
|
13
13
|
dst: usize,
|
|
14
14
|
): T {
|
|
15
|
-
while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
|
|
16
15
|
while (srcEnd > srcStart && isSpace(load<u16>(srcEnd - 2))) srcEnd -= 2;
|
|
17
16
|
|
|
18
17
|
if (srcStart - srcEnd == 0)
|
|
@@ -44,7 +43,7 @@ export function deserializeStaticArrayStruct<T extends StaticArray<any>>(
|
|
|
44
43
|
}
|
|
45
44
|
|
|
46
45
|
// Allocate StaticArray with correct size
|
|
47
|
-
const outSize = count
|
|
46
|
+
const outSize = count * sizeof<valueof<T>>();
|
|
48
47
|
const out = changetype<nonnull<T>>(dst || __new(outSize, idof<T>()));
|
|
49
48
|
|
|
50
49
|
// Second pass: populate values
|
|
@@ -4,21 +4,24 @@ import { deserializeArbitraryArray } from "./array/arbitrary";
|
|
|
4
4
|
import { deserializeArrayArray } from "./array/array";
|
|
5
5
|
import { deserializeBooleanArray } from "./array/bool";
|
|
6
6
|
import { deserializeBoxArray } from "./array/box";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { deserializeFloatArray_NAIVE } from "./array/float";
|
|
8
|
+
import { deserializeIntegerArray_NAIVE } from "./array/integer";
|
|
9
9
|
import { deserializeMapArray } from "./array/map";
|
|
10
10
|
import { deserializeObjectArray } from "./array/object";
|
|
11
11
|
import { deserializeRawArray } from "./array/raw";
|
|
12
12
|
import { deserializeStructArray } from "./array/struct";
|
|
13
|
-
import {
|
|
13
|
+
import { deserializeStringArray_NAIVE } from "./array/string";
|
|
14
14
|
import { deserializeStaticArrayBoolean } from "./staticarray/bool";
|
|
15
15
|
import { deserializeStaticArrayFloat } from "./staticarray/float";
|
|
16
16
|
import { deserializeStaticArrayInteger } from "./staticarray/integer";
|
|
17
17
|
import { deserializeStaticArrayString } from "./staticarray/string";
|
|
18
|
-
import { scanValueEnd } from "
|
|
18
|
+
import { scanValueEnd } from "../../util/scanValueEnd";
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
@inline function materializeStaticArray<T extends StaticArray<any>>(
|
|
21
|
+
@inline function materializeStaticArray<T extends StaticArray<any>>(
|
|
22
|
+
src: valueof<T>[],
|
|
23
|
+
dst: usize,
|
|
24
|
+
): T {
|
|
22
25
|
const byteLength = <usize>src.length * sizeof<valueof<T>>();
|
|
23
26
|
let out = dst;
|
|
24
27
|
|
|
@@ -35,7 +38,11 @@ import { scanValueEnd } from "../swar/array/shared";
|
|
|
35
38
|
return typed;
|
|
36
39
|
}
|
|
37
40
|
|
|
38
|
-
export function deserializeStaticArray<T extends StaticArray<any>>(
|
|
41
|
+
export function deserializeStaticArray<T extends StaticArray<any>>(
|
|
42
|
+
srcStart: usize,
|
|
43
|
+
srcEnd: usize,
|
|
44
|
+
dst: usize,
|
|
45
|
+
): T {
|
|
39
46
|
if (isString<valueof<T>>()) {
|
|
40
47
|
return changetype<T>(deserializeStaticArrayString(srcStart, srcEnd, dst));
|
|
41
48
|
} else if (isBoolean<valueof<T>>()) {
|
|
@@ -45,27 +52,61 @@ export function deserializeStaticArray<T extends StaticArray<any>>(srcStart: usi
|
|
|
45
52
|
} else if (isFloat<valueof<T>>()) {
|
|
46
53
|
return deserializeStaticArrayFloat<T>(srcStart, srcEnd, dst);
|
|
47
54
|
} else if (isArray<valueof<T>>()) {
|
|
48
|
-
return materializeStaticArray<T>(
|
|
55
|
+
return materializeStaticArray<T>(
|
|
56
|
+
deserializeArrayArray<valueof<T>[]>(srcStart, srcEnd, 0),
|
|
57
|
+
dst,
|
|
58
|
+
);
|
|
49
59
|
} else if (isManaged<valueof<T>>() || isReference<valueof<T>>()) {
|
|
50
60
|
const type = changetype<nonnull<valueof<T>>>(0);
|
|
51
61
|
if (type instanceof StaticArray) {
|
|
52
|
-
return materializeStaticArray<T>(
|
|
62
|
+
return materializeStaticArray<T>(
|
|
63
|
+
deserializeArrayArray<valueof<T>[]>(srcStart, srcEnd, 0),
|
|
64
|
+
dst,
|
|
65
|
+
);
|
|
53
66
|
} else if (type instanceof JSON.Value) {
|
|
54
|
-
return materializeStaticArray<T>(
|
|
67
|
+
return materializeStaticArray<T>(
|
|
68
|
+
changetype<valueof<T>[]>(
|
|
69
|
+
deserializeArbitraryArray(srcStart, srcEnd, 0),
|
|
70
|
+
),
|
|
71
|
+
dst,
|
|
72
|
+
);
|
|
55
73
|
} else if (type instanceof JSON.Box) {
|
|
56
|
-
return materializeStaticArray<T>(
|
|
74
|
+
return materializeStaticArray<T>(
|
|
75
|
+
changetype<valueof<T>[]>(
|
|
76
|
+
deserializeBoxArray<valueof<T>[]>(srcStart, srcEnd, 0),
|
|
77
|
+
),
|
|
78
|
+
dst,
|
|
79
|
+
);
|
|
57
80
|
} else if (type instanceof JSON.Obj) {
|
|
58
|
-
return materializeStaticArray<T>(
|
|
81
|
+
return materializeStaticArray<T>(
|
|
82
|
+
deserializeObjectArray<valueof<T>[]>(srcStart, srcEnd, 0),
|
|
83
|
+
dst,
|
|
84
|
+
);
|
|
59
85
|
} else if (type instanceof JSON.Raw) {
|
|
60
|
-
return materializeStaticArray<T>(
|
|
86
|
+
return materializeStaticArray<T>(
|
|
87
|
+
changetype<valueof<T>[]>(deserializeRawArray(srcStart, srcEnd, 0)),
|
|
88
|
+
dst,
|
|
89
|
+
);
|
|
61
90
|
} else if (type instanceof Map) {
|
|
62
|
-
return materializeStaticArray<T>(
|
|
91
|
+
return materializeStaticArray<T>(
|
|
92
|
+
deserializeMapArray<valueof<T>[]>(srcStart, srcEnd, 0),
|
|
93
|
+
dst,
|
|
94
|
+
);
|
|
63
95
|
// @ts-ignore: supplied by transform
|
|
64
96
|
} else if (isDefined(type.__DESERIALIZE_CUSTOM)) {
|
|
65
|
-
return materializeStaticArray<T>(
|
|
97
|
+
return materializeStaticArray<T>(
|
|
98
|
+
deserializeStructArray<valueof<T>[]>(srcStart, srcEnd, 0),
|
|
99
|
+
dst,
|
|
100
|
+
);
|
|
66
101
|
// @ts-ignore: supplied by transform
|
|
67
|
-
} else if (
|
|
68
|
-
|
|
102
|
+
} else if (
|
|
103
|
+
isDefined(type.__DESERIALIZE_SLOW) ||
|
|
104
|
+
isDefined(type.__DESERIALIZE_FAST)
|
|
105
|
+
) {
|
|
106
|
+
return materializeStaticArray<T>(
|
|
107
|
+
deserializeStructArray<valueof<T>[]>(srcStart, srcEnd, 0),
|
|
108
|
+
dst,
|
|
109
|
+
);
|
|
69
110
|
}
|
|
70
111
|
}
|
|
71
112
|
|
|
@@ -73,12 +114,21 @@ export function deserializeStaticArray<T extends StaticArray<any>>(srcStart: usi
|
|
|
73
114
|
}
|
|
74
115
|
|
|
75
116
|
|
|
76
|
-
@inline export function deserializeStaticArrayField<T extends StaticArray<any>>(
|
|
117
|
+
@inline export function deserializeStaticArrayField<T extends StaticArray<any>>(
|
|
118
|
+
srcStart: usize,
|
|
119
|
+
srcEnd: usize,
|
|
120
|
+
dstObj: usize,
|
|
121
|
+
dstOffset: usize = 0,
|
|
122
|
+
): usize {
|
|
77
123
|
const valueEnd = scanValueEnd(srcStart, srcEnd);
|
|
78
124
|
if (!valueEnd) throw new Error("Failed to parse JSON!");
|
|
79
125
|
|
|
80
126
|
const fieldPtr = dstObj + dstOffset;
|
|
81
|
-
const out = deserializeStaticArray<T>(
|
|
127
|
+
const out = deserializeStaticArray<T>(
|
|
128
|
+
srcStart,
|
|
129
|
+
valueEnd,
|
|
130
|
+
load<usize>(fieldPtr),
|
|
131
|
+
);
|
|
82
132
|
store<T>(fieldPtr, out);
|
|
83
133
|
return valueEnd;
|
|
84
134
|
}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { bs } from "../../../lib/as-bs";
|
|
2
|
+
import { OBJECT, TOTAL_OVERHEAD } from "rt/common";
|
|
3
|
+
import { __heap_base } from "memory";
|
|
4
|
+
import { BACK_SLASH, QUOTE } from "../../custom/chars";
|
|
5
|
+
import { DESERIALIZE_ESCAPE_TABLE } from "../../globals/tables";
|
|
6
|
+
|
|
7
|
+
// @ts-ignore: inline
|
|
8
|
+
@inline function hexDigit(c: u16): u32 {
|
|
9
|
+
if (c <= 0x39) return c - 0x30; // '0'-'9'
|
|
10
|
+
if (c <= 0x46) return c - 0x37; // 'A'-'F'
|
|
11
|
+
return c - 0x57; // 'a'-'f'
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// @ts-ignore: inline
|
|
15
|
+
@inline function hex4ToU16(srcStart: usize): u16 {
|
|
16
|
+
return <u16>(
|
|
17
|
+
((hexDigit(load<u16>(srcStart)) << 12) |
|
|
18
|
+
(hexDigit(load<u16>(srcStart, 2)) << 8) |
|
|
19
|
+
(hexDigit(load<u16>(srcStart, 4)) << 4) |
|
|
20
|
+
hexDigit(load<u16>(srcStart, 6)))
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// @ts-ignore: inline
|
|
25
|
+
@inline function isHexDigit(c: u16): bool {
|
|
26
|
+
return (
|
|
27
|
+
(c >= 0x30 && c <= 0x39) ||
|
|
28
|
+
(c >= 0x41 && c <= 0x46) ||
|
|
29
|
+
(c >= 0x61 && c <= 0x66)
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Strict RFC 8259 check for the char following a backslash, at [escPtr, srcEnd).
|
|
34
|
+
// Legal escapes: " \ / b f n r t and \uXXXX (4 hex digits). Throws otherwise:
|
|
35
|
+
// unknown escape letter, a trailing backslash, or a short / non-hex \u.
|
|
36
|
+
// @ts-ignore: inline
|
|
37
|
+
@inline function validateEscape(escPtr: usize, srcEnd: usize): void {
|
|
38
|
+
if (escPtr >= srcEnd)
|
|
39
|
+
throw new Error("Invalid JSON string: incomplete escape");
|
|
40
|
+
const code = load<u16>(escPtr);
|
|
41
|
+
if (code == 0x75) {
|
|
42
|
+
// \uXXXX
|
|
43
|
+
if (escPtr + 10 > srcEnd)
|
|
44
|
+
throw new Error("Invalid JSON string: incomplete \\u escape");
|
|
45
|
+
if (
|
|
46
|
+
!isHexDigit(load<u16>(escPtr, 2)) ||
|
|
47
|
+
!isHexDigit(load<u16>(escPtr, 4)) ||
|
|
48
|
+
!isHexDigit(load<u16>(escPtr, 6)) ||
|
|
49
|
+
!isHexDigit(load<u16>(escPtr, 8))
|
|
50
|
+
)
|
|
51
|
+
throw new Error("Invalid JSON string: \\u escape needs 4 hex digits");
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
// short escapes: " \ / b f n r t
|
|
55
|
+
if (
|
|
56
|
+
code != 0x22 &&
|
|
57
|
+
code != 0x5c &&
|
|
58
|
+
code != 0x2f &&
|
|
59
|
+
code != 0x62 &&
|
|
60
|
+
code != 0x66 &&
|
|
61
|
+
code != 0x6e &&
|
|
62
|
+
code != 0x72 &&
|
|
63
|
+
code != 0x74
|
|
64
|
+
)
|
|
65
|
+
throw new Error("Invalid JSON string: illegal escape");
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// @ts-ignore: inline
|
|
69
|
+
@inline export function deserializeString_NAIVE(
|
|
70
|
+
srcStart: usize,
|
|
71
|
+
srcEnd: usize,
|
|
72
|
+
): string {
|
|
73
|
+
// RFC 8259: a string is quote-framed. All callers pass quote-inclusive
|
|
74
|
+
// bounds, so the first and last chars must be `"` (rejects `"` alone and
|
|
75
|
+
// trailing garbage like `""x`).
|
|
76
|
+
if (
|
|
77
|
+
srcEnd - srcStart < 4 ||
|
|
78
|
+
load<u16>(srcStart) != QUOTE ||
|
|
79
|
+
load<u16>(srcEnd - 2) != QUOTE
|
|
80
|
+
)
|
|
81
|
+
throw new Error("Invalid JSON string: missing surrounding quotes");
|
|
82
|
+
// Strip quotes
|
|
83
|
+
srcStart += 2;
|
|
84
|
+
srcEnd -= 2;
|
|
85
|
+
const outStart = bs.offset - bs.buffer;
|
|
86
|
+
bs.ensureSize(u32(srcEnd - srcStart));
|
|
87
|
+
|
|
88
|
+
while (srcStart < srcEnd) {
|
|
89
|
+
const block = load<u16>(srcStart);
|
|
90
|
+
store<u16>(bs.offset, block);
|
|
91
|
+
srcStart += 2;
|
|
92
|
+
|
|
93
|
+
// Early exit
|
|
94
|
+
if (block !== 0x5c) {
|
|
95
|
+
// RFC 8259: literal control chars (U+0000..U+001F) must be escaped.
|
|
96
|
+
if (block < 0x20)
|
|
97
|
+
throw new Error("Invalid JSON string: unescaped control character");
|
|
98
|
+
bs.offset += 2;
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
validateEscape(srcStart, srcEnd);
|
|
103
|
+
const code = load<u16>(srcStart);
|
|
104
|
+
if (code !== 0x75) {
|
|
105
|
+
// Short escapes (\n \t \" \\)
|
|
106
|
+
const block = load<u16>(srcStart);
|
|
107
|
+
const escape = load<u16>(DESERIALIZE_ESCAPE_TABLE + block);
|
|
108
|
+
store<u16>(bs.offset, escape);
|
|
109
|
+
srcStart += 2;
|
|
110
|
+
} else {
|
|
111
|
+
// Unicode escape (\uXXXX)
|
|
112
|
+
const escaped = hex4ToU16(srcStart + 2);
|
|
113
|
+
store<u16>(bs.offset, escaped);
|
|
114
|
+
srcStart += 10;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
bs.offset += 2;
|
|
118
|
+
}
|
|
119
|
+
return bs.sliceOut<string>(outStart);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Writes into the destination field, reusing or resizing the backing string.
|
|
123
|
+
// Mirrors `writeStringToField` in ../swar/string.ts.
|
|
124
|
+
// @ts-ignore: inline
|
|
125
|
+
@inline function writeStringToField(
|
|
126
|
+
dstFieldPtr: usize,
|
|
127
|
+
srcStart: usize,
|
|
128
|
+
byteLength: u32,
|
|
129
|
+
): void {
|
|
130
|
+
if (byteLength == 0) {
|
|
131
|
+
store<usize>(dstFieldPtr, changetype<usize>(""));
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const current = load<usize>(dstFieldPtr);
|
|
136
|
+
let stringPtr: usize;
|
|
137
|
+
if (current >= __heap_base) {
|
|
138
|
+
if (changetype<OBJECT>(current - TOTAL_OVERHEAD).rtSize == byteLength) {
|
|
139
|
+
stringPtr = current;
|
|
140
|
+
} else {
|
|
141
|
+
stringPtr = __renew(current, byteLength);
|
|
142
|
+
store<usize>(dstFieldPtr, stringPtr);
|
|
143
|
+
}
|
|
144
|
+
} else {
|
|
145
|
+
stringPtr = __new(byteLength, idof<string>());
|
|
146
|
+
store<usize>(dstFieldPtr, stringPtr);
|
|
147
|
+
}
|
|
148
|
+
memory.copy(stringPtr, srcStart, byteLength);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// @ts-ignore: inline
|
|
152
|
+
@inline export function deserializeStringField_NAIVE<T extends string | null>(
|
|
153
|
+
srcStart: usize,
|
|
154
|
+
srcEnd: usize,
|
|
155
|
+
dstObj: usize,
|
|
156
|
+
dstOffset: usize = 0,
|
|
157
|
+
): usize {
|
|
158
|
+
const dstFieldPtr = dstObj + dstOffset;
|
|
159
|
+
if (srcStart + 2 > srcEnd || load<u16>(srcStart) != QUOTE)
|
|
160
|
+
abort("Expected leading quote");
|
|
161
|
+
|
|
162
|
+
const payloadStart = srcStart + 2;
|
|
163
|
+
srcStart = payloadStart;
|
|
164
|
+
|
|
165
|
+
bs.offset = bs.buffer;
|
|
166
|
+
bs.ensureSize(<u32>(srcEnd - payloadStart));
|
|
167
|
+
|
|
168
|
+
while (srcStart < srcEnd) {
|
|
169
|
+
const block = load<u16>(srcStart);
|
|
170
|
+
|
|
171
|
+
if (block == QUOTE) {
|
|
172
|
+
writeStringToField(dstFieldPtr, bs.buffer, <u32>(bs.offset - bs.buffer));
|
|
173
|
+
bs.offset = bs.buffer;
|
|
174
|
+
return srcStart + 2;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (block != BACK_SLASH) {
|
|
178
|
+
store<u16>(bs.offset, block);
|
|
179
|
+
bs.offset += 2;
|
|
180
|
+
srcStart += 2;
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const code = load<u16>(srcStart, 2);
|
|
185
|
+
if (code !== 0x75) {
|
|
186
|
+
// Short escapes (\n \t \" \\)
|
|
187
|
+
store<u16>(bs.offset, load<u16>(DESERIALIZE_ESCAPE_TABLE + code));
|
|
188
|
+
srcStart += 4;
|
|
189
|
+
} else {
|
|
190
|
+
// Unicode escape (\uXXXX)
|
|
191
|
+
store<u16>(bs.offset, hex4ToU16(srcStart + 4));
|
|
192
|
+
srcStart += 12;
|
|
193
|
+
}
|
|
194
|
+
bs.offset += 2;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
abort("Expected closing quote");
|
|
198
|
+
return 0;
|
|
199
|
+
}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
export function deserializeStruct<T>(
|
|
1
|
+
export function deserializeStruct<T>(
|
|
2
|
+
srcStart: usize,
|
|
3
|
+
srcEnd: usize,
|
|
4
|
+
dst: usize,
|
|
5
|
+
): T {
|
|
2
6
|
const out = changetype<nonnull<T>>(dst || __new(offsetof<T>(), idof<T>()));
|
|
3
7
|
|
|
4
8
|
// @ts-ignore: supplied by transform
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { COMMA, BRACKET_RIGHT } from "../../custom/chars";
|
|
2
|
-
import {
|
|
2
|
+
import { deserializeFloat_NAIVE } from "./float";
|
|
3
3
|
import { atoi, isSpace } from "../../util";
|
|
4
4
|
|
|
5
5
|
|
|
@@ -25,7 +25,11 @@ import { atoi, isSpace } from "../../util";
|
|
|
25
25
|
return count;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
export function
|
|
28
|
+
export function deserializeTypedArray_NAIVE<T extends ArrayLike<number>>(
|
|
29
|
+
srcStart: usize,
|
|
30
|
+
srcEnd: usize,
|
|
31
|
+
dst: usize = 0,
|
|
32
|
+
): T {
|
|
29
33
|
const count = countTypedArrayElements(srcStart, srcEnd);
|
|
30
34
|
let out = changetype<T>(dst || changetype<usize>(instantiate<T>(count)));
|
|
31
35
|
|
|
@@ -44,7 +48,12 @@ export function deserializeTypedArray<T extends ArrayLike<number>>(srcStart: usi
|
|
|
44
48
|
const code = load<u16>(srcStart);
|
|
45
49
|
if (code == COMMA || code == BRACKET_RIGHT || isSpace(code)) {
|
|
46
50
|
if (isFloat<valueof<T>>()) {
|
|
47
|
-
unchecked(
|
|
51
|
+
unchecked(
|
|
52
|
+
(out[index++] = deserializeFloat_NAIVE<valueof<T>>(
|
|
53
|
+
lastIndex,
|
|
54
|
+
srcStart,
|
|
55
|
+
)),
|
|
56
|
+
);
|
|
48
57
|
} else {
|
|
49
58
|
unchecked((out[index++] = atoi<valueof<T>>(lastIndex, srcStart)));
|
|
50
59
|
}
|
|
@@ -60,7 +69,11 @@ export function deserializeTypedArray<T extends ArrayLike<number>>(srcStart: usi
|
|
|
60
69
|
return out;
|
|
61
70
|
}
|
|
62
71
|
|
|
63
|
-
export function
|
|
72
|
+
export function deserializeArrayBuffer_NAIVE(
|
|
73
|
+
srcStart: usize,
|
|
74
|
+
srcEnd: usize,
|
|
75
|
+
dst: usize = 0,
|
|
76
|
+
): ArrayBuffer {
|
|
64
77
|
const count = countTypedArrayElements(srcStart, srcEnd);
|
|
65
78
|
let out = dst ? changetype<ArrayBuffer>(dst) : new ArrayBuffer(count);
|
|
66
79
|
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
import { atoi } from "../../util/atoi";
|
|
2
2
|
|
|
3
3
|
// @ts-ignore: inline
|
|
4
|
-
@inline export function
|
|
4
|
+
@inline export function deserializeUnsigned_NAIVE<T extends number>(
|
|
5
|
+
srcStart: usize,
|
|
6
|
+
srcEnd: usize,
|
|
7
|
+
): T {
|
|
5
8
|
return atoi<T>(srcStart, srcEnd);
|
|
6
9
|
}
|
|
7
10
|
|
|
8
11
|
// @ts-ignore: inline
|
|
9
|
-
@inline export function
|
|
12
|
+
@inline export function deserializeUnsignedField_NAIVE<T extends number>(
|
|
13
|
+
srcStart: usize,
|
|
14
|
+
srcEnd: usize,
|
|
15
|
+
dstObj: usize,
|
|
16
|
+
dstOffset: usize = 0,
|
|
17
|
+
): usize {
|
|
10
18
|
const fieldPtr = dstObj + dstOffset;
|
|
11
19
|
let digit = <u32>load<u16>(srcStart) - 48;
|
|
12
20
|
if (digit > 9) unreachable();
|
|
@@ -61,16 +69,3 @@ import { atoi } from "../../util/atoi";
|
|
|
61
69
|
return srcStart;
|
|
62
70
|
}
|
|
63
71
|
}
|
|
64
|
-
|
|
65
|
-
export function deserializeUnsignedScan<T extends number>(src: usize, dst: usize): usize {
|
|
66
|
-
let digit = <T>load<u16>(src) - 48;
|
|
67
|
-
if (digit > 9) abort("Found invalid digit");
|
|
68
|
-
let val = digit;
|
|
69
|
-
src += 2;
|
|
70
|
-
while ((digit = <u32>load<u16>(src) - 48) < 10) {
|
|
71
|
-
val = val * 10 + digit;
|
|
72
|
-
src += 2;
|
|
73
|
-
}
|
|
74
|
-
store<T>(dst, val);
|
|
75
|
-
return src;
|
|
76
|
-
}
|