json-as 1.0.0-beta.9 → 1.0.1
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/.github/workflows/{nodejs.yml → tests.yml} +1 -1
- package/{CHANGELOG → CHANGELOG.md} +45 -0
- package/README.md +147 -93
- package/assembly/__benches__/abc.bench.ts +21 -0
- package/assembly/__benches__/large.bench.ts +174 -0
- package/assembly/__benches__/lib/index.ts +26 -0
- package/assembly/__benches__/medium.bench.ts +46 -0
- package/assembly/__benches__/small.bench.ts +33 -0
- package/assembly/__benches__/vec3.bench.ts +72 -0
- package/assembly/__tests__/array.spec.ts +42 -0
- package/assembly/__tests__/float.spec.ts +3 -3
- package/assembly/__tests__/map.spec.ts +7 -0
- package/assembly/__tests__/raw.spec.ts +4 -5
- package/assembly/__tests__/struct.spec.ts +2 -2
- package/assembly/deserialize/simple/arbitrary.ts +8 -4
- package/assembly/deserialize/simple/array/arbitrary.ts +6 -6
- package/assembly/deserialize/simple/array/array.ts +4 -3
- package/assembly/deserialize/simple/array/bool.ts +7 -7
- package/assembly/deserialize/simple/array/float.ts +2 -2
- package/assembly/deserialize/simple/array/integer.ts +1 -1
- package/assembly/deserialize/simple/array/map.ts +1 -1
- package/assembly/deserialize/simple/array/string.ts +3 -3
- package/assembly/deserialize/simple/array/struct.ts +14 -3
- package/assembly/deserialize/simple/array.ts +3 -0
- package/assembly/deserialize/simple/map.ts +93 -75
- package/assembly/deserialize/simple/object.ts +26 -16
- package/assembly/deserialize/simple/struct.ts +31 -19
- package/assembly/index.ts +14 -11
- package/assembly/serialize/simple/array.ts +1 -0
- package/assembly/serialize/simple/bool.ts +1 -0
- package/assembly/serialize/simple/date.ts +1 -0
- package/assembly/serialize/simple/float.ts +1 -0
- package/assembly/serialize/simple/integer.ts +1 -0
- package/assembly/serialize/simple/map.ts +1 -0
- package/assembly/serialize/simple/object.ts +1 -0
- package/assembly/serialize/simple/raw.ts +1 -0
- package/assembly/serialize/simple/string.ts +1 -0
- package/assembly/test.ts +18 -0
- package/bench/abc.bench.ts +20 -0
- package/bench/large.bench.ts +126 -0
- package/bench/medium.bench.ts +43 -0
- package/bench/small.bench.ts +30 -0
- package/bench/vec3.bench.ts +26 -0
- package/index.ts +1 -1
- package/package.json +24 -26
- package/run-bench.as.sh +27 -0
- package/run-bench.js.sh +12 -0
- package/run-tests.sh +14 -2
- package/transform/lib/index.js +29 -69
- package/transform/lib/index.js.map +1 -1
- package/transform/src/index.ts +55 -71
- package/.gitmodules +0 -0
- package/assembly/__benches__/misc.bench.ts +0 -47
- package/assembly/__benches__/schemas.ts +0 -25
- package/assembly/__benches__/string.bench.ts +0 -23
- package/assembly/__benches__/struct.bench.ts +0 -21
- package/assembly/as-bs.d.ts +0 -53
- package/bench/schemas.ts +0 -5
- package/bench/string.bench.ts +0 -16
- /package/bench/{bench.ts → lib/bench.ts} +0 -0
|
@@ -1,154 +1,172 @@
|
|
|
1
1
|
import { JSON } from "../..";
|
|
2
2
|
import { BACK_SLASH, COMMA, CHAR_F, BRACE_LEFT, BRACKET_LEFT, CHAR_N, QUOTE, BRACE_RIGHT, BRACKET_RIGHT, CHAR_T, COLON } from "../../custom/chars";
|
|
3
3
|
import { isSpace } from "../../util";
|
|
4
|
+
import { ptrToStr } from "../../util/ptrToStr";
|
|
4
5
|
|
|
5
6
|
export function deserializeMap<T extends Map<any, any>>(srcStart: usize, srcEnd: usize, dst: usize): T {
|
|
6
|
-
const out = changetype<T
|
|
7
|
+
const out = changetype<nonnull<T>>(dst || changetype<usize>(instantiate<T>()));
|
|
7
8
|
// @ts-ignore: type
|
|
8
9
|
if (!isString<indexof<T>>() && !isInteger<indexof<T>>() && !isFloat<indexof<T>>()) throw new Error("Map key must also be a valid JSON key!");
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
let
|
|
11
|
+
let keyStart: usize = 0;
|
|
12
|
+
let keyEnd: usize = 0;
|
|
12
13
|
let isKey = false;
|
|
13
14
|
let depth = 0;
|
|
14
|
-
let lastIndex = 0;
|
|
15
|
+
let lastIndex: usize = 0;
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
|
|
18
|
+
while (srcEnd > srcStart && isSpace(load<u16>(srcEnd - 2))) srcEnd -= 2; // would like to optimize this later
|
|
18
19
|
|
|
20
|
+
if (srcStart - srcEnd == 0)
|
|
21
|
+
throw new Error("Input string had zero length or was all whitespace");
|
|
22
|
+
if (load<u16>(srcStart) != BRACE_LEFT) throw new Error("Expected '{' at start of object at position " + (srcEnd - srcStart).toString());
|
|
23
|
+
if (load<u16>(srcEnd - 2) != BRACE_RIGHT) throw new Error("Expected '}' at end of object at position " + (srcEnd - srcStart).toString());
|
|
24
|
+
|
|
25
|
+
srcStart += 2;
|
|
19
26
|
while (srcStart < srcEnd) {
|
|
20
27
|
let code = load<u16>(srcStart); // while (isSpace(code)) code = load<u16>(srcStart += 2);
|
|
21
|
-
if (
|
|
28
|
+
if (keyStart == 0) {
|
|
22
29
|
if (code == QUOTE && load<u16>(srcStart - 2) !== BACK_SLASH) {
|
|
23
30
|
if (isKey) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
31
|
+
keyStart = lastIndex;
|
|
32
|
+
keyEnd = srcStart;
|
|
33
|
+
// console.log("Key: " + ptrToStr(lastIndex, srcStart));
|
|
34
|
+
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart + 2)));
|
|
35
|
+
while (isSpace((code = load<u16>((srcStart += 2))))) { }
|
|
36
|
+
if (code !== COLON) throw new Error("Expected ':' after key at position " + (srcEnd - srcStart).toString());
|
|
29
37
|
isKey = false;
|
|
30
38
|
} else {
|
|
31
|
-
|
|
39
|
+
// console.log("Got key start");
|
|
40
|
+
isKey = true; // i don't like this
|
|
32
41
|
lastIndex = srcStart + 2;
|
|
33
42
|
}
|
|
34
43
|
}
|
|
35
44
|
// isKey = !isKey;
|
|
36
45
|
srcStart += 2;
|
|
37
46
|
} else {
|
|
38
|
-
|
|
39
|
-
if (isString<valueof<T>>() && code == QUOTE) {
|
|
47
|
+
if (code == QUOTE) {
|
|
40
48
|
lastIndex = srcStart;
|
|
41
49
|
srcStart += 2;
|
|
42
50
|
while (srcStart < srcEnd) {
|
|
43
51
|
const code = load<u16>(srcStart);
|
|
44
52
|
if (code == QUOTE && load<u16>(srcStart - 2) !== BACK_SLASH) {
|
|
45
|
-
|
|
46
|
-
/* empty */
|
|
47
|
-
}
|
|
53
|
+
// console.log("Value (string): " + ptrToStr(lastIndex, srcStart + 2));
|
|
48
54
|
// @ts-ignore: type
|
|
49
|
-
out.set(
|
|
50
|
-
|
|
55
|
+
out.set(ptrToStr(keyStart, keyEnd), JSON.__deserialize<valueof<T>>(lastIndex, srcStart + 2));
|
|
56
|
+
// while (isSpace(load<u16>(srcStart))) srcStart += 2;
|
|
57
|
+
srcStart += 4;
|
|
58
|
+
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
|
|
59
|
+
keyStart = 0;
|
|
51
60
|
break;
|
|
52
61
|
}
|
|
53
62
|
srcStart += 2;
|
|
54
63
|
}
|
|
55
|
-
|
|
56
|
-
} else if ((!isBoolean<valueof<T>>() && isInteger<valueof<T>>() && code - 48 <= 9) || code == 45) {
|
|
64
|
+
} else if (code - 48 <= 9 || code == 45) {
|
|
57
65
|
lastIndex = srcStart;
|
|
58
66
|
srcStart += 2;
|
|
59
67
|
while (srcStart < srcEnd) {
|
|
60
68
|
const code = load<u16>(srcStart);
|
|
61
|
-
if (code == COMMA ||
|
|
69
|
+
if (code == COMMA || code == BRACE_RIGHT || isSpace(code)) {
|
|
70
|
+
// console.log("Value (number): " + ptrToStr(lastIndex, srcStart));
|
|
62
71
|
// @ts-ignore: type
|
|
63
|
-
out.set(
|
|
64
|
-
while (isSpace(load<u16>((srcStart += 2)))) {
|
|
65
|
-
|
|
66
|
-
}
|
|
67
|
-
|
|
72
|
+
out.set(ptrToStr(keyStart, keyEnd), JSON.__deserialize<valueof<T>>(lastIndex, srcStart));
|
|
73
|
+
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
74
|
+
// /* empty */
|
|
75
|
+
// }
|
|
76
|
+
srcStart += 2;
|
|
77
|
+
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
|
|
78
|
+
keyStart = 0;
|
|
68
79
|
break;
|
|
69
80
|
}
|
|
70
81
|
srcStart += 2;
|
|
71
82
|
}
|
|
72
|
-
|
|
73
|
-
} else if (isArray<valueof<T>>() && code == BRACKET_LEFT) {
|
|
83
|
+
} else if (code == BRACE_LEFT) {
|
|
74
84
|
lastIndex = srcStart;
|
|
75
85
|
depth++;
|
|
76
86
|
srcStart += 2;
|
|
77
87
|
while (srcStart < srcEnd) {
|
|
78
88
|
const code = load<u16>(srcStart);
|
|
79
|
-
if (code ==
|
|
89
|
+
if (code == QUOTE) {
|
|
90
|
+
srcStart += 2;
|
|
91
|
+
while (!(load<u16>(srcStart) == QUOTE && load<u16>(srcStart - 2) != BACK_SLASH)) srcStart += 2;
|
|
92
|
+
} else if (code == BRACE_RIGHT) {
|
|
80
93
|
if (--depth == 0) {
|
|
94
|
+
// console.log("Value (object): " + ptrToStr(lastIndex, srcStart + 2));
|
|
81
95
|
// @ts-ignore: type
|
|
82
|
-
out.set(
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
96
|
+
out.set(ptrToStr(keyStart, keyEnd), JSON.__deserialize<valueof<T>>(lastIndex, (srcStart += 2)));
|
|
97
|
+
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
|
|
98
|
+
keyStart = 0;
|
|
99
|
+
// while (isSpace(load<u16>(srcStart))) {
|
|
100
|
+
// /* empty */
|
|
101
|
+
// }
|
|
87
102
|
break;
|
|
88
103
|
}
|
|
89
|
-
} else if (code ==
|
|
104
|
+
} else if (code == BRACE_LEFT) depth++;
|
|
90
105
|
srcStart += 2;
|
|
91
106
|
}
|
|
92
|
-
|
|
93
|
-
} else if (isDefined(changetype<nonnull<valueof<T>>>(0).__DESERIALIZE) && code == BRACE_LEFT) {
|
|
107
|
+
} else if (code == BRACKET_LEFT) {
|
|
94
108
|
lastIndex = srcStart;
|
|
95
109
|
depth++;
|
|
96
110
|
srcStart += 2;
|
|
97
111
|
while (srcStart < srcEnd) {
|
|
98
112
|
const code = load<u16>(srcStart);
|
|
99
|
-
if (code ==
|
|
113
|
+
if (code == BRACKET_RIGHT) {
|
|
100
114
|
if (--depth == 0) {
|
|
115
|
+
// console.log("Value (array): " + ptrToStr(lastIndex, srcStart + 2));
|
|
101
116
|
// @ts-ignore: type
|
|
102
|
-
out.set(
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
117
|
+
out.set(ptrToStr(keyStart, keyEnd), JSON.__deserialize<valueof<T>>(lastIndex, (srcStart += 2)));
|
|
118
|
+
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
|
|
119
|
+
keyStart = 0;
|
|
120
|
+
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
121
|
+
// /* empty */
|
|
122
|
+
// }
|
|
107
123
|
break;
|
|
108
124
|
}
|
|
109
|
-
} else if (code ==
|
|
125
|
+
} else if (code == BRACKET_LEFT) depth++;
|
|
110
126
|
srcStart += 2;
|
|
111
127
|
}
|
|
112
|
-
|
|
113
|
-
} else if (isBoolean<valueof<T>>() && code == CHAR_T) {
|
|
128
|
+
} else if (code == CHAR_T) {
|
|
114
129
|
if (load<u64>(srcStart) == 28429475166421108) {
|
|
130
|
+
// console.log("Value (bool): " + ptrToStr(srcStart, srcStart + 8));
|
|
115
131
|
// @ts-ignore: type
|
|
116
|
-
out.set(
|
|
117
|
-
while (isSpace(load<u16>((srcStart += 2)))) {
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
|
|
132
|
+
out.set(ptrToStr(keyStart, keyEnd), JSON.__deserialize<valueof<T>>(srcStart, (srcStart += 8)));
|
|
133
|
+
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
134
|
+
// /* empty */
|
|
135
|
+
// }
|
|
136
|
+
srcStart += 2;
|
|
137
|
+
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)) + " " + (srcStart < srcEnd).toString());
|
|
138
|
+
keyStart = 0;
|
|
121
139
|
}
|
|
122
|
-
|
|
123
|
-
} else if (isBoolean<valueof<T>>() && code == CHAR_F) {
|
|
140
|
+
} else if (code == CHAR_F) {
|
|
124
141
|
if (load<u64>(srcStart, 2) == 28429466576093281) {
|
|
142
|
+
// console.log("Value (bool): " + ptrToStr(srcStart, srcStart + 10));
|
|
125
143
|
// @ts-ignore: type
|
|
126
|
-
out.set(
|
|
127
|
-
while (isSpace(load<u16>((srcStart += 2)))) {
|
|
128
|
-
|
|
129
|
-
}
|
|
130
|
-
|
|
144
|
+
out.set(ptrToStr(keyStart, keyEnd), JSON.__deserialize<valueof<T>>(srcStart, (srcStart += 10)));
|
|
145
|
+
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
146
|
+
// /* empty */
|
|
147
|
+
// }
|
|
148
|
+
srcStart += 2;
|
|
149
|
+
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
|
|
150
|
+
keyStart = 0;
|
|
131
151
|
}
|
|
132
|
-
} else if (
|
|
152
|
+
} else if (code == CHAR_N) {
|
|
133
153
|
if (load<u64>(srcStart) == 30399761348886638) {
|
|
154
|
+
// console.log("Value (null): " + ptrToStr(srcStart, srcStart + 8));
|
|
134
155
|
// @ts-ignore: type
|
|
135
|
-
out.set(
|
|
136
|
-
while (isSpace(load<u16>((srcStart += 2)))) {
|
|
137
|
-
|
|
138
|
-
}
|
|
156
|
+
out.set(ptrToStr(keyStart, keyEnd), JSON.__deserialize<valueof<T>>(srcStart, (srcStart += 8)));
|
|
157
|
+
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
158
|
+
/* empty */
|
|
159
|
+
// }
|
|
160
|
+
srcStart += 2;
|
|
161
|
+
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
|
|
162
|
+
keyStart = 0;
|
|
139
163
|
}
|
|
164
|
+
} else if (isSpace(code)) {
|
|
165
|
+
srcStart += 2;
|
|
140
166
|
} else {
|
|
141
|
-
|
|
142
|
-
throw new Error("Unexpected character " + String.fromCharCode(code) + " or type " + nameof<valueof<T>>() + " does not match found type!");
|
|
167
|
+
throw new Error("Unexpected character in JSON object '" + String.fromCharCode(code) + "' at position " + (srcEnd - srcStart).toString());
|
|
143
168
|
}
|
|
144
169
|
}
|
|
145
170
|
}
|
|
146
171
|
return out;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
function sliceTo(srcStart: usize, srcEnd: usize): string {
|
|
150
|
-
const dstSize = srcEnd - srcStart;
|
|
151
|
-
const dst = __new(dstSize, idof<string>());
|
|
152
|
-
memory.copy(dst, srcStart, dstSize);
|
|
153
|
-
return changetype<string>(dst);
|
|
154
|
-
}
|
|
172
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { JSON } from "../..";
|
|
2
|
-
import { BACK_SLASH, COMMA, CHAR_F, BRACE_LEFT, BRACKET_LEFT, CHAR_N, QUOTE, BRACE_RIGHT, BRACKET_RIGHT, CHAR_T } from "../../custom/chars";
|
|
2
|
+
import { BACK_SLASH, COMMA, CHAR_F, BRACE_LEFT, BRACKET_LEFT, CHAR_N, QUOTE, BRACE_RIGHT, BRACKET_RIGHT, CHAR_T, COLON } from "../../custom/chars";
|
|
3
3
|
import { isSpace } from "../../util";
|
|
4
4
|
import { ptrToStr } from "../../util/ptrToStr";
|
|
5
5
|
import { deserializeArbitrary } from "./arbitrary";
|
|
6
6
|
|
|
7
7
|
export function deserializeObject(srcStart: usize, srcEnd: usize, dst: usize): JSON.Obj {
|
|
8
|
-
const out = new JSON.Obj();
|
|
8
|
+
const out = changetype<JSON.Obj>(dst || changetype<usize>(new JSON.Obj()));
|
|
9
9
|
|
|
10
10
|
let keyStart: usize = 0;
|
|
11
11
|
let keyEnd: usize = 0;
|
|
@@ -13,8 +13,14 @@ export function deserializeObject(srcStart: usize, srcEnd: usize, dst: usize): J
|
|
|
13
13
|
let depth = 0;
|
|
14
14
|
let lastIndex: usize = 0;
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
|
|
17
|
+
while (srcEnd > srcStart && isSpace(load<u16>(srcEnd - 2))) srcEnd -= 2; // would like to optimize this later
|
|
18
|
+
|
|
19
|
+
if (srcStart - srcEnd == 0)
|
|
20
|
+
throw new Error("Input string had zero length or was all whitespace");
|
|
21
|
+
if (load<u16>(srcStart) != BRACE_LEFT) throw new Error("Expected '{' at start of object at position " + (srcEnd - srcStart).toString());
|
|
22
|
+
if (load<u16>(srcEnd - 2) != BRACE_RIGHT) throw new Error("Expected '}' at end of object at position " + (srcEnd - srcStart).toString());
|
|
23
|
+
|
|
18
24
|
srcStart += 2;
|
|
19
25
|
while (srcStart < srcEnd) {
|
|
20
26
|
let code = load<u16>(srcStart); // while (isSpace(code)) code = load<u16>(srcStart += 2);
|
|
@@ -23,13 +29,10 @@ export function deserializeObject(srcStart: usize, srcEnd: usize, dst: usize): J
|
|
|
23
29
|
if (isKey) {
|
|
24
30
|
keyStart = lastIndex;
|
|
25
31
|
keyEnd = srcStart;
|
|
26
|
-
// console.log("Key: " + ptrToStr(
|
|
32
|
+
// console.log("Key: " + ptrToStr(lastIndex, srcStart));
|
|
27
33
|
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart + 2)));
|
|
28
|
-
srcStart += 2
|
|
29
|
-
|
|
30
|
-
// /* empty */
|
|
31
|
-
// }
|
|
32
|
-
// if (code !== COLON) throw new Error("Expected ':' after key at position " + (srcStart - srcPtr).toString());
|
|
34
|
+
while (isSpace((code = load<u16>((srcStart += 2))))) { }
|
|
35
|
+
if (code !== COLON) throw new Error("Expected ':' after key at position " + (srcEnd - srcStart).toString());
|
|
33
36
|
isKey = false;
|
|
34
37
|
} else {
|
|
35
38
|
// console.log("Got key start");
|
|
@@ -80,10 +83,13 @@ export function deserializeObject(srcStart: usize, srcEnd: usize, dst: usize): J
|
|
|
80
83
|
srcStart += 2;
|
|
81
84
|
while (srcStart < srcEnd) {
|
|
82
85
|
const code = load<u16>(srcStart);
|
|
83
|
-
if (code ==
|
|
86
|
+
if (code == QUOTE) {
|
|
87
|
+
srcStart += 2;
|
|
88
|
+
while (!(load<u16>(srcStart) == QUOTE && load<u16>(srcStart - 2) != BACK_SLASH)) srcStart += 2;
|
|
89
|
+
} else if (code == BRACE_RIGHT) {
|
|
84
90
|
if (--depth == 0) {
|
|
85
91
|
// console.log("Value (object): " + ptrToStr(lastIndex, srcStart + 2));
|
|
86
|
-
out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, srcStart += 2, dst));
|
|
92
|
+
out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, (srcStart += 2), dst));
|
|
87
93
|
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
|
|
88
94
|
keyStart = 0;
|
|
89
95
|
// while (isSpace(load<u16>(srcStart))) {
|
|
@@ -103,7 +109,7 @@ export function deserializeObject(srcStart: usize, srcEnd: usize, dst: usize): J
|
|
|
103
109
|
if (code == BRACKET_RIGHT) {
|
|
104
110
|
if (--depth == 0) {
|
|
105
111
|
// console.log("Value (array): " + ptrToStr(lastIndex, srcStart + 2));
|
|
106
|
-
out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, srcStart += 2, dst));
|
|
112
|
+
out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, (srcStart += 2), dst));
|
|
107
113
|
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
|
|
108
114
|
keyStart = 0;
|
|
109
115
|
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
@@ -117,7 +123,7 @@ export function deserializeObject(srcStart: usize, srcEnd: usize, dst: usize): J
|
|
|
117
123
|
} else if (code == CHAR_T) {
|
|
118
124
|
if (load<u64>(srcStart) == 28429475166421108) {
|
|
119
125
|
// console.log("Value (bool): " + ptrToStr(srcStart, srcStart + 8));
|
|
120
|
-
out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(
|
|
126
|
+
out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(srcStart, (srcStart += 8), dst));
|
|
121
127
|
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
122
128
|
// /* empty */
|
|
123
129
|
// }
|
|
@@ -128,7 +134,7 @@ export function deserializeObject(srcStart: usize, srcEnd: usize, dst: usize): J
|
|
|
128
134
|
} else if (code == CHAR_F) {
|
|
129
135
|
if (load<u64>(srcStart, 2) == 28429466576093281) {
|
|
130
136
|
// console.log("Value (bool): " + ptrToStr(srcStart, srcStart + 10));
|
|
131
|
-
out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(
|
|
137
|
+
out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(srcStart, (srcStart += 10), dst));
|
|
132
138
|
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
133
139
|
// /* empty */
|
|
134
140
|
// }
|
|
@@ -139,7 +145,7 @@ export function deserializeObject(srcStart: usize, srcEnd: usize, dst: usize): J
|
|
|
139
145
|
} else if (code == CHAR_N) {
|
|
140
146
|
if (load<u64>(srcStart) == 30399761348886638) {
|
|
141
147
|
// console.log("Value (null): " + ptrToStr(srcStart, srcStart + 8));
|
|
142
|
-
out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(
|
|
148
|
+
out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(srcStart, (srcStart += 8), dst));
|
|
143
149
|
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
144
150
|
/* empty */
|
|
145
151
|
// }
|
|
@@ -147,6 +153,10 @@ export function deserializeObject(srcStart: usize, srcEnd: usize, dst: usize): J
|
|
|
147
153
|
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
|
|
148
154
|
keyStart = 0;
|
|
149
155
|
}
|
|
156
|
+
} else if (isSpace(code)) {
|
|
157
|
+
srcStart += 2;
|
|
158
|
+
} else {
|
|
159
|
+
throw new Error("Unexpected character in JSON object '" + String.fromCharCode(code) + "' at position " + (srcEnd - srcStart).toString());
|
|
150
160
|
}
|
|
151
161
|
}
|
|
152
162
|
}
|
|
@@ -1,23 +1,29 @@
|
|
|
1
1
|
import { BACK_SLASH, COMMA, CHAR_F, BRACE_LEFT, BRACKET_LEFT, CHAR_N, QUOTE, BRACE_RIGHT, BRACKET_RIGHT, CHAR_T, COLON } from "../../custom/chars";
|
|
2
2
|
import { isSpace } from "../../util";
|
|
3
|
+
import { ptrToStr } from "../../util/ptrToStr";
|
|
3
4
|
|
|
4
5
|
export function deserializeStruct<T>(srcStart: usize, srcEnd: usize, dst: usize): T {
|
|
5
6
|
const out = changetype<nonnull<T>>(dst || __new(offsetof<T>(), idof<T>()));
|
|
6
7
|
|
|
8
|
+
// @ts-ignore: supplied by transform
|
|
9
|
+
if (isDefined(out.__INITIALIZE)) out.__INITIALIZE();
|
|
10
|
+
|
|
7
11
|
let keyStart: usize = 0;
|
|
8
12
|
let keyEnd: usize = 0;
|
|
9
13
|
let isKey = false;
|
|
10
14
|
let depth = 0;
|
|
11
15
|
let lastIndex: usize = 0;
|
|
12
16
|
|
|
13
|
-
while (isSpace(load<u16>(srcStart))) srcStart += 2;
|
|
14
|
-
while (isSpace(load<u16>(srcEnd
|
|
17
|
+
while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
|
|
18
|
+
while (srcEnd > srcStart && isSpace(load<u16>(srcEnd - 2))) srcEnd -= 2; // would like to optimize this later
|
|
15
19
|
|
|
20
|
+
if (srcStart - srcEnd == 0)
|
|
21
|
+
throw new Error("Input string had zero length or was all whitespace");
|
|
16
22
|
if (load<u16>(srcStart) != BRACE_LEFT) throw new Error("Expected '{' at start of object at position " + (srcEnd - srcStart).toString());
|
|
17
|
-
if (load<u16>(srcEnd) != BRACE_RIGHT) throw new Error("Expected '}' at end of object at position " + (srcEnd - srcStart).toString());
|
|
23
|
+
if (load<u16>(srcEnd - 2) != BRACE_RIGHT) throw new Error("Expected '}' at end of object at position " + (srcEnd - srcStart).toString());
|
|
18
24
|
|
|
19
25
|
srcStart += 2;
|
|
20
|
-
while (srcStart
|
|
26
|
+
while (srcStart < srcEnd) {
|
|
21
27
|
let code = load<u16>(srcStart); // while (isSpace(code)) code = load<u16>(srcStart += 2);
|
|
22
28
|
if (keyStart == 0) {
|
|
23
29
|
if (code == QUOTE && load<u16>(srcStart - 2) !== BACK_SLASH) {
|
|
@@ -26,7 +32,7 @@ export function deserializeStruct<T>(srcStart: usize, srcEnd: usize, dst: usize)
|
|
|
26
32
|
keyEnd = srcStart;
|
|
27
33
|
// console.log("Key: " + ptrToStr(lastIndex, srcStart));
|
|
28
34
|
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart + 2)));
|
|
29
|
-
while (isSpace((code = load<u16>((srcStart += 2))))) {}
|
|
35
|
+
while (isSpace((code = load<u16>((srcStart += 2))))) { }
|
|
30
36
|
if (code !== COLON) throw new Error("Expected ':' after key at position " + (srcEnd - srcStart).toString());
|
|
31
37
|
isKey = false;
|
|
32
38
|
} else {
|
|
@@ -41,12 +47,12 @@ export function deserializeStruct<T>(srcStart: usize, srcEnd: usize, dst: usize)
|
|
|
41
47
|
if (code == QUOTE) {
|
|
42
48
|
lastIndex = srcStart;
|
|
43
49
|
srcStart += 2;
|
|
44
|
-
while (srcStart
|
|
50
|
+
while (srcStart < srcEnd) {
|
|
45
51
|
const code = load<u16>(srcStart);
|
|
46
52
|
if (code == QUOTE && load<u16>(srcStart - 2) !== BACK_SLASH) {
|
|
47
53
|
// console.log("Value (string): " + ptrToStr(lastIndex, srcStart + 2));
|
|
48
54
|
// @ts-ignore: exists
|
|
49
|
-
out.__DESERIALIZE(keyStart, keyEnd, lastIndex, srcStart + 2,
|
|
55
|
+
out.__DESERIALIZE(keyStart, keyEnd, lastIndex, srcStart + 2, changetype<usize>(out));
|
|
50
56
|
// while (isSpace(load<u16>(srcStart))) srcStart += 2;
|
|
51
57
|
srcStart += 4;
|
|
52
58
|
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
|
|
@@ -58,12 +64,12 @@ export function deserializeStruct<T>(srcStart: usize, srcEnd: usize, dst: usize)
|
|
|
58
64
|
} else if (code - 48 <= 9 || code == 45) {
|
|
59
65
|
lastIndex = srcStart;
|
|
60
66
|
srcStart += 2;
|
|
61
|
-
while (srcStart
|
|
67
|
+
while (srcStart < srcEnd) {
|
|
62
68
|
const code = load<u16>(srcStart);
|
|
63
69
|
if (code == COMMA || code == BRACE_RIGHT || isSpace(code)) {
|
|
64
70
|
// console.log("Value (number): " + ptrToStr(lastIndex, srcStart));
|
|
65
71
|
// @ts-ignore: exists
|
|
66
|
-
out.__DESERIALIZE(keyStart, keyEnd, lastIndex, srcStart,
|
|
72
|
+
out.__DESERIALIZE(keyStart, keyEnd, lastIndex, srcStart, changetype<usize>(out));
|
|
67
73
|
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
68
74
|
// /* empty */
|
|
69
75
|
// }
|
|
@@ -78,13 +84,16 @@ export function deserializeStruct<T>(srcStart: usize, srcEnd: usize, dst: usize)
|
|
|
78
84
|
lastIndex = srcStart;
|
|
79
85
|
depth++;
|
|
80
86
|
srcStart += 2;
|
|
81
|
-
while (srcStart
|
|
87
|
+
while (srcStart < srcEnd) {
|
|
82
88
|
const code = load<u16>(srcStart);
|
|
83
|
-
if (code ==
|
|
89
|
+
if (code == QUOTE) {
|
|
90
|
+
srcStart += 2;
|
|
91
|
+
while (!(load<u16>(srcStart) == QUOTE && load<u16>(srcStart - 2) != BACK_SLASH)) srcStart += 2;
|
|
92
|
+
} else if (code == BRACE_RIGHT) {
|
|
84
93
|
if (--depth == 0) {
|
|
85
94
|
// console.log("Value (object): " + ptrToStr(lastIndex, srcStart + 2));
|
|
86
95
|
// @ts-ignore: exists
|
|
87
|
-
out.__DESERIALIZE(keyStart, keyEnd, lastIndex, (srcStart += 2),
|
|
96
|
+
out.__DESERIALIZE(keyStart, keyEnd, lastIndex, (srcStart += 2), changetype<usize>(out));
|
|
88
97
|
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
|
|
89
98
|
keyStart = 0;
|
|
90
99
|
// while (isSpace(load<u16>(srcStart))) {
|
|
@@ -99,13 +108,16 @@ export function deserializeStruct<T>(srcStart: usize, srcEnd: usize, dst: usize)
|
|
|
99
108
|
lastIndex = srcStart;
|
|
100
109
|
depth++;
|
|
101
110
|
srcStart += 2;
|
|
102
|
-
while (srcStart
|
|
111
|
+
while (srcStart < srcEnd) {
|
|
103
112
|
const code = load<u16>(srcStart);
|
|
104
|
-
if (code ==
|
|
113
|
+
if (code == QUOTE) {
|
|
114
|
+
srcStart += 2;
|
|
115
|
+
while (!(load<u16>(srcStart) == QUOTE && load<u16>(srcStart - 2) != BACK_SLASH)) srcStart += 2;
|
|
116
|
+
} else if (code == BRACKET_RIGHT) {
|
|
105
117
|
if (--depth == 0) {
|
|
106
118
|
// console.log("Value (array): " + ptrToStr(lastIndex, srcStart + 2));
|
|
107
119
|
// @ts-ignore: exists
|
|
108
|
-
out.__DESERIALIZE(keyStart, keyEnd, lastIndex, (srcStart += 2),
|
|
120
|
+
out.__DESERIALIZE(keyStart, keyEnd, lastIndex, (srcStart += 2), changetype<usize>(out));
|
|
109
121
|
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
|
|
110
122
|
keyStart = 0;
|
|
111
123
|
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
@@ -120,19 +132,19 @@ export function deserializeStruct<T>(srcStart: usize, srcEnd: usize, dst: usize)
|
|
|
120
132
|
if (load<u64>(srcStart) == 28429475166421108) {
|
|
121
133
|
// console.log("Value (bool): " + ptrToStr(srcStart, srcStart + 8));
|
|
122
134
|
// @ts-ignore: exists
|
|
123
|
-
out.__DESERIALIZE(keyStart, keyEnd, srcStart, (srcStart += 8),
|
|
135
|
+
out.__DESERIALIZE(keyStart, keyEnd, srcStart, (srcStart += 8), changetype<usize>(out));
|
|
124
136
|
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
125
137
|
// /* empty */
|
|
126
138
|
// }
|
|
127
139
|
srcStart += 2;
|
|
128
|
-
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)) + " " + (srcStart
|
|
140
|
+
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)) + " " + (srcStart < srcEnd).toString());
|
|
129
141
|
keyStart = 0;
|
|
130
142
|
}
|
|
131
143
|
} else if (code == CHAR_F) {
|
|
132
144
|
if (load<u64>(srcStart, 2) == 28429466576093281) {
|
|
133
145
|
// console.log("Value (bool): " + ptrToStr(srcStart, srcStart + 10));
|
|
134
146
|
// @ts-ignore: exists
|
|
135
|
-
out.__DESERIALIZE(keyStart, keyEnd, srcStart, (srcStart += 10),
|
|
147
|
+
out.__DESERIALIZE(keyStart, keyEnd, srcStart, (srcStart += 10), changetype<usize>(out));
|
|
136
148
|
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
137
149
|
// /* empty */
|
|
138
150
|
// }
|
|
@@ -144,7 +156,7 @@ export function deserializeStruct<T>(srcStart: usize, srcEnd: usize, dst: usize)
|
|
|
144
156
|
if (load<u64>(srcStart) == 30399761348886638) {
|
|
145
157
|
// console.log("Value (null): " + ptrToStr(srcStart, srcStart + 8));
|
|
146
158
|
// @ts-ignore: exists
|
|
147
|
-
out.__DESERIALIZE(keyStart, keyEnd, srcStart, (srcStart += 8),
|
|
159
|
+
out.__DESERIALIZE(keyStart, keyEnd, srcStart, (srcStart += 8), changetype<usize>(out));
|
|
148
160
|
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
149
161
|
/* empty */
|
|
150
162
|
// }
|
package/assembly/index.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/// <reference path="./index.d.ts" />
|
|
2
2
|
|
|
3
|
+
import { bs } from "../lib/as-bs";
|
|
3
4
|
import { serializeString } from "./serialize/simple/string";
|
|
4
5
|
import { serializeArray } from "./serialize/simple/array";
|
|
5
6
|
import { serializeMap } from "./serialize/simple/map";
|
|
@@ -66,7 +67,7 @@ export namespace JSON {
|
|
|
66
67
|
return out;
|
|
67
68
|
}
|
|
68
69
|
return data ? "true" : "false";
|
|
69
|
-
} else if (isInteger<T>() && nameof<T>() == "usize" && data == 0) {
|
|
70
|
+
} else if (isInteger<T>() && !isSigned<T>() && nameof<T>() == "usize" && data == 0) {
|
|
70
71
|
if (out) {
|
|
71
72
|
out = changetype<string>(__renew(changetype<usize>(out), 8));
|
|
72
73
|
store<u64>(changetype<usize>(out), 30399761348886638);
|
|
@@ -233,11 +234,12 @@ export namespace JSON {
|
|
|
233
234
|
U64 = 4,
|
|
234
235
|
F32 = 5,
|
|
235
236
|
F64 = 6,
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
237
|
+
Null = 7,
|
|
238
|
+
Bool = 8,
|
|
239
|
+
String = 9,
|
|
240
|
+
Object = 10,
|
|
241
|
+
Array = 12,
|
|
242
|
+
Struct = 13,
|
|
241
243
|
}
|
|
242
244
|
|
|
243
245
|
export class Raw {
|
|
@@ -297,6 +299,9 @@ export namespace JSON {
|
|
|
297
299
|
if (isBoolean<T>()) {
|
|
298
300
|
this.type = JSON.Types.Bool;
|
|
299
301
|
store<T>(changetype<usize>(this), value, STORAGE);
|
|
302
|
+
} else if (isInteger<T>() && !isSigned<T>() && changetype<usize>(value) == 0 && nameof<T>() == "usize") {
|
|
303
|
+
this.type = JSON.Types.Null;
|
|
304
|
+
store<usize>(changetype<usize>(this), 0, STORAGE);
|
|
300
305
|
} else if (value instanceof u8 || value instanceof i8) {
|
|
301
306
|
this.type = JSON.Types.U8;
|
|
302
307
|
store<T>(changetype<usize>(this), value, STORAGE);
|
|
@@ -514,8 +519,7 @@ export namespace JSON {
|
|
|
514
519
|
}
|
|
515
520
|
}
|
|
516
521
|
|
|
517
|
-
|
|
518
|
-
@inline export function __serialize<T>(src: T): void {
|
|
522
|
+
export function __serialize<T>(src: T): void {
|
|
519
523
|
if (isBoolean<T>()) {
|
|
520
524
|
serializeBool(src as bool);
|
|
521
525
|
} else if (isInteger<T>() && nameof<T>() == "usize" && src == 0) {
|
|
@@ -565,8 +569,7 @@ export namespace JSON {
|
|
|
565
569
|
}
|
|
566
570
|
}
|
|
567
571
|
|
|
568
|
-
|
|
569
|
-
@inline export function __deserialize<T>(srcStart: usize, srcEnd: usize, dst: usize = 0): T {
|
|
572
|
+
export function __deserialize<T>(srcStart: usize, srcEnd: usize, dst: usize = 0): T {
|
|
570
573
|
if (isBoolean<T>()) {
|
|
571
574
|
// @ts-ignore: type
|
|
572
575
|
return deserializeBoolean(srcStart, srcEnd);
|
|
@@ -588,7 +591,7 @@ export namespace JSON {
|
|
|
588
591
|
// @ts-ignore: Defined by transform
|
|
589
592
|
if (isDefined(type.__INITIALIZE)) changetype<nonnull<T>>(out).__INITIALIZE();
|
|
590
593
|
// @ts-ignore
|
|
591
|
-
return changetype<nonnull<T>>(out).__DESERIALIZE_CUSTOM(ptrToStr(
|
|
594
|
+
return changetype<nonnull<T>>(out).__DESERIALIZE_CUSTOM(ptrToStr(srcStart, srcEnd));
|
|
592
595
|
// @ts-ignore: Defined by transform
|
|
593
596
|
} else if (isDefined(type.__DESERIALIZE)) {
|
|
594
597
|
return deserializeStruct<T>(srcStart, srcEnd, dst);
|