json-as 0.5.38 → 0.5.41
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/assembly/__benches__/as-json.ts +19 -11
- package/assembly/src/json.ts +584 -556
- package/assembly/src/util.ts +17 -9
- package/assembly/test.ts +33 -5
- package/package.json +1 -1
- package/transform/lib/index.js +47 -72
- package/transform/package.json +1 -1
- package/transform/src/index.ts +16 -10
- package/transform/lib/hash.js +0 -72
- package/transform/lib/types.js +0 -15
package/assembly/src/json.ts
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
import { StringSink } from "as-string-sink/assembly";
|
|
2
2
|
import { isSpace, CharCode } from "util/string";
|
|
3
3
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
4
|
+
backSlashCode,
|
|
5
|
+
commaCode,
|
|
6
|
+
commaWord,
|
|
7
|
+
eCode,
|
|
8
|
+
fCode,
|
|
9
|
+
leftBraceCode,
|
|
10
|
+
leftBracketCode,
|
|
11
|
+
leftBracketWord,
|
|
12
|
+
nCode,
|
|
13
|
+
nullWord,
|
|
14
|
+
quoteCode,
|
|
15
|
+
rCode,
|
|
16
|
+
rightBraceCode,
|
|
17
|
+
rightBracketCode,
|
|
18
|
+
rightBracketWord,
|
|
19
|
+
tCode,
|
|
20
|
+
trueWord,
|
|
21
|
+
uCode,
|
|
22
|
+
emptyArrayWord,
|
|
23
23
|
} from "./chars";
|
|
24
24
|
import { parseSciInteger, unsafeCharCodeAt } from "./util";
|
|
25
25
|
|
|
@@ -27,201 +27,209 @@ import { parseSciInteger, unsafeCharCodeAt } from "./util";
|
|
|
27
27
|
* JSON Encoder/Decoder for AssemblyScript
|
|
28
28
|
*/
|
|
29
29
|
export namespace JSON {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
result += serializeString(unchecked(data[data.length - 1]));
|
|
73
|
-
result += rightBracketWord;
|
|
74
|
-
return result;
|
|
75
|
-
// @ts-ignore
|
|
76
|
-
} else if (isBoolean<valueof<T>>()) {
|
|
77
|
-
// @ts-ignore
|
|
78
|
-
return leftBracketWord + data.join(commaWord) + rightBracketWord;
|
|
79
|
-
// @ts-ignore
|
|
80
|
-
} else if (isFloat<valueof<T>>() || isInteger<valueof<T>>()) {
|
|
81
|
-
// @ts-ignore
|
|
82
|
-
return leftBracketWord + data.join(commaWord) + rightBracketWord;
|
|
83
|
-
} else {
|
|
84
|
-
let result = new StringSink(leftBracketWord);
|
|
85
|
-
// @ts-ignore
|
|
86
|
-
for (let i = 0; i < data.length - 1; i++) {
|
|
87
|
-
// @ts-ignore
|
|
88
|
-
result.write(JSON.stringify(unchecked(data[i])));
|
|
89
|
-
result.write(commaWord);
|
|
90
|
-
}
|
|
91
|
-
// @ts-ignore
|
|
92
|
-
result.write(JSON.stringify(unchecked(data[data.length - 1])));
|
|
93
|
-
result.write(rightBracketWord);
|
|
94
|
-
return result.toString();
|
|
95
|
-
}
|
|
96
|
-
} else {
|
|
97
|
-
throw new Error(
|
|
98
|
-
`Could not serialize data of type ${nameof<T>()}. Make sure to add the correct decorators to classes.`
|
|
99
|
-
);
|
|
30
|
+
/**
|
|
31
|
+
* Stringifies valid JSON data.
|
|
32
|
+
* ```js
|
|
33
|
+
* JSON.stringify<T>(data)
|
|
34
|
+
* ```
|
|
35
|
+
* @param data T
|
|
36
|
+
* @returns string
|
|
37
|
+
*/
|
|
38
|
+
// @ts-ignore
|
|
39
|
+
@inline export function stringify<
|
|
40
|
+
T
|
|
41
|
+
>(data: T): string {
|
|
42
|
+
// String
|
|
43
|
+
if (isString<T>() && data != null) {
|
|
44
|
+
// @ts-ignore
|
|
45
|
+
return serializeString(data);
|
|
46
|
+
} else if (isBoolean<T>()) {
|
|
47
|
+
return data ? "true" : "false";
|
|
48
|
+
} else if (isNullable<T>() && data == null) {
|
|
49
|
+
return "null";
|
|
50
|
+
// @ts-ignore
|
|
51
|
+
} else if ((isInteger<T>() || isFloat<T>()) && isFinite(data)) {
|
|
52
|
+
// @ts-ignore
|
|
53
|
+
return data.toString();
|
|
54
|
+
// @ts-ignore
|
|
55
|
+
} else if (isDefined(data.__JSON_Serialize)) {
|
|
56
|
+
// @ts-ignore
|
|
57
|
+
return data.__JSON_Serialize();
|
|
58
|
+
} else if (data instanceof Date) {
|
|
59
|
+
return data.toISOString();
|
|
60
|
+
} else if (isArrayLike<T>()) {
|
|
61
|
+
// @ts-ignore
|
|
62
|
+
if (data.length == 0) {
|
|
63
|
+
return emptyArrayWord;
|
|
64
|
+
// @ts-ignore
|
|
65
|
+
} else if (isString<valueof<T>>()) {
|
|
66
|
+
let result = "[";
|
|
67
|
+
// @ts-ignore
|
|
68
|
+
for (let i = 0; i < data.length - 1; i++) {
|
|
69
|
+
// @ts-ignore
|
|
70
|
+
result += serializeString(unchecked(data[i]));
|
|
71
|
+
result += commaWord;
|
|
100
72
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
} else if (isFloat<T>() || isInteger<T>()) {
|
|
121
|
-
return parseNumber<T>(data);
|
|
122
|
-
} else if (isArrayLike<T>()) {
|
|
123
|
-
// @ts-ignore
|
|
124
|
-
return parseArray<T>(data.trimStart());
|
|
125
|
-
// @ts-ignore
|
|
126
|
-
} else if (isNullable<T>() && data == "null") {
|
|
127
|
-
// @ts-ignore
|
|
128
|
-
return null;
|
|
129
|
-
// @ts-ignore
|
|
130
|
-
} else if (isDefined(type.__JSON_Set_Key)) {
|
|
131
|
-
return parseObject<T>(data.trimStart());
|
|
132
|
-
} else if (idof<nonnull<T>>() == idof<Date>()) {
|
|
133
|
-
// @ts-ignore
|
|
134
|
-
return Date.fromString(data);
|
|
135
|
-
} else {
|
|
136
|
-
// @ts-ignore
|
|
137
|
-
throw new Error(
|
|
138
|
-
`Could not deserialize data ${data} to type ${nameof<T>()}. Make sure to add the correct decorators to classes.`
|
|
139
|
-
);
|
|
73
|
+
// @ts-ignore
|
|
74
|
+
result += serializeString(unchecked(data[data.length - 1]));
|
|
75
|
+
result += rightBracketWord;
|
|
76
|
+
return result;
|
|
77
|
+
// @ts-ignore
|
|
78
|
+
} else if (isBoolean<valueof<T>>()) {
|
|
79
|
+
// @ts-ignore
|
|
80
|
+
return leftBracketWord + data.join(commaWord) + rightBracketWord;
|
|
81
|
+
// @ts-ignore
|
|
82
|
+
} else if (isFloat<valueof<T>>() || isInteger<valueof<T>>()) {
|
|
83
|
+
// @ts-ignore
|
|
84
|
+
return leftBracketWord + data.join(commaWord) + rightBracketWord;
|
|
85
|
+
} else {
|
|
86
|
+
let result = new StringSink(leftBracketWord);
|
|
87
|
+
// @ts-ignore
|
|
88
|
+
for (let i = 0; i < data.length - 1; i++) {
|
|
89
|
+
// @ts-ignore
|
|
90
|
+
result.write(JSON.stringify(unchecked(data[i])));
|
|
91
|
+
result.write(commaWord);
|
|
140
92
|
}
|
|
93
|
+
// @ts-ignore
|
|
94
|
+
result.write(JSON.stringify(unchecked(data[data.length - 1])));
|
|
95
|
+
result.write(rightBracketWord);
|
|
96
|
+
return result.toString();
|
|
97
|
+
}
|
|
98
|
+
} else {
|
|
99
|
+
throw new Error(
|
|
100
|
+
`Could not serialize data of type ${nameof<T>()}. Make sure to add the correct decorators to classes.`
|
|
101
|
+
);
|
|
141
102
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Parses valid JSON strings into their original format.
|
|
106
|
+
* ```js
|
|
107
|
+
* JSON.parse<T>(data)
|
|
108
|
+
* ```
|
|
109
|
+
* @param data string
|
|
110
|
+
* @returns T
|
|
111
|
+
*/
|
|
112
|
+
|
|
113
|
+
// @ts-ignore
|
|
114
|
+
@inline export function parse<
|
|
115
|
+
T
|
|
116
|
+
>(data: string): T {
|
|
117
|
+
let type: T;
|
|
118
|
+
if (isString<T>()) {
|
|
119
|
+
// @ts-ignore
|
|
120
|
+
return parseString(data);
|
|
121
|
+
} else if (isBoolean<T>()) {
|
|
122
|
+
// @ts-ignore
|
|
123
|
+
return parseBoolean<T>(data);
|
|
124
|
+
} else if (isFloat<T>() || isInteger<T>()) {
|
|
125
|
+
return parseNumber<T>(data);
|
|
126
|
+
} else if (isArrayLike<T>()) {
|
|
127
|
+
// @ts-ignore
|
|
128
|
+
return parseArray<T>(data.trimStart());
|
|
129
|
+
// @ts-ignore
|
|
130
|
+
} else if (isNullable<T>() && data == "null") {
|
|
131
|
+
// @ts-ignore
|
|
132
|
+
return null;
|
|
133
|
+
// @ts-ignore
|
|
134
|
+
} else if (isDefined(type.__JSON_Set_Key)) {
|
|
135
|
+
return parseObject<T>(data.trimStart());
|
|
136
|
+
} else if (idof<nonnull<T>>() == idof<Date>()) {
|
|
137
|
+
// @ts-ignore
|
|
138
|
+
return Date.fromString(data);
|
|
139
|
+
} else {
|
|
140
|
+
// @ts-ignore
|
|
141
|
+
throw new Error(
|
|
142
|
+
`Could not deserialize data ${data} to type ${nameof<T>()}. Make sure to add the correct decorators to classes.`
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// @ts-ignore
|
|
147
|
+
@inline function parseObjectValue<
|
|
148
|
+
T
|
|
149
|
+
>(data: string): T {
|
|
150
|
+
let type: T;
|
|
151
|
+
if (isString<T>()) {
|
|
152
|
+
// @ts-ignore
|
|
153
|
+
let result = "";
|
|
154
|
+
let last = 0;
|
|
155
|
+
let char = 0;
|
|
156
|
+
for (let i = 0; i < data.length; i++) {
|
|
157
|
+
// \\"
|
|
158
|
+
if (unsafeCharCodeAt(data, i) === backSlashCode) {
|
|
159
|
+
char = unsafeCharCodeAt(data, ++i);
|
|
160
|
+
result += data.slice(last, i - 1);
|
|
161
|
+
if (char === 34) {
|
|
162
|
+
result += '"';
|
|
163
|
+
last = ++i;
|
|
164
|
+
} else if (char === 110) {
|
|
165
|
+
result += "\n";
|
|
166
|
+
last = ++i;
|
|
167
|
+
// 92 98 114 116 102 117
|
|
168
|
+
} else if (char >= 92 && char <= 117) {
|
|
169
|
+
if (char === 92) {
|
|
170
|
+
result += "\\";
|
|
171
|
+
last = ++i;
|
|
172
|
+
} else if (char === 98) {
|
|
173
|
+
result += "\b";
|
|
174
|
+
last = ++i;
|
|
175
|
+
} else if (char === 102) {
|
|
176
|
+
result += "\f";
|
|
177
|
+
last = ++i;
|
|
178
|
+
} else if (char === 114) {
|
|
179
|
+
result += "\r";
|
|
180
|
+
last = ++i;
|
|
181
|
+
} else if (char === 116) {
|
|
182
|
+
result += "\t";
|
|
183
|
+
last = ++i;
|
|
184
|
+
} else if (
|
|
185
|
+
char === 117 &&
|
|
186
|
+
load<u64>(changetype<usize>(data) + <usize>((i + 1) << 1)) ===
|
|
187
|
+
27584753879220272
|
|
188
|
+
) {
|
|
189
|
+
result += "\u000b";
|
|
190
|
+
i += 4;
|
|
191
|
+
last = ++i;
|
|
189
192
|
}
|
|
190
|
-
|
|
191
|
-
// @ts-ignore
|
|
192
|
-
return result;
|
|
193
|
-
} else if (isBoolean<T>()) {
|
|
194
|
-
// @ts-ignore
|
|
195
|
-
return parseBoolean<T>(data);
|
|
196
|
-
} else if (isFloat<T>() || isInteger<T>()) {
|
|
197
|
-
return parseNumber<T>(data);
|
|
198
|
-
} else if (isArrayLike<T>()) {
|
|
199
|
-
// @ts-ignore
|
|
200
|
-
return parseArray<T>(data);
|
|
201
|
-
// @ts-ignore
|
|
202
|
-
} else if (isNullable<T>() && data == "null") {
|
|
203
|
-
// @ts-ignore
|
|
204
|
-
return null;
|
|
205
|
-
// @ts-ignore
|
|
206
|
-
} else if (isDefined(type.__JSON_Set_Key)) {
|
|
207
|
-
return parseObject<T>(data.trimStart());
|
|
208
|
-
} else if (idof<nonnull<T>>() == idof<Date>()) {
|
|
209
|
-
// @ts-ignore
|
|
210
|
-
return Date.fromString(data);
|
|
211
|
-
} else {
|
|
212
|
-
// @ts-ignore
|
|
213
|
-
throw new Error(
|
|
214
|
-
`Could not deserialize data ${data} to type ${nameof<T>()}. Make sure to add the correct decorators to classes.`
|
|
215
|
-
);
|
|
193
|
+
}
|
|
216
194
|
}
|
|
195
|
+
}
|
|
196
|
+
result += data.slice(last);
|
|
197
|
+
// @ts-ignore
|
|
198
|
+
return result;
|
|
199
|
+
} else if (isBoolean<T>()) {
|
|
200
|
+
// @ts-ignore
|
|
201
|
+
return parseBoolean<T>(data);
|
|
202
|
+
} else if (isFloat<T>() || isInteger<T>()) {
|
|
203
|
+
return parseNumber<T>(data);
|
|
204
|
+
} else if (isArrayLike<T>()) {
|
|
205
|
+
// @ts-ignore
|
|
206
|
+
return parseArray<T>(data);
|
|
207
|
+
// @ts-ignore
|
|
208
|
+
} else if (isNullable<T>() && data == "null") {
|
|
209
|
+
// @ts-ignore
|
|
210
|
+
return null;
|
|
211
|
+
// @ts-ignore
|
|
212
|
+
} else if (isDefined(type.__JSON_Set_Key)) {
|
|
213
|
+
return parseObject<T>(data.trimStart());
|
|
214
|
+
} else if (idof<nonnull<T>>() == idof<Date>()) {
|
|
215
|
+
// @ts-ignore
|
|
216
|
+
return Date.fromString(data);
|
|
217
|
+
} else {
|
|
218
|
+
// @ts-ignore
|
|
219
|
+
throw new Error(
|
|
220
|
+
`Could not deserialize data ${data} to type ${nameof<T>()}. Make sure to add the correct decorators to classes.`
|
|
221
|
+
);
|
|
217
222
|
}
|
|
223
|
+
}
|
|
218
224
|
}
|
|
219
225
|
|
|
220
226
|
// @ts-ignore
|
|
221
|
-
@inline function serializeString(
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
227
|
+
@inline function serializeString(
|
|
228
|
+
data: string
|
|
229
|
+
): string {
|
|
230
|
+
// @ts-ignore
|
|
231
|
+
//if (data.length === 0) return "\"\"";
|
|
232
|
+
/*
|
|
225
233
|
let char: i32 = 0;
|
|
226
234
|
if (data.length === 1) {
|
|
227
235
|
char = unsafeCharCodeAt(data, 0);
|
|
@@ -255,325 +263,339 @@ export namespace JSON {
|
|
|
255
263
|
}
|
|
256
264
|
}*/
|
|
257
265
|
|
|
258
|
-
|
|
266
|
+
let result = '"';
|
|
259
267
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
}
|
|
292
|
-
case 13: {
|
|
293
|
-
result += "\\r";
|
|
294
|
-
break;
|
|
295
|
-
}
|
|
296
|
-
}
|
|
268
|
+
let last: i32 = 0;
|
|
269
|
+
// @ts-ignore
|
|
270
|
+
for (let i = 0; i < data.length; i++) {
|
|
271
|
+
const char = unsafeCharCodeAt(<string>data, i);
|
|
272
|
+
if (char === 34 || char === 92) {
|
|
273
|
+
result += (<string>data).slice(last, i) + "\\";
|
|
274
|
+
last = i;
|
|
275
|
+
i++;
|
|
276
|
+
} else if (char <= 13 && char >= 8) {
|
|
277
|
+
result += (<string>data).slice(last, i);
|
|
278
|
+
last = ++i;
|
|
279
|
+
switch (char) {
|
|
280
|
+
case 8: {
|
|
281
|
+
result += "\\b";
|
|
282
|
+
break;
|
|
283
|
+
}
|
|
284
|
+
case 9: {
|
|
285
|
+
result += "\\t";
|
|
286
|
+
break;
|
|
287
|
+
}
|
|
288
|
+
case 10: {
|
|
289
|
+
result += "\\n";
|
|
290
|
+
break;
|
|
291
|
+
}
|
|
292
|
+
case 11: {
|
|
293
|
+
result += "\\x0B"; // \\u000b
|
|
294
|
+
break;
|
|
295
|
+
}
|
|
296
|
+
case 12: {
|
|
297
|
+
result += "\\f";
|
|
298
|
+
break;
|
|
297
299
|
}
|
|
300
|
+
case 13: {
|
|
301
|
+
result += "\\r";
|
|
302
|
+
break;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
298
305
|
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
306
|
+
}
|
|
307
|
+
if (result.length === 1) return '"' + data + '"';
|
|
308
|
+
else result += (<string>data).slice(last);
|
|
309
|
+
return result + '"';
|
|
302
310
|
}
|
|
303
311
|
|
|
304
312
|
// @ts-ignore
|
|
305
|
-
@inline function parseString(
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
}
|
|
363
|
-
}
|
|
313
|
+
@inline function parseString(
|
|
314
|
+
data: string
|
|
315
|
+
): string {
|
|
316
|
+
let result = "";
|
|
317
|
+
let last = 1;
|
|
318
|
+
for (let i = 1; i < data.length - 1; i++) {
|
|
319
|
+
// \\"
|
|
320
|
+
if (unsafeCharCodeAt(data, i) === backSlashCode) {
|
|
321
|
+
const char = unsafeCharCodeAt(data, ++i);
|
|
322
|
+
result += data.slice(last, i - 1);
|
|
323
|
+
if (char === 34) {
|
|
324
|
+
result += '"';
|
|
325
|
+
last = ++i;
|
|
326
|
+
} else if (char === 110) {
|
|
327
|
+
result += "\n";
|
|
328
|
+
last = ++i;
|
|
329
|
+
// 92 98 114 116 102 117
|
|
330
|
+
} else if (char >= 92 && char <= 117) {
|
|
331
|
+
switch (char) {
|
|
332
|
+
case 92: {
|
|
333
|
+
result += "\\";
|
|
334
|
+
last = ++i;
|
|
335
|
+
break;
|
|
336
|
+
}
|
|
337
|
+
case 98: {
|
|
338
|
+
result += "\b";
|
|
339
|
+
last = ++i;
|
|
340
|
+
break;
|
|
341
|
+
}
|
|
342
|
+
case 110: {
|
|
343
|
+
result += "\n";
|
|
344
|
+
last = ++i;
|
|
345
|
+
}
|
|
346
|
+
case 102: {
|
|
347
|
+
result += "\f";
|
|
348
|
+
last = ++i;
|
|
349
|
+
break;
|
|
350
|
+
}
|
|
351
|
+
case 114: {
|
|
352
|
+
result += "\r";
|
|
353
|
+
last = ++i;
|
|
354
|
+
break;
|
|
355
|
+
}
|
|
356
|
+
case 116: {
|
|
357
|
+
result += "\t";
|
|
358
|
+
last = ++i;
|
|
359
|
+
break;
|
|
360
|
+
}
|
|
361
|
+
default: {
|
|
362
|
+
if (
|
|
363
|
+
char === 117 &&
|
|
364
|
+
load<u64>(changetype<usize>(data) + <usize>((i + 1) << 1)) ===
|
|
365
|
+
27584753879220272
|
|
366
|
+
) {
|
|
367
|
+
result += "\u000b";
|
|
368
|
+
i += 4;
|
|
369
|
+
last = ++i;
|
|
364
370
|
}
|
|
371
|
+
break;
|
|
372
|
+
}
|
|
365
373
|
}
|
|
374
|
+
}
|
|
366
375
|
}
|
|
367
|
-
|
|
368
|
-
|
|
376
|
+
}
|
|
377
|
+
result += data.slice(last, data.length - 1);
|
|
378
|
+
return result;
|
|
369
379
|
}
|
|
370
380
|
|
|
371
381
|
// @ts-ignore
|
|
372
|
-
@inline function parseBoolean<
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
382
|
+
@inline function parseBoolean<
|
|
383
|
+
T extends boolean
|
|
384
|
+
>(data: string): T {
|
|
385
|
+
if (data.length > 3 && data.startsWith("true")) return <T>true;
|
|
386
|
+
else if (data.length > 4 && data.startsWith("false")) return <T>false;
|
|
387
|
+
else throw new Error(`JSON: Cannot parse "${data}" as boolean`);
|
|
376
388
|
}
|
|
377
389
|
|
|
378
390
|
// @ts-ignore
|
|
379
|
-
@inline export function parseNumber<
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
}
|
|
384
|
-
// @ts-ignore
|
|
385
|
-
const type: T = 0;
|
|
391
|
+
@inline export function parseNumber<
|
|
392
|
+
T
|
|
393
|
+
>(data: string): T {
|
|
394
|
+
if (isInteger<T>()) {
|
|
386
395
|
// @ts-ignore
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
396
|
+
return parseSciInteger<T>(data);
|
|
397
|
+
}
|
|
398
|
+
// @ts-ignore
|
|
399
|
+
const type: T = 0;
|
|
400
|
+
// @ts-ignore
|
|
401
|
+
if (type instanceof f64) return f64.parse(data);
|
|
402
|
+
// @ts-ignore
|
|
403
|
+
else if (type instanceof f32) return f32.parse(data);
|
|
390
404
|
}
|
|
391
405
|
|
|
392
406
|
// @ts-ignore
|
|
393
|
-
@inline function parseObject<
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
407
|
+
@inline function parseObject<
|
|
408
|
+
T
|
|
409
|
+
>(data: string): T {
|
|
410
|
+
let schema: nonnull<T> = changetype<nonnull<T>>(
|
|
411
|
+
__new(offsetof<nonnull<T>>(), idof<nonnull<T>>())
|
|
412
|
+
);
|
|
413
|
+
let key = "";
|
|
414
|
+
let isKey = false;
|
|
415
|
+
let depth = 0;
|
|
416
|
+
let char = 0;
|
|
417
|
+
let outerLoopIndex = 1;
|
|
418
|
+
for (; outerLoopIndex < data.length - 1; outerLoopIndex++) {
|
|
419
|
+
char = unsafeCharCodeAt(data, outerLoopIndex);
|
|
420
|
+
if (char === leftBracketCode) {
|
|
421
|
+
for (
|
|
422
|
+
let arrayValueIndex = outerLoopIndex;
|
|
423
|
+
arrayValueIndex < data.length - 1;
|
|
424
|
+
arrayValueIndex++
|
|
425
|
+
) {
|
|
426
|
+
char = unsafeCharCodeAt(data, arrayValueIndex);
|
|
404
427
|
if (char === leftBracketCode) {
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
char = unsafeCharCodeAt(data, arrayValueIndex);
|
|
411
|
-
if (char === leftBracketCode) {
|
|
412
|
-
depth++;
|
|
413
|
-
} else if (char === rightBracketCode) {
|
|
414
|
-
depth--;
|
|
415
|
-
if (depth === 0) {
|
|
416
|
-
++arrayValueIndex;
|
|
417
|
-
// @ts-ignore
|
|
418
|
-
schema.__JSON_Set_Key(
|
|
419
|
-
key,
|
|
420
|
-
data.slice(outerLoopIndex, arrayValueIndex)
|
|
421
|
-
);
|
|
422
|
-
outerLoopIndex = arrayValueIndex;
|
|
423
|
-
isKey = false;
|
|
424
|
-
break;
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
} else if (char === leftBraceCode) {
|
|
429
|
-
for (
|
|
430
|
-
let objectValueIndex = outerLoopIndex;
|
|
431
|
-
objectValueIndex < data.length - 1;
|
|
432
|
-
objectValueIndex++
|
|
433
|
-
) {
|
|
434
|
-
char = unsafeCharCodeAt(data, objectValueIndex);
|
|
435
|
-
if (char === leftBraceCode) {
|
|
436
|
-
depth++;
|
|
437
|
-
} else if (char === rightBraceCode) {
|
|
438
|
-
depth--;
|
|
439
|
-
if (depth === 0) {
|
|
440
|
-
++objectValueIndex;
|
|
441
|
-
// @ts-ignore
|
|
442
|
-
schema.__JSON_Set_Key(
|
|
443
|
-
key,
|
|
444
|
-
data.slice(outerLoopIndex, objectValueIndex)
|
|
445
|
-
);
|
|
446
|
-
outerLoopIndex = objectValueIndex;
|
|
447
|
-
isKey = false;
|
|
448
|
-
break;
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
} else if (char === quoteCode) {
|
|
453
|
-
for (
|
|
454
|
-
let stringValueIndex = ++outerLoopIndex;
|
|
455
|
-
stringValueIndex < data.length - 1;
|
|
456
|
-
stringValueIndex++
|
|
457
|
-
) {
|
|
458
|
-
char = unsafeCharCodeAt(data, stringValueIndex);
|
|
459
|
-
if (
|
|
460
|
-
char === quoteCode &&
|
|
461
|
-
unsafeCharCodeAt(data, stringValueIndex - 1) !== backSlashCode
|
|
462
|
-
) {
|
|
463
|
-
if (isKey === false) {
|
|
464
|
-
key = data.slice(outerLoopIndex, stringValueIndex);
|
|
465
|
-
isKey = true;
|
|
466
|
-
} else {
|
|
467
|
-
// @ts-ignore
|
|
468
|
-
schema.__JSON_Set_Key(
|
|
469
|
-
key,
|
|
470
|
-
data.slice(outerLoopIndex, stringValueIndex)
|
|
471
|
-
);
|
|
472
|
-
isKey = false;
|
|
473
|
-
}
|
|
474
|
-
outerLoopIndex = ++stringValueIndex;
|
|
475
|
-
break;
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
} else if (char == nCode) {
|
|
428
|
+
depth++;
|
|
429
|
+
} else if (char === rightBracketCode) {
|
|
430
|
+
depth--;
|
|
431
|
+
if (depth === 0) {
|
|
432
|
+
++arrayValueIndex;
|
|
479
433
|
// @ts-ignore
|
|
480
|
-
schema.__JSON_Set_Key(
|
|
434
|
+
schema.__JSON_Set_Key(
|
|
435
|
+
key,
|
|
436
|
+
data.slice(outerLoopIndex, arrayValueIndex)
|
|
437
|
+
);
|
|
438
|
+
outerLoopIndex = arrayValueIndex;
|
|
481
439
|
isKey = false;
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
440
|
+
break;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
} else if (char === leftBraceCode) {
|
|
445
|
+
for (
|
|
446
|
+
let objectValueIndex = outerLoopIndex;
|
|
447
|
+
objectValueIndex < data.length - 1;
|
|
448
|
+
objectValueIndex++
|
|
449
|
+
) {
|
|
450
|
+
char = unsafeCharCodeAt(data, objectValueIndex);
|
|
451
|
+
if (char === leftBraceCode) {
|
|
452
|
+
depth++;
|
|
453
|
+
} else if (char === rightBraceCode) {
|
|
454
|
+
depth--;
|
|
455
|
+
if (depth === 0) {
|
|
456
|
+
++objectValueIndex;
|
|
488
457
|
// @ts-ignore
|
|
489
|
-
schema.__JSON_Set_Key(
|
|
458
|
+
schema.__JSON_Set_Key(
|
|
459
|
+
key,
|
|
460
|
+
data.slice(outerLoopIndex, objectValueIndex)
|
|
461
|
+
);
|
|
462
|
+
outerLoopIndex = objectValueIndex;
|
|
490
463
|
isKey = false;
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
464
|
+
break;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
} else if (char === quoteCode) {
|
|
469
|
+
for (
|
|
470
|
+
let stringValueIndex = ++outerLoopIndex;
|
|
471
|
+
stringValueIndex < data.length - 1;
|
|
472
|
+
stringValueIndex++
|
|
473
|
+
) {
|
|
474
|
+
char = unsafeCharCodeAt(data, stringValueIndex);
|
|
475
|
+
if (
|
|
476
|
+
char === quoteCode &&
|
|
477
|
+
unsafeCharCodeAt(data, stringValueIndex - 1) !== backSlashCode
|
|
497
478
|
) {
|
|
479
|
+
if (isKey === false) {
|
|
480
|
+
key = data.slice(outerLoopIndex, stringValueIndex);
|
|
481
|
+
isKey = true;
|
|
482
|
+
} else {
|
|
498
483
|
// @ts-ignore
|
|
499
|
-
schema.__JSON_Set_Key(
|
|
484
|
+
schema.__JSON_Set_Key(
|
|
485
|
+
key,
|
|
486
|
+
data.slice(outerLoopIndex, stringValueIndex)
|
|
487
|
+
);
|
|
500
488
|
isKey = false;
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
489
|
+
}
|
|
490
|
+
outerLoopIndex = ++stringValueIndex;
|
|
491
|
+
break;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
} else if (char == nCode) {
|
|
495
|
+
// @ts-ignore
|
|
496
|
+
schema.__JSON_Set_Key(key, nullWord);
|
|
497
|
+
isKey = false;
|
|
498
|
+
} else if (
|
|
499
|
+
char === tCode &&
|
|
500
|
+
unsafeCharCodeAt(data, ++outerLoopIndex) === rCode &&
|
|
501
|
+
unsafeCharCodeAt(data, ++outerLoopIndex) === uCode &&
|
|
502
|
+
unsafeCharCodeAt(data, ++outerLoopIndex) === eCode
|
|
503
|
+
) {
|
|
504
|
+
// @ts-ignore
|
|
505
|
+
schema.__JSON_Set_Key(key, trueWord);
|
|
506
|
+
isKey = false;
|
|
507
|
+
} else if (
|
|
508
|
+
char === fCode &&
|
|
509
|
+
unsafeCharCodeAt(data, ++outerLoopIndex) === "a".charCodeAt(0) &&
|
|
510
|
+
unsafeCharCodeAt(data, ++outerLoopIndex) === "l".charCodeAt(0) &&
|
|
511
|
+
unsafeCharCodeAt(data, ++outerLoopIndex) === "s".charCodeAt(0) &&
|
|
512
|
+
unsafeCharCodeAt(data, ++outerLoopIndex) === eCode
|
|
513
|
+
) {
|
|
514
|
+
// @ts-ignore
|
|
515
|
+
schema.__JSON_Set_Key(key, "false");
|
|
516
|
+
isKey = false;
|
|
517
|
+
} else if ((char >= 48 && char <= 57) || char === 45) {
|
|
518
|
+
let numberValueIndex = ++outerLoopIndex;
|
|
519
|
+
for (; numberValueIndex < data.length; numberValueIndex++) {
|
|
520
|
+
char = unsafeCharCodeAt(data, numberValueIndex);
|
|
521
|
+
if (char === commaCode || char === rightBraceCode || isSpace(char)) {
|
|
522
|
+
// @ts-ignore
|
|
523
|
+
schema.__JSON_Set_Key(
|
|
524
|
+
key,
|
|
525
|
+
data.slice(outerLoopIndex - 1, numberValueIndex)
|
|
526
|
+
);
|
|
527
|
+
outerLoopIndex = numberValueIndex;
|
|
528
|
+
isKey = false;
|
|
529
|
+
break;
|
|
516
530
|
}
|
|
531
|
+
}
|
|
517
532
|
}
|
|
518
|
-
|
|
533
|
+
}
|
|
534
|
+
return schema;
|
|
519
535
|
}
|
|
520
536
|
|
|
521
537
|
// @ts-ignore
|
|
522
|
-
@inline function parseArray<
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
538
|
+
@inline function parseArray<
|
|
539
|
+
T extends unknown[]
|
|
540
|
+
>(data: string): T {
|
|
541
|
+
if (isString<valueof<T>>()) {
|
|
542
|
+
return <T>parseStringArray(data);
|
|
543
|
+
} else if (isBoolean<valueof<T>>()) {
|
|
544
|
+
// @ts-ignore
|
|
545
|
+
return parseBooleanArray<T>(data);
|
|
546
|
+
} else if (isFloat<valueof<T>>() || isInteger<valueof<T>>()) {
|
|
547
|
+
// @ts-ignore
|
|
548
|
+
return parseNumberArray<T>(data);
|
|
549
|
+
} else if (isArrayLike<valueof<T>>()) {
|
|
550
|
+
// @ts-ignore
|
|
551
|
+
return parseArrayArray<T>(data);
|
|
552
|
+
// @ts-ignore
|
|
553
|
+
} else if (isManaged<valueof<T>>() || isReference<valueof<T>>()) {
|
|
554
|
+
// We instantiate the required memory for the class and fill it. This is extremely unsafe and uses "a bit of magic".
|
|
555
|
+
const type = changetype<nonnull<valueof<T>>>(
|
|
556
|
+
__new(offsetof<nonnull<valueof<T>>>(), idof<nonnull<valueof<T>>>())
|
|
557
|
+
);
|
|
558
|
+
// @ts-ignore
|
|
559
|
+
if (isDefined(type.__JSON_Set_Key)) {
|
|
560
|
+
// @ts-ignore
|
|
561
|
+
return parseObjectArray<T>(data);
|
|
546
562
|
}
|
|
547
563
|
return unreachable();
|
|
564
|
+
}
|
|
565
|
+
return unreachable();
|
|
548
566
|
}
|
|
549
567
|
|
|
550
568
|
// @ts-ignore
|
|
551
|
-
@inline function parseStringArray(
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
569
|
+
@inline function parseStringArray(
|
|
570
|
+
data: string
|
|
571
|
+
): string[] {
|
|
572
|
+
const result: string[] = [];
|
|
573
|
+
let lastPos = 0;
|
|
574
|
+
let instr = false;
|
|
575
|
+
for (let i = 1; i < data.length - 1; i++) {
|
|
576
|
+
if (unsafeCharCodeAt(data, i) === quoteCode) {
|
|
577
|
+
if (instr === false) {
|
|
578
|
+
instr = true;
|
|
579
|
+
lastPos = i;
|
|
580
|
+
} else if (unsafeCharCodeAt(data, i - 1) !== backSlashCode) {
|
|
581
|
+
instr = false;
|
|
582
|
+
result.push(data.slice(lastPos + 1, i).replaceAll('\\"', '"'));
|
|
583
|
+
}
|
|
565
584
|
}
|
|
566
|
-
|
|
585
|
+
}
|
|
586
|
+
return result;
|
|
567
587
|
}
|
|
568
588
|
|
|
569
589
|
// @ts-ignore
|
|
570
|
-
@inline function parseBooleanArray<
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
590
|
+
@inline function parseBooleanArray<
|
|
591
|
+
T extends boolean[]
|
|
592
|
+
>(data: string): T {
|
|
593
|
+
const result = instantiate<T>();
|
|
594
|
+
let lastPos = 1;
|
|
595
|
+
let char = 0;
|
|
596
|
+
for (let i = 1; i < data.length - 1; i++) {
|
|
597
|
+
char = unsafeCharCodeAt(data, i);
|
|
598
|
+
/*// if char == "t" && i+3 == "e"
|
|
577
599
|
if (char === tCode && data.charCodeAt(i + 3) === eCode) {
|
|
578
600
|
//i += 3;
|
|
579
601
|
result.push(parseBoolean<valueof<T>>(data.slice(lastPos, i+2)));
|
|
@@ -583,91 +605,97 @@ export namespace JSON {
|
|
|
583
605
|
result.push(parseBoolean<valueof<T>>(data.slice(lastPos, i+3)));
|
|
584
606
|
//i++;
|
|
585
607
|
}*/
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
}
|
|
608
|
+
if (char === tCode || char === fCode) {
|
|
609
|
+
lastPos = i;
|
|
610
|
+
} else if (char === eCode) {
|
|
611
|
+
i++;
|
|
612
|
+
result.push(parseBoolean<valueof<T>>(data.slice(lastPos, i)));
|
|
592
613
|
}
|
|
593
|
-
|
|
614
|
+
}
|
|
615
|
+
return result;
|
|
594
616
|
}
|
|
595
617
|
|
|
596
618
|
// @ts-ignore
|
|
597
|
-
@inline function parseNumberArray<
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
619
|
+
@inline function parseNumberArray<
|
|
620
|
+
T extends number[]
|
|
621
|
+
>(data: string): T {
|
|
622
|
+
const result = instantiate<T>();
|
|
623
|
+
let lastPos = 0;
|
|
624
|
+
let char = 0;
|
|
625
|
+
let i = 1;
|
|
626
|
+
for (; i < data.length - 1; i++) {
|
|
627
|
+
char = unsafeCharCodeAt(data, i);
|
|
628
|
+
if ((lastPos === 0 && char >= 48 && char <= 57) || char === 45) {
|
|
629
|
+
lastPos = i;
|
|
630
|
+
} else if ((isSpace(char) || char == commaCode) && lastPos > 0) {
|
|
631
|
+
result.push(parseNumber<valueof<T>>(data.slice(lastPos, i)));
|
|
632
|
+
lastPos = 0;
|
|
610
633
|
}
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
634
|
+
}
|
|
635
|
+
for (; i > lastPos - 1; i--) {
|
|
636
|
+
char = unsafeCharCodeAt(data, i);
|
|
637
|
+
if (char !== rightBracketCode) {
|
|
638
|
+
result.push(parseNumber<valueof<T>>(data.slice(lastPos, i + 1)));
|
|
639
|
+
break;
|
|
617
640
|
}
|
|
618
|
-
|
|
641
|
+
}
|
|
642
|
+
return result;
|
|
619
643
|
}
|
|
620
644
|
|
|
621
645
|
// @ts-ignore
|
|
622
|
-
@inline function parseArrayArray<
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
+
@inline function parseArrayArray<
|
|
647
|
+
T extends unknown[][]
|
|
648
|
+
>(data: string): T {
|
|
649
|
+
const result = instantiate<T>();
|
|
650
|
+
let char = 0;
|
|
651
|
+
let lastPos = 0;
|
|
652
|
+
let depth = 0;
|
|
653
|
+
let i = 1;
|
|
654
|
+
// Find start of bracket
|
|
655
|
+
//for (; unsafeCharCodeAt(data, i) !== leftBracketCode; i++) {}
|
|
656
|
+
//i++;
|
|
657
|
+
for (; i < data.length - 1; i++) {
|
|
658
|
+
char = unsafeCharCodeAt(data, i);
|
|
659
|
+
if (char === leftBracketCode) {
|
|
660
|
+
if (depth === 0) {
|
|
661
|
+
lastPos = i;
|
|
662
|
+
}
|
|
663
|
+
// Shifting is 6% faster than incrementing
|
|
664
|
+
depth++;
|
|
665
|
+
} else if (char === rightBracketCode) {
|
|
666
|
+
depth--;
|
|
667
|
+
if (depth === 0) {
|
|
668
|
+
i++;
|
|
669
|
+
result.push(JSON.parse<valueof<T>>(data.slice(lastPos, i)));
|
|
670
|
+
}
|
|
646
671
|
}
|
|
647
|
-
|
|
672
|
+
}
|
|
673
|
+
return result;
|
|
648
674
|
}
|
|
649
675
|
|
|
650
676
|
// @ts-ignore
|
|
651
|
-
@inline export function parseObjectArray<
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
677
|
+
@inline export function parseObjectArray<
|
|
678
|
+
T extends unknown[]
|
|
679
|
+
>(data: string): T {
|
|
680
|
+
const result = instantiate<T>();
|
|
681
|
+
let char = 0;
|
|
682
|
+
let lastPos: u32 = 1;
|
|
683
|
+
let depth: u32 = 0;
|
|
684
|
+
for (let pos: u32 = 0; pos < <u32>data.length; pos++) {
|
|
685
|
+
char = unsafeCharCodeAt(data, pos);
|
|
686
|
+
if (char === leftBraceCode) {
|
|
687
|
+
if (depth === 0) {
|
|
688
|
+
lastPos = pos;
|
|
689
|
+
}
|
|
690
|
+
depth++;
|
|
691
|
+
} else if (char === rightBraceCode) {
|
|
692
|
+
depth--;
|
|
693
|
+
if (depth === 0) {
|
|
694
|
+
pos++;
|
|
695
|
+
result.push(JSON.parse<valueof<T>>(data.slice(lastPos, pos)));
|
|
696
|
+
//lastPos = pos + 2;
|
|
697
|
+
}
|
|
671
698
|
}
|
|
672
|
-
|
|
699
|
+
}
|
|
700
|
+
return result;
|
|
673
701
|
}
|