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
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { ptrToStr } from "../../util/ptrToStr";
|
|
2
|
+
import { isSpace } from "../../util";
|
|
3
|
+
|
|
4
|
+
// Strict RFC 8259 number-grammar check over [srcStart, srcEnd) (surrounding
|
|
5
|
+
// whitespace tolerated). Throws on any deviation: leading zeros, a bare `-`, a
|
|
6
|
+
// fraction / exponent with no digits, a `+` sign, hex, Inf/NaN, or trailing
|
|
7
|
+
// garbage. f64.parse alone is lenient (parses a numeric prefix and ignores the
|
|
8
|
+
// rest), so this guard is what makes the naive value path reject malformed
|
|
9
|
+
// numbers like `0e`, `-01`, `1.`, `2.e3`, `0x42`.
|
|
10
|
+
// @ts-ignore: inline
|
|
11
|
+
@inline function validateJSONNumber(srcStart: usize, srcEnd: usize): void {
|
|
12
|
+
let ptr = srcStart;
|
|
13
|
+
while (ptr < srcEnd && isSpace(load<u16>(ptr))) ptr += 2;
|
|
14
|
+
let end = srcEnd;
|
|
15
|
+
while (end > ptr && isSpace(load<u16>(end - 2))) end -= 2;
|
|
16
|
+
if (ptr >= end) throw new Error("Invalid JSON number: empty");
|
|
17
|
+
|
|
18
|
+
if (load<u16>(ptr) == 45) ptr += 2; // optional minus
|
|
19
|
+
if (ptr >= end) throw new Error("Invalid JSON number: bare '-'");
|
|
20
|
+
|
|
21
|
+
// Library extension (non-RFC, intentionally supported + tested): the literals
|
|
22
|
+
// NaN / Infinity / -Infinity. Hand these to f64.parse without strict checking.
|
|
23
|
+
const lead = load<u16>(ptr);
|
|
24
|
+
if (lead == 78 || lead == 110 || lead == 73 || lead == 105) return; // N n I i
|
|
25
|
+
|
|
26
|
+
// integer part: lone 0, or [1-9] digit*
|
|
27
|
+
const first = load<u16>(ptr);
|
|
28
|
+
if (first == 48) {
|
|
29
|
+
ptr += 2;
|
|
30
|
+
if (ptr < end && <u32>(load<u16>(ptr) - 48) <= 9)
|
|
31
|
+
throw new Error("Invalid JSON number: leading zero");
|
|
32
|
+
} else if (<u32>(first - 48) <= 9) {
|
|
33
|
+
ptr += 2;
|
|
34
|
+
while (ptr < end && <u32>(load<u16>(ptr) - 48) <= 9) ptr += 2;
|
|
35
|
+
} else {
|
|
36
|
+
throw new Error("Invalid JSON number: expected digit");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// optional fraction: '.' digit+
|
|
40
|
+
if (ptr < end && load<u16>(ptr) == 46) {
|
|
41
|
+
ptr += 2;
|
|
42
|
+
if (ptr >= end || <u32>(load<u16>(ptr) - 48) > 9)
|
|
43
|
+
throw new Error("Invalid JSON number: fraction needs a digit");
|
|
44
|
+
while (ptr < end && <u32>(load<u16>(ptr) - 48) <= 9) ptr += 2;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// optional exponent: ('e'|'E') ['+'|'-'] digit+
|
|
48
|
+
if (ptr < end) {
|
|
49
|
+
const e = load<u16>(ptr);
|
|
50
|
+
if (e == 101 || e == 69) {
|
|
51
|
+
ptr += 2;
|
|
52
|
+
if (ptr < end) {
|
|
53
|
+
const sign = load<u16>(ptr);
|
|
54
|
+
if (sign == 43 || sign == 45) ptr += 2;
|
|
55
|
+
}
|
|
56
|
+
if (ptr >= end || <u32>(load<u16>(ptr) - 48) > 9)
|
|
57
|
+
throw new Error("Invalid JSON number: exponent needs a digit");
|
|
58
|
+
while (ptr < end && <u32>(load<u16>(ptr) - 48) <= 9) ptr += 2;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (ptr != end) throw new Error("Invalid JSON number: trailing characters");
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// @ts-ignore: inline
|
|
66
|
+
@inline export function deserializeFloat_NAIVE<T>(
|
|
67
|
+
srcStart: usize,
|
|
68
|
+
srcEnd: usize,
|
|
69
|
+
): T {
|
|
70
|
+
validateJSONNumber(srcStart, srcEnd);
|
|
71
|
+
// @ts-ignore
|
|
72
|
+
const type: T = 0;
|
|
73
|
+
// @ts-ignore
|
|
74
|
+
if (type instanceof f64) return f64.parse(ptrToStr(srcStart, srcEnd));
|
|
75
|
+
// @ts-ignore
|
|
76
|
+
return f32.parse(ptrToStr(srcStart, srcEnd));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// @ts-ignore: inline
|
|
80
|
+
@inline function scanFloatEnd(srcStart: usize, srcEnd: usize): usize {
|
|
81
|
+
let ptr = srcStart;
|
|
82
|
+
if (ptr < srcEnd && load<u16>(ptr) == 45) ptr += 2; // optional minus
|
|
83
|
+
|
|
84
|
+
while (ptr < srcEnd) {
|
|
85
|
+
const code = load<u16>(ptr);
|
|
86
|
+
if (<u32>code - 48 > 9) break;
|
|
87
|
+
ptr += 2;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (ptr < srcEnd && load<u16>(ptr) == 46) {
|
|
91
|
+
ptr += 2;
|
|
92
|
+
while (ptr < srcEnd) {
|
|
93
|
+
const code = load<u16>(ptr);
|
|
94
|
+
if (<u32>code - 48 > 9) break;
|
|
95
|
+
ptr += 2;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (ptr < srcEnd) {
|
|
100
|
+
const code = load<u16>(ptr);
|
|
101
|
+
if (code == 101 || code == 69) {
|
|
102
|
+
ptr += 2;
|
|
103
|
+
if (ptr < srcEnd) {
|
|
104
|
+
const sign = load<u16>(ptr);
|
|
105
|
+
if (sign == 45 || sign == 43) ptr += 2;
|
|
106
|
+
}
|
|
107
|
+
while (ptr < srcEnd) {
|
|
108
|
+
const code = load<u16>(ptr);
|
|
109
|
+
if (<u32>code - 48 > 9) break;
|
|
110
|
+
ptr += 2;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return ptr;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// @ts-ignore: inline
|
|
119
|
+
@inline export function deserializeFloatField_NAIVE<T extends number>(
|
|
120
|
+
srcStart: usize,
|
|
121
|
+
srcEnd: usize,
|
|
122
|
+
dstObj: usize,
|
|
123
|
+
dstOffset: usize = 0,
|
|
124
|
+
): usize {
|
|
125
|
+
const fieldPtr = dstObj + dstOffset;
|
|
126
|
+
const end = scanFloatEnd(srcStart, srcEnd);
|
|
127
|
+
|
|
128
|
+
if (sizeof<T>() == sizeof<f32>()) {
|
|
129
|
+
store<f32>(fieldPtr, f32.parse(ptrToStr(srcStart, end)));
|
|
130
|
+
} else {
|
|
131
|
+
store<f64>(fieldPtr, f64.parse(ptrToStr(srcStart, end)));
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return end;
|
|
135
|
+
}
|
|
@@ -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 deserializeInteger_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 deserializeIntegerField_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 negative = false;
|
|
12
20
|
if (load<u16>(srcStart) == 45) {
|
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
import { JSON } from "../..";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
BACK_SLASH,
|
|
4
|
+
COMMA,
|
|
5
|
+
CHAR_F,
|
|
6
|
+
BRACE_LEFT,
|
|
7
|
+
BRACKET_LEFT,
|
|
8
|
+
CHAR_N,
|
|
9
|
+
QUOTE,
|
|
10
|
+
BRACE_RIGHT,
|
|
11
|
+
BRACKET_RIGHT,
|
|
12
|
+
CHAR_T,
|
|
13
|
+
COLON,
|
|
14
|
+
} from "../../custom/chars";
|
|
3
15
|
import { isSpace, isUnescapedQuote, scanStringEnd } from "../../util";
|
|
4
|
-
import { scanValueEnd } from "
|
|
16
|
+
import { scanValueEnd } from "../../util/scanValueEnd";
|
|
5
17
|
|
|
6
18
|
// @ts-ignore: Decorator is valid here
|
|
7
19
|
@inline function deserializeMapKey<T>(start: usize, end: usize): T {
|
|
@@ -10,8 +22,14 @@ import { scanValueEnd } from "../swar/array/shared";
|
|
|
10
22
|
return JSON.parse<T>(keyText);
|
|
11
23
|
}
|
|
12
24
|
|
|
13
|
-
export function deserializeMap<T extends Map<any, any>>(
|
|
14
|
-
|
|
25
|
+
export function deserializeMap<T extends Map<any, any>>(
|
|
26
|
+
srcStart: usize,
|
|
27
|
+
srcEnd: usize,
|
|
28
|
+
dst: usize,
|
|
29
|
+
): T {
|
|
30
|
+
const out = changetype<nonnull<T>>(
|
|
31
|
+
dst || changetype<usize>(instantiate<T>()),
|
|
32
|
+
);
|
|
15
33
|
|
|
16
34
|
let keyStart: usize = 0;
|
|
17
35
|
let keyEnd: usize = 0;
|
|
@@ -19,12 +37,20 @@ export function deserializeMap<T extends Map<any, any>>(srcStart: usize, srcEnd:
|
|
|
19
37
|
let depth = 0;
|
|
20
38
|
let lastIndex: usize = 0;
|
|
21
39
|
|
|
22
|
-
while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
|
|
23
40
|
while (srcEnd > srcStart && isSpace(load<u16>(srcEnd - 2))) srcEnd -= 2; // would like to optimize this later
|
|
24
41
|
|
|
25
|
-
if (srcStart - srcEnd == 0)
|
|
26
|
-
|
|
27
|
-
if (load<u16>(
|
|
42
|
+
if (srcStart - srcEnd == 0)
|
|
43
|
+
throw new Error("Input string had zero length or was all whitespace");
|
|
44
|
+
if (load<u16>(srcStart) != BRACE_LEFT)
|
|
45
|
+
throw new Error(
|
|
46
|
+
"Expected '{' at start of object at position " +
|
|
47
|
+
(srcEnd - srcStart).toString(),
|
|
48
|
+
);
|
|
49
|
+
if (load<u16>(srcEnd - 2) != BRACE_RIGHT)
|
|
50
|
+
throw new Error(
|
|
51
|
+
"Expected '}' at end of object at position " +
|
|
52
|
+
(srcEnd - srcStart).toString(),
|
|
53
|
+
);
|
|
28
54
|
|
|
29
55
|
srcStart += 2;
|
|
30
56
|
while (srcStart < srcEnd) {
|
|
@@ -37,7 +63,11 @@ export function deserializeMap<T extends Map<any, any>>(srcStart: usize, srcEnd:
|
|
|
37
63
|
// console.log("Key: " + ptrToStr(lastIndex, srcStart));
|
|
38
64
|
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart + 2)));
|
|
39
65
|
while (isSpace((code = load<u16>((srcStart += 2))))) {}
|
|
40
|
-
if (code !== COLON)
|
|
66
|
+
if (code !== COLON)
|
|
67
|
+
throw new Error(
|
|
68
|
+
"Expected ':' after key at position " +
|
|
69
|
+
(srcEnd - srcStart).toString(),
|
|
70
|
+
);
|
|
41
71
|
isKey = false;
|
|
42
72
|
} else {
|
|
43
73
|
// console.log("Got key start");
|
|
@@ -51,9 +81,13 @@ export function deserializeMap<T extends Map<any, any>>(srcStart: usize, srcEnd:
|
|
|
51
81
|
if (code == QUOTE) {
|
|
52
82
|
lastIndex = srcStart;
|
|
53
83
|
srcStart = scanStringEnd(srcStart, srcEnd);
|
|
54
|
-
if (srcStart >= srcEnd)
|
|
84
|
+
if (srcStart >= srcEnd)
|
|
85
|
+
throw new Error("Unterminated string in JSON object");
|
|
55
86
|
// @ts-ignore: type
|
|
56
|
-
out.set(
|
|
87
|
+
out.set(
|
|
88
|
+
deserializeMapKey<indexof<T>>(keyStart, keyEnd),
|
|
89
|
+
JSON.__deserialize<valueof<T>>(lastIndex, srcStart + 2),
|
|
90
|
+
);
|
|
57
91
|
srcStart += 2;
|
|
58
92
|
keyStart = 0;
|
|
59
93
|
continue;
|
|
@@ -65,7 +99,10 @@ export function deserializeMap<T extends Map<any, any>>(srcStart: usize, srcEnd:
|
|
|
65
99
|
if (code == COMMA || code == BRACE_RIGHT || isSpace(code)) {
|
|
66
100
|
// console.log("Value (number): " + ptrToStr(lastIndex, srcStart));
|
|
67
101
|
// @ts-ignore: type
|
|
68
|
-
out.set(
|
|
102
|
+
out.set(
|
|
103
|
+
deserializeMapKey<indexof<T>>(keyStart, keyEnd),
|
|
104
|
+
JSON.__deserialize<valueof<T>>(lastIndex, srcStart),
|
|
105
|
+
);
|
|
69
106
|
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
70
107
|
// /* empty */
|
|
71
108
|
// }
|
|
@@ -84,12 +121,16 @@ export function deserializeMap<T extends Map<any, any>>(srcStart: usize, srcEnd:
|
|
|
84
121
|
const code = load<u16>(srcStart);
|
|
85
122
|
if (code == QUOTE) {
|
|
86
123
|
srcStart = scanStringEnd(srcStart, srcEnd);
|
|
87
|
-
if (srcStart >= srcEnd)
|
|
124
|
+
if (srcStart >= srcEnd)
|
|
125
|
+
throw new Error("Unterminated string in JSON object");
|
|
88
126
|
} else if (code == BRACE_RIGHT) {
|
|
89
127
|
if (--depth == 0) {
|
|
90
128
|
// console.log("Value (object): " + ptrToStr(lastIndex, srcStart + 2));
|
|
91
129
|
// @ts-ignore: type
|
|
92
|
-
out.set(
|
|
130
|
+
out.set(
|
|
131
|
+
deserializeMapKey<indexof<T>>(keyStart, keyEnd),
|
|
132
|
+
JSON.__deserialize<valueof<T>>(lastIndex, (srcStart += 2)),
|
|
133
|
+
);
|
|
93
134
|
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
|
|
94
135
|
keyStart = 0;
|
|
95
136
|
// while (isSpace(load<u16>(srcStart))) {
|
|
@@ -108,12 +149,16 @@ export function deserializeMap<T extends Map<any, any>>(srcStart: usize, srcEnd:
|
|
|
108
149
|
const code = load<u16>(srcStart);
|
|
109
150
|
if (code == QUOTE) {
|
|
110
151
|
srcStart = scanStringEnd(srcStart, srcEnd);
|
|
111
|
-
if (srcStart >= srcEnd)
|
|
152
|
+
if (srcStart >= srcEnd)
|
|
153
|
+
throw new Error("Unterminated string in JSON object");
|
|
112
154
|
} else if (code == BRACKET_RIGHT) {
|
|
113
155
|
if (--depth == 0) {
|
|
114
156
|
// console.log("Value (array): " + ptrToStr(lastIndex, srcStart + 2));
|
|
115
157
|
// @ts-ignore: type
|
|
116
|
-
out.set(
|
|
158
|
+
out.set(
|
|
159
|
+
deserializeMapKey<indexof<T>>(keyStart, keyEnd),
|
|
160
|
+
JSON.__deserialize<valueof<T>>(lastIndex, (srcStart += 2)),
|
|
161
|
+
);
|
|
117
162
|
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
|
|
118
163
|
keyStart = 0;
|
|
119
164
|
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
@@ -128,7 +173,10 @@ export function deserializeMap<T extends Map<any, any>>(srcStart: usize, srcEnd:
|
|
|
128
173
|
if (load<u64>(srcStart) == 28429475166421108) {
|
|
129
174
|
// console.log("Value (bool): " + ptrToStr(srcStart, srcStart + 8));
|
|
130
175
|
// @ts-ignore: type
|
|
131
|
-
out.set(
|
|
176
|
+
out.set(
|
|
177
|
+
deserializeMapKey<indexof<T>>(keyStart, keyEnd),
|
|
178
|
+
JSON.__deserialize<valueof<T>>(srcStart, (srcStart += 8)),
|
|
179
|
+
);
|
|
132
180
|
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
133
181
|
// /* empty */
|
|
134
182
|
// }
|
|
@@ -140,7 +188,10 @@ export function deserializeMap<T extends Map<any, any>>(srcStart: usize, srcEnd:
|
|
|
140
188
|
if (load<u64>(srcStart, 2) == 28429466576093281) {
|
|
141
189
|
// console.log("Value (bool): " + ptrToStr(srcStart, srcStart + 10));
|
|
142
190
|
// @ts-ignore: type
|
|
143
|
-
out.set(
|
|
191
|
+
out.set(
|
|
192
|
+
deserializeMapKey<indexof<T>>(keyStart, keyEnd),
|
|
193
|
+
JSON.__deserialize<valueof<T>>(srcStart, (srcStart += 10)),
|
|
194
|
+
);
|
|
144
195
|
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
145
196
|
// /* empty */
|
|
146
197
|
// }
|
|
@@ -152,7 +203,10 @@ export function deserializeMap<T extends Map<any, any>>(srcStart: usize, srcEnd:
|
|
|
152
203
|
if (load<u64>(srcStart) == 30399761348886638) {
|
|
153
204
|
// console.log("Value (null): " + ptrToStr(srcStart, srcStart + 8));
|
|
154
205
|
// @ts-ignore: type
|
|
155
|
-
out.set(
|
|
206
|
+
out.set(
|
|
207
|
+
deserializeMapKey<indexof<T>>(keyStart, keyEnd),
|
|
208
|
+
JSON.__deserialize<valueof<T>>(srcStart, (srcStart += 8)),
|
|
209
|
+
);
|
|
156
210
|
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
157
211
|
/* empty */
|
|
158
212
|
// }
|
|
@@ -163,7 +217,12 @@ export function deserializeMap<T extends Map<any, any>>(srcStart: usize, srcEnd:
|
|
|
163
217
|
} else if (isSpace(code)) {
|
|
164
218
|
srcStart += 2;
|
|
165
219
|
} else {
|
|
166
|
-
throw new Error(
|
|
220
|
+
throw new Error(
|
|
221
|
+
"Unexpected character in JSON object '" +
|
|
222
|
+
String.fromCharCode(code) +
|
|
223
|
+
"' at position " +
|
|
224
|
+
(srcEnd - srcStart).toString(),
|
|
225
|
+
);
|
|
167
226
|
}
|
|
168
227
|
}
|
|
169
228
|
}
|
|
@@ -171,15 +230,22 @@ export function deserializeMap<T extends Map<any, any>>(srcStart: usize, srcEnd:
|
|
|
171
230
|
}
|
|
172
231
|
|
|
173
232
|
|
|
174
|
-
@inline
|
|
233
|
+
@inline function deserializeMapBody<T extends Map<any, any>>(
|
|
234
|
+
srcStart: usize,
|
|
235
|
+
srcEnd: usize,
|
|
236
|
+
out: T,
|
|
237
|
+
): usize {
|
|
175
238
|
changetype<nonnull<T>>(out).clear();
|
|
176
239
|
|
|
177
|
-
if (srcStart >= srcEnd || load<u16>(srcStart) != BRACE_LEFT)
|
|
240
|
+
if (srcStart >= srcEnd || load<u16>(srcStart) != BRACE_LEFT)
|
|
241
|
+
throw new Error("Failed to parse JSON!");
|
|
178
242
|
srcStart += 2;
|
|
243
|
+
while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
|
|
179
244
|
if (srcStart >= srcEnd) throw new Error("Failed to parse JSON!");
|
|
180
245
|
if (load<u16>(srcStart) == BRACE_RIGHT) return srcStart + 2;
|
|
181
246
|
|
|
182
247
|
while (srcStart < srcEnd) {
|
|
248
|
+
while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
|
|
183
249
|
if (load<u16>(srcStart) != QUOTE) break;
|
|
184
250
|
|
|
185
251
|
const keyStart = srcStart + 2;
|
|
@@ -187,20 +253,27 @@ export function deserializeMap<T extends Map<any, any>>(srcStart: usize, srcEnd:
|
|
|
187
253
|
if (keyEnd >= srcEnd) break;
|
|
188
254
|
|
|
189
255
|
srcStart = keyEnd + 2;
|
|
256
|
+
while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
|
|
190
257
|
if (srcStart >= srcEnd || load<u16>(srcStart) != COLON) break;
|
|
191
258
|
srcStart += 2;
|
|
259
|
+
while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
|
|
192
260
|
|
|
193
261
|
const valueEnd = scanValueEnd(srcStart, srcEnd);
|
|
194
262
|
if (!valueEnd || valueEnd <= srcStart) break;
|
|
195
263
|
|
|
196
264
|
// @ts-ignore: type
|
|
197
|
-
changetype<nonnull<T>>(out).set(
|
|
265
|
+
changetype<nonnull<T>>(out).set(
|
|
266
|
+
deserializeMapKey<indexof<T>>(keyStart, keyEnd),
|
|
267
|
+
JSON.__deserialize<valueof<T>>(srcStart, valueEnd),
|
|
268
|
+
);
|
|
198
269
|
srcStart = valueEnd;
|
|
199
270
|
|
|
271
|
+
while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
|
|
200
272
|
if (srcStart >= srcEnd) break;
|
|
201
273
|
const code = load<u16>(srcStart);
|
|
202
274
|
if (code == COMMA) {
|
|
203
275
|
srcStart += 2;
|
|
276
|
+
while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
|
|
204
277
|
continue;
|
|
205
278
|
}
|
|
206
279
|
if (code == BRACE_RIGHT) return srcStart + 2;
|
|
@@ -211,11 +284,17 @@ export function deserializeMap<T extends Map<any, any>>(srcStart: usize, srcEnd:
|
|
|
211
284
|
}
|
|
212
285
|
|
|
213
286
|
|
|
214
|
-
@inline export function deserializeMapField<T extends Map<any, any>>(
|
|
215
|
-
|
|
287
|
+
@inline export function deserializeMapField<T extends Map<any, any>>(
|
|
288
|
+
srcStart: usize,
|
|
289
|
+
srcEnd: usize,
|
|
290
|
+
dstObj: usize,
|
|
291
|
+
dstOffset: usize = 0,
|
|
292
|
+
): usize {
|
|
293
|
+
const fieldPtr = dstObj + dstOffset;
|
|
294
|
+
let out = load<T>(fieldPtr);
|
|
216
295
|
if (!changetype<usize>(out)) {
|
|
217
296
|
out = changetype<T>(instantiate<T>());
|
|
218
|
-
store<T>(
|
|
297
|
+
store<T>(fieldPtr, out);
|
|
219
298
|
}
|
|
220
|
-
return
|
|
299
|
+
return deserializeMapBody<T>(srcStart, srcEnd, out);
|
|
221
300
|
}
|
|
@@ -1,16 +1,30 @@
|
|
|
1
1
|
import { JSON } from "../..";
|
|
2
2
|
import { bs } from "../../../lib/as-bs";
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
BACK_SLASH,
|
|
5
|
+
COMMA,
|
|
6
|
+
CHAR_F,
|
|
7
|
+
BRACE_LEFT,
|
|
8
|
+
BRACKET_LEFT,
|
|
9
|
+
CHAR_N,
|
|
10
|
+
QUOTE,
|
|
11
|
+
BRACE_RIGHT,
|
|
12
|
+
BRACKET_RIGHT,
|
|
13
|
+
CHAR_T,
|
|
14
|
+
COLON,
|
|
15
|
+
} from "../../custom/chars";
|
|
4
16
|
import { isSpace, isUnescapedQuote, scanStringEnd } from "../../util";
|
|
5
17
|
import { ptrToStr } from "../../util/ptrToStr";
|
|
6
|
-
import { deserializeString_SWAR } from "../swar/string";
|
|
7
|
-
import { deserializeArbitrary } from "./arbitrary";
|
|
8
18
|
import { deserializeArray } from "./array";
|
|
9
19
|
import { deserializeBoolean } from "./bool";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
20
|
+
import { deserializeFloat_NAIVE } from "./float";
|
|
21
|
+
import { deserializeString_NAIVE } from "./string";
|
|
12
22
|
|
|
13
|
-
export function deserializeObject(
|
|
23
|
+
export function deserializeObject(
|
|
24
|
+
srcStart: usize,
|
|
25
|
+
srcEnd: usize,
|
|
26
|
+
dst: usize,
|
|
27
|
+
): JSON.Obj {
|
|
14
28
|
const out = changetype<JSON.Obj>(dst || changetype<usize>(new JSON.Obj()));
|
|
15
29
|
|
|
16
30
|
let keyStart: usize = 0;
|
|
@@ -19,12 +33,20 @@ export function deserializeObject(srcStart: usize, srcEnd: usize, dst: usize): J
|
|
|
19
33
|
let depth = 0;
|
|
20
34
|
let lastIndex: usize = 0;
|
|
21
35
|
|
|
22
|
-
while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
|
|
23
36
|
while (srcEnd > srcStart && isSpace(load<u16>(srcEnd - 2))) srcEnd -= 2; // would like to optimize this later
|
|
24
37
|
|
|
25
|
-
if (srcStart - srcEnd == 0)
|
|
26
|
-
|
|
27
|
-
if (load<u16>(
|
|
38
|
+
if (srcStart - srcEnd == 0)
|
|
39
|
+
throw new Error("Input string had zero length or was all whitespace");
|
|
40
|
+
if (load<u16>(srcStart) != BRACE_LEFT)
|
|
41
|
+
throw new Error(
|
|
42
|
+
"Expected '{' at start of object at position " +
|
|
43
|
+
(srcEnd - srcStart).toString(),
|
|
44
|
+
);
|
|
45
|
+
if (load<u16>(srcEnd - 2) != BRACE_RIGHT)
|
|
46
|
+
throw new Error(
|
|
47
|
+
"Expected '}' at end of object at position " +
|
|
48
|
+
(srcEnd - srcStart).toString(),
|
|
49
|
+
);
|
|
28
50
|
|
|
29
51
|
srcStart += 2;
|
|
30
52
|
while (srcStart < srcEnd) {
|
|
@@ -37,7 +59,11 @@ export function deserializeObject(srcStart: usize, srcEnd: usize, dst: usize): J
|
|
|
37
59
|
// console.log("Key: " + ptrToStr(lastIndex, srcStart));
|
|
38
60
|
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart + 2)));
|
|
39
61
|
while (isSpace((code = load<u16>((srcStart += 2))))) {}
|
|
40
|
-
if (code !== COLON)
|
|
62
|
+
if (code !== COLON)
|
|
63
|
+
throw new Error(
|
|
64
|
+
"Expected ':' after key at position " +
|
|
65
|
+
(srcEnd - srcStart).toString(),
|
|
66
|
+
);
|
|
41
67
|
isKey = false;
|
|
42
68
|
} else {
|
|
43
69
|
// console.log("Got key start");
|
|
@@ -51,8 +77,12 @@ export function deserializeObject(srcStart: usize, srcEnd: usize, dst: usize): J
|
|
|
51
77
|
if (code == QUOTE) {
|
|
52
78
|
lastIndex = srcStart;
|
|
53
79
|
srcStart = scanStringEnd(srcStart, srcEnd);
|
|
54
|
-
if (srcStart >= srcEnd)
|
|
55
|
-
|
|
80
|
+
if (srcStart >= srcEnd)
|
|
81
|
+
throw new Error("Unterminated string in JSON object");
|
|
82
|
+
out.set(
|
|
83
|
+
ptrToStr(keyStart, keyEnd),
|
|
84
|
+
deserializeString_NAIVE(lastIndex, srcStart + 2),
|
|
85
|
+
);
|
|
56
86
|
srcStart += 2;
|
|
57
87
|
keyStart = 0;
|
|
58
88
|
continue;
|
|
@@ -63,7 +93,10 @@ export function deserializeObject(srcStart: usize, srcEnd: usize, dst: usize): J
|
|
|
63
93
|
const code = load<u16>(srcStart);
|
|
64
94
|
if (code == COMMA || code == BRACE_RIGHT || isSpace(code)) {
|
|
65
95
|
// console.log("Value (number): " + ptrToStr(lastIndex, srcStart));
|
|
66
|
-
out.set(
|
|
96
|
+
out.set(
|
|
97
|
+
ptrToStr(keyStart, keyEnd),
|
|
98
|
+
deserializeFloat_NAIVE<f64>(lastIndex, srcStart),
|
|
99
|
+
);
|
|
67
100
|
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
68
101
|
// /* empty */
|
|
69
102
|
// }
|
|
@@ -82,11 +115,15 @@ export function deserializeObject(srcStart: usize, srcEnd: usize, dst: usize): J
|
|
|
82
115
|
const code = load<u16>(srcStart);
|
|
83
116
|
if (code == QUOTE) {
|
|
84
117
|
srcStart = scanStringEnd(srcStart, srcEnd);
|
|
85
|
-
if (srcStart >= srcEnd)
|
|
118
|
+
if (srcStart >= srcEnd)
|
|
119
|
+
throw new Error("Unterminated string in JSON object");
|
|
86
120
|
} else if (code == BRACE_RIGHT) {
|
|
87
121
|
if (--depth == 0) {
|
|
88
122
|
// console.log("Value (object): " + ptrToStr(lastIndex, srcStart + 2));
|
|
89
|
-
out.set(
|
|
123
|
+
out.set(
|
|
124
|
+
ptrToStr(keyStart, keyEnd),
|
|
125
|
+
deserializeObject(lastIndex, (srcStart += 2), 0),
|
|
126
|
+
);
|
|
90
127
|
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
|
|
91
128
|
keyStart = 0;
|
|
92
129
|
// while (isSpace(load<u16>(srcStart))) {
|
|
@@ -105,11 +142,15 @@ export function deserializeObject(srcStart: usize, srcEnd: usize, dst: usize): J
|
|
|
105
142
|
const code = load<u16>(srcStart);
|
|
106
143
|
if (code == QUOTE) {
|
|
107
144
|
srcStart = scanStringEnd(srcStart, srcEnd);
|
|
108
|
-
if (srcStart >= srcEnd)
|
|
145
|
+
if (srcStart >= srcEnd)
|
|
146
|
+
throw new Error("Unterminated string in JSON object");
|
|
109
147
|
} else if (code == BRACKET_RIGHT) {
|
|
110
148
|
if (--depth == 0) {
|
|
111
149
|
// console.log("Value (array): " + ptrToStr(lastIndex, srcStart + 2));
|
|
112
|
-
out.set(
|
|
150
|
+
out.set(
|
|
151
|
+
ptrToStr(keyStart, keyEnd),
|
|
152
|
+
deserializeArray<JSON.Value[]>(lastIndex, (srcStart += 2), 0),
|
|
153
|
+
);
|
|
113
154
|
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
|
|
114
155
|
keyStart = 0;
|
|
115
156
|
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
@@ -159,7 +200,12 @@ export function deserializeObject(srcStart: usize, srcEnd: usize, dst: usize): J
|
|
|
159
200
|
} else if (isSpace(code)) {
|
|
160
201
|
srcStart += 2;
|
|
161
202
|
} else {
|
|
162
|
-
throw new Error(
|
|
203
|
+
throw new Error(
|
|
204
|
+
"Unexpected character in JSON object '" +
|
|
205
|
+
String.fromCharCode(code) +
|
|
206
|
+
"' at position " +
|
|
207
|
+
(srcEnd - srcStart).toString(),
|
|
208
|
+
);
|
|
163
209
|
}
|
|
164
210
|
}
|
|
165
211
|
}
|
|
@@ -2,6 +2,9 @@ import { JSON } from "../..";
|
|
|
2
2
|
import { ptrToStr } from "../../util/ptrToStr";
|
|
3
3
|
|
|
4
4
|
// @ts-ignore: inline
|
|
5
|
-
@inline export function deserializeRaw(
|
|
5
|
+
@inline export function deserializeRaw(
|
|
6
|
+
srcStart: usize,
|
|
7
|
+
srcEnd: usize,
|
|
8
|
+
): JSON.Raw {
|
|
6
9
|
return JSON.Raw.from(ptrToStr(srcStart, srcEnd));
|
|
7
10
|
}
|