json-as 1.0.0-alpha.4 → 1.0.0-beta.10
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/.trunk/configs/.markdownlint.yaml +2 -0
- package/.trunk/configs/.shellcheckrc +7 -0
- package/.trunk/configs/.yamllint.yaml +7 -0
- package/.trunk/trunk.yaml +37 -0
- package/CHANGELOG +60 -0
- package/README.md +303 -48
- package/assembly/__benches__/misc.bench.ts +47 -0
- package/assembly/__benches__/schemas.ts +25 -0
- package/assembly/__benches__/string.bench.ts +23 -0
- package/assembly/__benches__/struct.bench.ts +21 -0
- package/assembly/__tests__/arbitrary.spec.ts +19 -0
- package/assembly/__tests__/array.spec.ts +42 -1
- package/assembly/__tests__/bool.spec.ts +1 -1
- package/assembly/__tests__/box.spec.ts +1 -1
- package/assembly/__tests__/custom.spec.ts +42 -0
- package/assembly/__tests__/date.spec.ts +1 -1
- package/assembly/__tests__/float.spec.ts +4 -4
- package/assembly/__tests__/integer.spec.ts +1 -1
- package/assembly/__tests__/null.spec.ts +1 -1
- package/assembly/__tests__/raw.spec.ts +23 -0
- package/assembly/__tests__/string.spec.ts +1 -1
- package/assembly/__tests__/{obj.spec.ts → struct.spec.ts} +18 -4
- package/assembly/__tests__/test.spec.ts +1 -1
- package/assembly/__tests__/types.ts +3 -3
- package/assembly/as-bs.d.ts +53 -0
- package/assembly/custom/bench.ts +26 -0
- package/assembly/deserialize/simd/string.ts +1 -1
- package/assembly/deserialize/simple/arbitrary.ts +1 -1
- package/assembly/deserialize/simple/array/arbitrary.ts +46 -24
- 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 +1 -1
- 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 +29 -0
- package/assembly/deserialize/simple/array.ts +7 -9
- package/assembly/deserialize/simple/integer.ts +2 -1
- package/assembly/deserialize/simple/map.ts +92 -67
- package/assembly/deserialize/simple/object.ts +14 -19
- package/assembly/deserialize/simple/raw.ts +6 -0
- package/assembly/deserialize/simple/struct.ts +171 -0
- package/assembly/index.d.ts +15 -1
- package/assembly/index.ts +202 -25
- package/assembly/serialize/simd/string.ts +0 -1
- package/assembly/serialize/simple/arbitrary.ts +15 -2
- package/assembly/serialize/simple/array.ts +0 -1
- package/assembly/serialize/simple/bool.ts +0 -2
- package/assembly/serialize/simple/date.ts +0 -1
- package/assembly/serialize/simple/float.ts +0 -1
- package/assembly/serialize/simple/integer.ts +0 -1
- package/assembly/serialize/simple/map.ts +0 -1
- package/assembly/serialize/simple/object.ts +42 -6
- package/assembly/serialize/simple/raw.ts +14 -0
- package/assembly/serialize/simple/string.ts +0 -1
- package/assembly/serialize/simple/struct.ts +7 -0
- package/assembly/test.ts +80 -13
- package/assembly/util/atoi.ts +1 -1
- package/bench/bench.ts +15 -0
- package/bench/schemas.ts +5 -0
- package/bench/string.bench.ts +16 -0
- package/bench.js +11 -2
- package/index.ts +1 -1
- package/{modules/as-bs/assembly/index.ts → lib/as-bs.ts} +3 -3
- package/lib/tsconfig.json +8 -0
- package/package.json +10 -6
- package/run-tests.sh +1 -1
- package/transform/lib/index.js +124 -55
- package/transform/lib/index.js.map +1 -1
- package/transform/src/index.ts +141 -62
- package/.gitmodules +0 -0
- package/as-test.config.json +0 -18
- package/assembly/deserialize/simple/array/object.ts +0 -18
- package/modules/as-bs/LICENSE +0 -21
- package/modules/as-bs/README.md +0 -95
- package/modules/as-bs/assembly/tsconfig.json +0 -97
- package/modules/as-bs/index.ts +0 -1
- package/modules/as-bs/package.json +0 -32
- /package/{modules/test/assembly → assembly/__tests__/lib}/index.ts +0 -0
|
@@ -5,7 +5,7 @@ import { deserializeBooleanArray } from "./array/bool";
|
|
|
5
5
|
import { deserializeFloatArray } from "./array/float";
|
|
6
6
|
import { deserializeIntegerArray } from "./array/integer";
|
|
7
7
|
import { deserializeMapArray } from "./array/map";
|
|
8
|
-
import {
|
|
8
|
+
import { deserializeStructArray } from "./array/struct";
|
|
9
9
|
import { deserializeStringArray } from "./array/string";
|
|
10
10
|
|
|
11
11
|
// @ts-ignore: Decorator valid here
|
|
@@ -28,21 +28,19 @@ export function deserializeArray<T extends unknown[]>(srcStart: usize, srcEnd: u
|
|
|
28
28
|
const type = changetype<nonnull<valueof<T>>>(0);
|
|
29
29
|
if (type instanceof JSON.Value) {
|
|
30
30
|
// @ts-ignore: type
|
|
31
|
-
return deserializeArbitraryArray
|
|
31
|
+
return deserializeArbitraryArray(srcStart, srcEnd, dst);
|
|
32
32
|
} else if (type instanceof Map) {
|
|
33
33
|
// @ts-ignore: type
|
|
34
34
|
return deserializeMapArray<T>(srcStart, srcEnd, dst);
|
|
35
35
|
// @ts-ignore: defined by transform
|
|
36
|
+
} else if (isDefined(type.__DESERIALIZE_CUSTOM)) {
|
|
37
|
+
return deserializeStructArray<T>(srcStart, srcEnd, dst);
|
|
38
|
+
// @ts-ignore: defined by transform
|
|
36
39
|
} else if (isDefined(type.__DESERIALIZE)) {
|
|
37
|
-
return
|
|
40
|
+
return deserializeStructArray<T>(srcStart, srcEnd, dst);
|
|
38
41
|
}
|
|
39
42
|
throw new Error("Could not parse array of type " + nameof<T>() + "!");
|
|
40
43
|
} else {
|
|
41
44
|
throw new Error("Could not parse array of type " + nameof<T>() + "!");
|
|
42
45
|
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function isMap<T>(): boolean {
|
|
46
|
-
let type: T = changetype<T>(0);
|
|
47
|
-
return type instanceof Map;
|
|
48
|
-
}
|
|
46
|
+
}
|
|
@@ -1,145 +1,170 @@
|
|
|
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 || __new(offsetof<T>(), idof<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 (
|
|
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>>(lastIndex, (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>>(lastIndex, (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>>(lastIndex, (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
|
}
|
|
@@ -2,9 +2,10 @@ import { JSON } from "../..";
|
|
|
2
2
|
import { BACK_SLASH, COMMA, CHAR_F, BRACE_LEFT, BRACKET_LEFT, CHAR_N, QUOTE, BRACE_RIGHT, BRACKET_RIGHT, CHAR_T } from "../../custom/chars";
|
|
3
3
|
import { isSpace } from "../../util";
|
|
4
4
|
import { ptrToStr } from "../../util/ptrToStr";
|
|
5
|
+
import { deserializeArbitrary } from "./arbitrary";
|
|
5
6
|
|
|
6
|
-
export function deserializeObject
|
|
7
|
-
const out =
|
|
7
|
+
export function deserializeObject(srcStart: usize, srcEnd: usize, dst: usize): JSON.Obj {
|
|
8
|
+
const out = new JSON.Obj();
|
|
8
9
|
|
|
9
10
|
let keyStart: usize = 0;
|
|
10
11
|
let keyEnd: usize = 0;
|
|
@@ -12,8 +13,9 @@ export function deserializeObject<T>(srcStart: usize, srcEnd: usize, dst: usize)
|
|
|
12
13
|
let depth = 0;
|
|
13
14
|
let lastIndex: usize = 0;
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
|
|
17
|
+
while (srcEnd > srcStart && isSpace(load<u16>(srcEnd - 2))) srcEnd -= 2;
|
|
18
|
+
|
|
17
19
|
srcStart += 2;
|
|
18
20
|
while (srcStart < srcEnd) {
|
|
19
21
|
let code = load<u16>(srcStart); // while (isSpace(code)) code = load<u16>(srcStart += 2);
|
|
@@ -22,7 +24,7 @@ export function deserializeObject<T>(srcStart: usize, srcEnd: usize, dst: usize)
|
|
|
22
24
|
if (isKey) {
|
|
23
25
|
keyStart = lastIndex;
|
|
24
26
|
keyEnd = srcStart;
|
|
25
|
-
// console.log("Key: " + ptrToStr(
|
|
27
|
+
// console.log("Key: " + ptrToStr(keyStart, keyEnd));
|
|
26
28
|
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart + 2)));
|
|
27
29
|
srcStart += 2;
|
|
28
30
|
// while (isSpace((code = load<u16>((srcStart += 2))))) {
|
|
@@ -46,8 +48,7 @@ export function deserializeObject<T>(srcStart: usize, srcEnd: usize, dst: usize)
|
|
|
46
48
|
const code = load<u16>(srcStart);
|
|
47
49
|
if (code == QUOTE && load<u16>(srcStart - 2) !== BACK_SLASH) {
|
|
48
50
|
// console.log("Value (string): " + ptrToStr(lastIndex, srcStart + 2));
|
|
49
|
-
|
|
50
|
-
out.__DESERIALIZE(keyStart, keyEnd, lastIndex, srcStart + 2, dst);
|
|
51
|
+
out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, srcStart + 2, dst));
|
|
51
52
|
// while (isSpace(load<u16>(srcStart))) srcStart += 2;
|
|
52
53
|
srcStart += 4;
|
|
53
54
|
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
|
|
@@ -63,8 +64,7 @@ export function deserializeObject<T>(srcStart: usize, srcEnd: usize, dst: usize)
|
|
|
63
64
|
const code = load<u16>(srcStart);
|
|
64
65
|
if (code == COMMA || code == BRACE_RIGHT || isSpace(code)) {
|
|
65
66
|
// console.log("Value (number): " + ptrToStr(lastIndex, srcStart));
|
|
66
|
-
|
|
67
|
-
out.__DESERIALIZE(keyStart, keyEnd, lastIndex, srcStart, dst);
|
|
67
|
+
out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, srcStart, dst));
|
|
68
68
|
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
69
69
|
// /* empty */
|
|
70
70
|
// }
|
|
@@ -84,8 +84,7 @@ export function deserializeObject<T>(srcStart: usize, srcEnd: usize, dst: usize)
|
|
|
84
84
|
if (code == BRACE_RIGHT) {
|
|
85
85
|
if (--depth == 0) {
|
|
86
86
|
// console.log("Value (object): " + ptrToStr(lastIndex, srcStart + 2));
|
|
87
|
-
|
|
88
|
-
out.__DESERIALIZE(keyStart, keyEnd, lastIndex, (srcStart += 2), dst);
|
|
87
|
+
out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, srcStart += 2, dst));
|
|
89
88
|
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
|
|
90
89
|
keyStart = 0;
|
|
91
90
|
// while (isSpace(load<u16>(srcStart))) {
|
|
@@ -105,8 +104,7 @@ export function deserializeObject<T>(srcStart: usize, srcEnd: usize, dst: usize)
|
|
|
105
104
|
if (code == BRACKET_RIGHT) {
|
|
106
105
|
if (--depth == 0) {
|
|
107
106
|
// console.log("Value (array): " + ptrToStr(lastIndex, srcStart + 2));
|
|
108
|
-
|
|
109
|
-
out.__DESERIALIZE(keyStart, keyEnd, lastIndex, (srcStart += 2), dst);
|
|
107
|
+
out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, srcStart += 2, dst));
|
|
110
108
|
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
|
|
111
109
|
keyStart = 0;
|
|
112
110
|
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
@@ -120,8 +118,7 @@ export function deserializeObject<T>(srcStart: usize, srcEnd: usize, dst: usize)
|
|
|
120
118
|
} else if (code == CHAR_T) {
|
|
121
119
|
if (load<u64>(srcStart) == 28429475166421108) {
|
|
122
120
|
// console.log("Value (bool): " + ptrToStr(srcStart, srcStart + 8));
|
|
123
|
-
|
|
124
|
-
out.__DESERIALIZE(keyStart, keyEnd, srcStart, (srcStart += 8), dst);
|
|
121
|
+
out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, srcStart += 8, dst));
|
|
125
122
|
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
126
123
|
// /* empty */
|
|
127
124
|
// }
|
|
@@ -132,8 +129,7 @@ export function deserializeObject<T>(srcStart: usize, srcEnd: usize, dst: usize)
|
|
|
132
129
|
} else if (code == CHAR_F) {
|
|
133
130
|
if (load<u64>(srcStart, 2) == 28429466576093281) {
|
|
134
131
|
// console.log("Value (bool): " + ptrToStr(srcStart, srcStart + 10));
|
|
135
|
-
|
|
136
|
-
out.__DESERIALIZE(keyStart, keyEnd, srcStart, (srcStart += 10), dst);
|
|
132
|
+
out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, srcStart += 10, dst));
|
|
137
133
|
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
138
134
|
// /* empty */
|
|
139
135
|
// }
|
|
@@ -144,8 +140,7 @@ export function deserializeObject<T>(srcStart: usize, srcEnd: usize, dst: usize)
|
|
|
144
140
|
} else if (code == CHAR_N) {
|
|
145
141
|
if (load<u64>(srcStart) == 30399761348886638) {
|
|
146
142
|
// console.log("Value (null): " + ptrToStr(srcStart, srcStart + 8));
|
|
147
|
-
|
|
148
|
-
out.__DESERIALIZE(keyStart, keyEnd, srcStart, (srcStart += 8), dst);
|
|
143
|
+
out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, srcStart += 8, dst));
|
|
149
144
|
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
150
145
|
/* empty */
|
|
151
146
|
// }
|
|
@@ -0,0 +1,171 @@
|
|
|
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
|
+
import { isSpace } from "../../util";
|
|
3
|
+
|
|
4
|
+
export function deserializeStruct<T>(srcStart: usize, srcEnd: usize, dst: usize): T {
|
|
5
|
+
const out = changetype<nonnull<T>>(dst || __new(offsetof<T>(), idof<T>()));
|
|
6
|
+
|
|
7
|
+
// @ts-ignore: supplied by transform
|
|
8
|
+
if (isDefined(out.__INITIALIZE)) out.__INITIALIZE();
|
|
9
|
+
|
|
10
|
+
let keyStart: usize = 0;
|
|
11
|
+
let keyEnd: usize = 0;
|
|
12
|
+
let isKey = false;
|
|
13
|
+
let depth = 0;
|
|
14
|
+
let lastIndex: usize = 0;
|
|
15
|
+
|
|
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
|
+
|
|
24
|
+
srcStart += 2;
|
|
25
|
+
while (srcStart < srcEnd) {
|
|
26
|
+
let code = load<u16>(srcStart); // while (isSpace(code)) code = load<u16>(srcStart += 2);
|
|
27
|
+
if (keyStart == 0) {
|
|
28
|
+
if (code == QUOTE && load<u16>(srcStart - 2) !== BACK_SLASH) {
|
|
29
|
+
if (isKey) {
|
|
30
|
+
keyStart = lastIndex;
|
|
31
|
+
keyEnd = srcStart;
|
|
32
|
+
// console.log("Key: " + ptrToStr(lastIndex, srcStart));
|
|
33
|
+
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart + 2)));
|
|
34
|
+
while (isSpace((code = load<u16>((srcStart += 2))))) { }
|
|
35
|
+
if (code !== COLON) throw new Error("Expected ':' after key at position " + (srcEnd - srcStart).toString());
|
|
36
|
+
isKey = false;
|
|
37
|
+
} else {
|
|
38
|
+
// console.log("Got key start");
|
|
39
|
+
isKey = true; // i don't like this
|
|
40
|
+
lastIndex = srcStart + 2;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// isKey = !isKey;
|
|
44
|
+
srcStart += 2;
|
|
45
|
+
} else {
|
|
46
|
+
if (code == QUOTE) {
|
|
47
|
+
lastIndex = srcStart;
|
|
48
|
+
srcStart += 2;
|
|
49
|
+
while (srcStart < srcEnd) {
|
|
50
|
+
const code = load<u16>(srcStart);
|
|
51
|
+
if (code == QUOTE && load<u16>(srcStart - 2) !== BACK_SLASH) {
|
|
52
|
+
// console.log("Value (string): " + ptrToStr(lastIndex, srcStart + 2));
|
|
53
|
+
// @ts-ignore: exists
|
|
54
|
+
out.__DESERIALIZE(keyStart, keyEnd, lastIndex, srcStart + 2, changetype<usize>(out));
|
|
55
|
+
// while (isSpace(load<u16>(srcStart))) srcStart += 2;
|
|
56
|
+
srcStart += 4;
|
|
57
|
+
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
|
|
58
|
+
keyStart = 0;
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
srcStart += 2;
|
|
62
|
+
}
|
|
63
|
+
} else if (code - 48 <= 9 || code == 45) {
|
|
64
|
+
lastIndex = srcStart;
|
|
65
|
+
srcStart += 2;
|
|
66
|
+
while (srcStart < srcEnd) {
|
|
67
|
+
const code = load<u16>(srcStart);
|
|
68
|
+
if (code == COMMA || code == BRACE_RIGHT || isSpace(code)) {
|
|
69
|
+
// console.log("Value (number): " + ptrToStr(lastIndex, srcStart));
|
|
70
|
+
// @ts-ignore: exists
|
|
71
|
+
out.__DESERIALIZE(keyStart, keyEnd, lastIndex, srcStart, changetype<usize>(out));
|
|
72
|
+
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
73
|
+
// /* empty */
|
|
74
|
+
// }
|
|
75
|
+
srcStart += 2;
|
|
76
|
+
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
|
|
77
|
+
keyStart = 0;
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
srcStart += 2;
|
|
81
|
+
}
|
|
82
|
+
} else if (code == BRACE_LEFT) {
|
|
83
|
+
lastIndex = srcStart;
|
|
84
|
+
depth++;
|
|
85
|
+
srcStart += 2;
|
|
86
|
+
while (srcStart < srcEnd) {
|
|
87
|
+
const code = load<u16>(srcStart);
|
|
88
|
+
if (code == QUOTE) {
|
|
89
|
+
srcStart += 2;
|
|
90
|
+
while (!(load<u16>(srcStart) == QUOTE && load<u16>(srcStart - 2) != BACK_SLASH)) srcStart += 2;
|
|
91
|
+
} else if (code == BRACE_RIGHT) {
|
|
92
|
+
if (--depth == 0) {
|
|
93
|
+
// console.log("Value (object): " + ptrToStr(lastIndex, srcStart + 2));
|
|
94
|
+
// @ts-ignore: exists
|
|
95
|
+
out.__DESERIALIZE(keyStart, keyEnd, lastIndex, (srcStart += 2), changetype<usize>(out));
|
|
96
|
+
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
|
|
97
|
+
keyStart = 0;
|
|
98
|
+
// while (isSpace(load<u16>(srcStart))) {
|
|
99
|
+
// /* empty */
|
|
100
|
+
// }
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
} else if (code == BRACE_LEFT) depth++;
|
|
104
|
+
srcStart += 2;
|
|
105
|
+
}
|
|
106
|
+
} else if (code == BRACKET_LEFT) {
|
|
107
|
+
lastIndex = srcStart;
|
|
108
|
+
depth++;
|
|
109
|
+
srcStart += 2;
|
|
110
|
+
while (srcStart < srcEnd) {
|
|
111
|
+
const code = load<u16>(srcStart);
|
|
112
|
+
if (code == BRACKET_RIGHT) {
|
|
113
|
+
if (--depth == 0) {
|
|
114
|
+
// console.log("Value (array): " + ptrToStr(lastIndex, srcStart + 2));
|
|
115
|
+
// @ts-ignore: exists
|
|
116
|
+
out.__DESERIALIZE(keyStart, keyEnd, lastIndex, (srcStart += 2), changetype<usize>(out));
|
|
117
|
+
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
|
|
118
|
+
keyStart = 0;
|
|
119
|
+
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
120
|
+
// /* empty */
|
|
121
|
+
// }
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
} else if (code == BRACKET_LEFT) depth++;
|
|
125
|
+
srcStart += 2;
|
|
126
|
+
}
|
|
127
|
+
} else if (code == CHAR_T) {
|
|
128
|
+
if (load<u64>(srcStart) == 28429475166421108) {
|
|
129
|
+
// console.log("Value (bool): " + ptrToStr(srcStart, srcStart + 8));
|
|
130
|
+
// @ts-ignore: exists
|
|
131
|
+
out.__DESERIALIZE(keyStart, keyEnd, srcStart, (srcStart += 8), changetype<usize>(out));
|
|
132
|
+
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
133
|
+
// /* empty */
|
|
134
|
+
// }
|
|
135
|
+
srcStart += 2;
|
|
136
|
+
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)) + " " + (srcStart < srcEnd).toString());
|
|
137
|
+
keyStart = 0;
|
|
138
|
+
}
|
|
139
|
+
} else if (code == CHAR_F) {
|
|
140
|
+
if (load<u64>(srcStart, 2) == 28429466576093281) {
|
|
141
|
+
// console.log("Value (bool): " + ptrToStr(srcStart, srcStart + 10));
|
|
142
|
+
// @ts-ignore: exists
|
|
143
|
+
out.__DESERIALIZE(keyStart, keyEnd, srcStart, (srcStart += 10), changetype<usize>(out));
|
|
144
|
+
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
145
|
+
// /* empty */
|
|
146
|
+
// }
|
|
147
|
+
srcStart += 2;
|
|
148
|
+
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
|
|
149
|
+
keyStart = 0;
|
|
150
|
+
}
|
|
151
|
+
} else if (code == CHAR_N) {
|
|
152
|
+
if (load<u64>(srcStart) == 30399761348886638) {
|
|
153
|
+
// console.log("Value (null): " + ptrToStr(srcStart, srcStart + 8));
|
|
154
|
+
// @ts-ignore: exists
|
|
155
|
+
out.__DESERIALIZE(keyStart, keyEnd, srcStart, (srcStart += 8), changetype<usize>(out));
|
|
156
|
+
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
157
|
+
/* empty */
|
|
158
|
+
// }
|
|
159
|
+
srcStart += 2;
|
|
160
|
+
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
|
|
161
|
+
keyStart = 0;
|
|
162
|
+
}
|
|
163
|
+
} else if (isSpace(code)) {
|
|
164
|
+
srcStart += 2;
|
|
165
|
+
} else {
|
|
166
|
+
throw new Error("Unexpected character in JSON object '" + String.fromCharCode(code) + "' at position " + (srcEnd - srcStart).toString());
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return out;
|
|
171
|
+
}
|
package/assembly/index.d.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Class decorator that enables the class to be recognized as JSON.
|
|
3
3
|
*/
|
|
4
|
+
// @ts-ignore: type
|
|
4
5
|
declare function json(..._): void;
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Class decorator that enables the class to be recognized as JSON.
|
|
8
9
|
*/
|
|
10
|
+
// @ts-ignore: type
|
|
9
11
|
declare function serializable(..._): void;
|
|
10
12
|
|
|
11
13
|
/**
|
|
@@ -16,6 +18,7 @@ declare function alias(newName: string): Function;
|
|
|
16
18
|
/**
|
|
17
19
|
* Property decorator that allows omits a field, making it be ignored.
|
|
18
20
|
*/
|
|
21
|
+
// @ts-ignore: type
|
|
19
22
|
declare function omit(..._): void;
|
|
20
23
|
|
|
21
24
|
/**
|
|
@@ -26,6 +29,17 @@ declare function omitif(condition: string | ((value: any) => boolean)): Function
|
|
|
26
29
|
/**
|
|
27
30
|
* Property decorator that allows a field to be omitted when a property is null.
|
|
28
31
|
*/
|
|
32
|
+
// @ts-ignore: type
|
|
29
33
|
declare function omitnull(..._): Function;
|
|
30
34
|
|
|
31
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Method decorator that denotes a function to handle that schema's serialization.
|
|
37
|
+
*/
|
|
38
|
+
// @ts-ignore: type
|
|
39
|
+
declare function serializer(..._): any;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Method decorator that denotes a function to handle that schema's deserialization.
|
|
43
|
+
*/
|
|
44
|
+
// @ts-ignore: type
|
|
45
|
+
declare function deserializer(..._): any;
|