json-as 0.5.6 → 0.5.7
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/__tests__/as-json.spec.ts +4 -4
- package/assembly/src/json.ts +25 -18
- package/assembly/test.ts +3 -3
- package/package.json +4 -3
- package/transform/lib/index.js +46 -37
- package/transform/package.json +2 -2
- package/transform/src/index.ts +51 -42
- package/assembly/json.ts +0 -451
|
@@ -40,7 +40,7 @@ describe("Ser/de Numbers", () => {
|
|
|
40
40
|
canSerde<u64>(101);
|
|
41
41
|
canSerde<i32>(-100);
|
|
42
42
|
canSerde<i64>(-101);
|
|
43
|
-
|
|
43
|
+
/*
|
|
44
44
|
canSerde<u128>(u128.from("0"))
|
|
45
45
|
canSerde<u128>(u128.from("100"))
|
|
46
46
|
canSerde<u128>(u128.from("101"))
|
|
@@ -49,7 +49,7 @@ describe("Ser/de Numbers", () => {
|
|
|
49
49
|
canSerde<u128Safe>(u128Safe.from("100"))
|
|
50
50
|
canSerde<u128Safe>(u128Safe.from("101"))
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
canSerde<u256>(u256.fromU128(u128.from("0")))
|
|
53
53
|
canSerde<u256>(u256.fromU128(u128.from("100")))
|
|
54
54
|
canSerde<u256>(u256.fromU128(u128.from("101")))
|
|
55
55
|
|
|
@@ -65,9 +65,9 @@ describe("Ser/de Numbers", () => {
|
|
|
65
65
|
canSerde<i128Safe>(i128Safe.from("100"))
|
|
66
66
|
canSerde<i128Safe>(i128Safe.from("101"))
|
|
67
67
|
canSerde<i128Safe>(i128Safe.from("-100"))
|
|
68
|
-
canSerde<i128Safe>(i128Safe.from("-101"))
|
|
68
|
+
canSerde<i128Safe>(i128Safe.from("-101"))*/
|
|
69
69
|
|
|
70
|
-
canSerde<i256Safe>(new i256Safe(10, 11, 500, 501))
|
|
70
|
+
//canSerde<i256Safe>(new i256Safe(10, 11, 500, 501))
|
|
71
71
|
});
|
|
72
72
|
|
|
73
73
|
it("should ser/de floats", () => {
|
package/assembly/src/json.ts
CHANGED
|
@@ -165,8 +165,8 @@ export namespace JSON {
|
|
|
165
165
|
|
|
166
166
|
// @ts-ignore
|
|
167
167
|
@inline
|
|
168
|
-
|
|
169
|
-
|
|
168
|
+
// @ts-ignore
|
|
169
|
+
function parseBigNum<T>(data: string): T {
|
|
170
170
|
// @ts-ignore
|
|
171
171
|
if (idof<T>() == idof<u128>()) return u128.fromString(data);
|
|
172
172
|
// @ts-ignore
|
|
@@ -180,18 +180,18 @@ export namespace JSON {
|
|
|
180
180
|
// @ts-ignore
|
|
181
181
|
if (idof<T>() == idof<i128Safe>()) return i128Safe.fromString(data);
|
|
182
182
|
// @ts-ignore
|
|
183
|
-
if (idof<T>() == idof<i256Safe>()) return
|
|
183
|
+
//if (idof<T>() == idof<i256Safe>()) return data.
|
|
184
184
|
}
|
|
185
185
|
|
|
186
186
|
// @ts-ignore
|
|
187
187
|
@inline
|
|
188
|
-
|
|
188
|
+
function parseString(data: string): string {
|
|
189
189
|
return data.slice(1, data.length - 1).replaceAll('\\"', '"');
|
|
190
190
|
}
|
|
191
191
|
|
|
192
192
|
// @ts-ignore
|
|
193
193
|
@inline
|
|
194
|
-
|
|
194
|
+
function parseBoolean<T extends boolean>(data: string): T {
|
|
195
195
|
if (data.length > 3 && data.startsWith("true")) return <T>true;
|
|
196
196
|
else if (data.length > 4 && data.startsWith("false")) return <T>false;
|
|
197
197
|
else throw new Error(`JSON: Cannot parse "${data}" as boolean`);
|
|
@@ -199,7 +199,7 @@ export namespace JSON {
|
|
|
199
199
|
|
|
200
200
|
// @ts-ignore
|
|
201
201
|
@inline
|
|
202
|
-
|
|
202
|
+
function parseNumber<T>(data: string): T {
|
|
203
203
|
let type: T;
|
|
204
204
|
// @ts-ignore
|
|
205
205
|
if (type instanceof f64) return F64.parseFloat(data);
|
|
@@ -221,15 +221,15 @@ export namespace JSON {
|
|
|
221
221
|
else if (type instanceof i16) return I16.parseInt(data);
|
|
222
222
|
// @ts-ignore
|
|
223
223
|
else if (type instanceof i8) return I8.parseInt(data);
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
224
|
+
|
|
225
|
+
throw new Error(
|
|
226
|
+
`JSON: Cannot parse invalid data into a number. Either "${data}" is not a valid number, or <${nameof<T>()}> is an invald number type.`
|
|
227
|
+
);
|
|
228
228
|
}
|
|
229
229
|
|
|
230
230
|
// @ts-ignore
|
|
231
231
|
@inline
|
|
232
|
-
|
|
232
|
+
export function parseObject<T>(data: string): T {
|
|
233
233
|
let schema: nonnull<T> = changetype<nonnull<T>>(__new(offsetof<nonnull<T>>(), idof<nonnull<T>>()));
|
|
234
234
|
let key = "";
|
|
235
235
|
let isKey = false;
|
|
@@ -251,6 +251,7 @@ export namespace JSON {
|
|
|
251
251
|
depth = depth >> 1;
|
|
252
252
|
if (depth === 1) {
|
|
253
253
|
++arrayValueIndex;
|
|
254
|
+
// @ts-ignore
|
|
254
255
|
schema.__JSON_Set_Key(key, data.slice(outerLoopIndex, arrayValueIndex));
|
|
255
256
|
outerLoopIndex = arrayValueIndex;
|
|
256
257
|
isKey = false;
|
|
@@ -271,6 +272,7 @@ export namespace JSON {
|
|
|
271
272
|
depth = depth >> 1;
|
|
272
273
|
if (depth === 1) {
|
|
273
274
|
++objectValueIndex;
|
|
275
|
+
// @ts-ignore
|
|
274
276
|
schema.__JSON_Set_Key(key, data.slice(outerLoopIndex, objectValueIndex));
|
|
275
277
|
outerLoopIndex = objectValueIndex;
|
|
276
278
|
isKey = false;
|
|
@@ -293,6 +295,7 @@ export namespace JSON {
|
|
|
293
295
|
key = data.slice(outerLoopIndex, stringValueIndex);
|
|
294
296
|
isKey = true;
|
|
295
297
|
} else {
|
|
298
|
+
// @ts-ignore
|
|
296
299
|
schema.__JSON_Set_Key(key, data.slice(outerLoopIndex, stringValueIndex));
|
|
297
300
|
isKey = false;
|
|
298
301
|
}
|
|
@@ -301,6 +304,7 @@ export namespace JSON {
|
|
|
301
304
|
}
|
|
302
305
|
}
|
|
303
306
|
} else if (char == nCode) {
|
|
307
|
+
// @ts-ignore
|
|
304
308
|
schema.__JSON_Set_Key(key, nullWord);
|
|
305
309
|
isKey = false;
|
|
306
310
|
} else if (
|
|
@@ -309,6 +313,7 @@ export namespace JSON {
|
|
|
309
313
|
unsafeCharCodeAt(data, ++outerLoopIndex) === uCode &&
|
|
310
314
|
unsafeCharCodeAt(data, ++outerLoopIndex) === eCode
|
|
311
315
|
) {
|
|
316
|
+
// @ts-ignore
|
|
312
317
|
schema.__JSON_Set_Key(key, trueWord);
|
|
313
318
|
isKey = false;
|
|
314
319
|
} else if (
|
|
@@ -318,6 +323,7 @@ export namespace JSON {
|
|
|
318
323
|
unsafeCharCodeAt(data, ++outerLoopIndex) === "s".charCodeAt(0) &&
|
|
319
324
|
unsafeCharCodeAt(data, ++outerLoopIndex) === eCode
|
|
320
325
|
) {
|
|
326
|
+
// @ts-ignore
|
|
321
327
|
schema.__JSON_Set_Key(key, "false");
|
|
322
328
|
isKey = false;
|
|
323
329
|
} else if ((char >= 48 && char <= 57) || char === 45) {
|
|
@@ -325,6 +331,7 @@ export namespace JSON {
|
|
|
325
331
|
for (; numberValueIndex < data.length; numberValueIndex++) {
|
|
326
332
|
char = unsafeCharCodeAt(data, numberValueIndex);
|
|
327
333
|
if (char === commaCode || char === rightBraceCode || isSpace(char)) {
|
|
334
|
+
// @ts-ignore
|
|
328
335
|
schema.__JSON_Set_Key(key, data.slice(outerLoopIndex - 1, numberValueIndex));
|
|
329
336
|
outerLoopIndex = numberValueIndex;
|
|
330
337
|
isKey = false;
|
|
@@ -338,8 +345,8 @@ export namespace JSON {
|
|
|
338
345
|
|
|
339
346
|
// @ts-ignore
|
|
340
347
|
@inline
|
|
341
|
-
|
|
342
|
-
|
|
348
|
+
// @ts-ignore
|
|
349
|
+
export function parseArray<T extends unknown[]>(data: string): T {
|
|
343
350
|
let type!: valueof<T>;
|
|
344
351
|
if (type instanceof String) {
|
|
345
352
|
return <T>parseStringArray(data);
|
|
@@ -361,7 +368,7 @@ export namespace JSON {
|
|
|
361
368
|
|
|
362
369
|
// @ts-ignore
|
|
363
370
|
@inline
|
|
364
|
-
|
|
371
|
+
export function parseStringArray(data: string): string[] {
|
|
365
372
|
const result: string[] = [];
|
|
366
373
|
let lastPos = 0;
|
|
367
374
|
let instr = false;
|
|
@@ -381,7 +388,7 @@ export namespace JSON {
|
|
|
381
388
|
|
|
382
389
|
// @ts-ignore
|
|
383
390
|
@inline
|
|
384
|
-
|
|
391
|
+
export function parseBooleanArray<T extends boolean[]>(data: string): T {
|
|
385
392
|
const result = instantiate<T>();
|
|
386
393
|
let lastPos = 1;
|
|
387
394
|
let char = 0;
|
|
@@ -409,7 +416,7 @@ export namespace JSON {
|
|
|
409
416
|
|
|
410
417
|
// @ts-ignore
|
|
411
418
|
@inline
|
|
412
|
-
|
|
419
|
+
export function parseNumberArray<T extends number[]>(data: string): T {
|
|
413
420
|
const result = instantiate<T>();
|
|
414
421
|
let lastPos = 0;
|
|
415
422
|
let char = 0;
|
|
@@ -435,7 +442,7 @@ export namespace JSON {
|
|
|
435
442
|
|
|
436
443
|
// @ts-ignore
|
|
437
444
|
@inline
|
|
438
|
-
|
|
445
|
+
export function parseArrayArray<T extends unknown[][]>(data: string): T {
|
|
439
446
|
const result = instantiate<T>();
|
|
440
447
|
let char = 0;
|
|
441
448
|
let lastPos = 0;
|
|
@@ -465,7 +472,7 @@ export namespace JSON {
|
|
|
465
472
|
|
|
466
473
|
// @ts-ignore
|
|
467
474
|
@inline
|
|
468
|
-
|
|
475
|
+
export function parseObjectArray<T extends unknown[][]>(data: string): T {
|
|
469
476
|
const result = instantiate<T>();
|
|
470
477
|
let char = 0;
|
|
471
478
|
let lastPos = 1;
|
package/assembly/test.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "wasi"
|
|
1
|
+
import { wasi_console } from "@assemblyscript/wasi-shim/assembly/wasi_console"
|
|
2
2
|
import { u128 } from "as-bignum/assembly";
|
|
3
3
|
import {
|
|
4
4
|
JSON
|
|
@@ -48,6 +48,6 @@ const player: Player = {
|
|
|
48
48
|
};
|
|
49
49
|
|
|
50
50
|
const serializedPlayer = JSON.stringify<Player>(player);
|
|
51
|
-
|
|
51
|
+
wasi_console.log("Serialized Player: " + serializedPlayer);
|
|
52
52
|
const deserializedPlayer = JSON.parse<Player>(serializedPlayer);
|
|
53
|
-
|
|
53
|
+
wasi_console.log("Deserialized Player: " + JSON.stringify(deserializedPlayer));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "json-as",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.7",
|
|
4
4
|
"description": "JSON encoder/decoder for AssemblyScript",
|
|
5
5
|
"types": "assembly/index.ts",
|
|
6
6
|
"author": "Jairus Tanaka",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"scripts": {
|
|
12
12
|
"aspect": "asp",
|
|
13
13
|
"bench:astral": "astral",
|
|
14
|
-
"build:test": "asc assembly/test.ts --
|
|
14
|
+
"build:test": "asc assembly/test.ts --config ./node_modules/@assemblyscript/wasi-shim/asconfig.json --transform \"./transform\" --exportStart _start -o ./build/test.wasm",
|
|
15
15
|
"build:transform": "tsc -p ./transform",
|
|
16
16
|
"test:wasmtime": "wasmtime ./build/test.wasm",
|
|
17
17
|
"test:lunatic": "lunatic ./build/test.wasm",
|
|
@@ -22,8 +22,9 @@
|
|
|
22
22
|
"@as-pect/cli": "^7.0.7",
|
|
23
23
|
"@as-tral/cli": "^1.1.1",
|
|
24
24
|
"@assemblyscript/loader": "^0.21.3",
|
|
25
|
+
"@assemblyscript/wasi-shim": "^0.1.0",
|
|
25
26
|
"@serial-as/json": "^2.0.0",
|
|
26
|
-
"assemblyscript": "^0.
|
|
27
|
+
"assemblyscript": "^0.24.1",
|
|
27
28
|
"assemblyscript-prettier": "^1.0.2",
|
|
28
29
|
"prettier": "^2.7.1",
|
|
29
30
|
"typescript": "^4.7.2"
|
package/transform/lib/index.js
CHANGED
|
@@ -1,15 +1,23 @@
|
|
|
1
1
|
import { ClassDecorator, registerDecorator, } from "visitor-as/dist/decorator.js";
|
|
2
2
|
import { getName, toString } from "visitor-as/dist/utils.js";
|
|
3
3
|
import { SimpleParser } from "visitor-as/dist/index.js";
|
|
4
|
+
class SchemaData {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.keys = [];
|
|
7
|
+
this.values = [];
|
|
8
|
+
this.types = [];
|
|
9
|
+
this.name = "";
|
|
10
|
+
this.parent = "";
|
|
11
|
+
this.encodeStmts = [];
|
|
12
|
+
this.setDataStmts = [];
|
|
13
|
+
}
|
|
14
|
+
}
|
|
4
15
|
class AsJSONTransform extends ClassDecorator {
|
|
5
16
|
constructor() {
|
|
6
17
|
super(...arguments);
|
|
18
|
+
this.schemasList = [];
|
|
7
19
|
this.sources = [];
|
|
8
|
-
this.encodeStmts = [];
|
|
9
|
-
//public decodeStmts: string[] = [];
|
|
10
|
-
this.setDataStmts = [];
|
|
11
20
|
}
|
|
12
|
-
//public checkDecodeStmts: string[] = [];
|
|
13
21
|
visitMethodDeclaration() { }
|
|
14
22
|
visitFieldDeclaration(node) {
|
|
15
23
|
const lineText = toString(node);
|
|
@@ -21,13 +29,13 @@ class AsJSONTransform extends ClassDecorator {
|
|
|
21
29
|
}
|
|
22
30
|
let type = getName(node.type);
|
|
23
31
|
// @ts-ignore
|
|
24
|
-
this.encodeStmts.push(`"${name}":\${JSON.stringify<${type}>(this.${name})},`);
|
|
32
|
+
this.currentClass.encodeStmts.push(`"${name}":\${JSON.stringify<${type}>(this.${name})},`);
|
|
25
33
|
// @ts-ignore
|
|
26
34
|
//this.decodeStmts.push(
|
|
27
35
|
// `${name}: JSON.parseObjectValue<${type}>(values.get("${name}")),\n`
|
|
28
36
|
//);
|
|
29
37
|
// @ts-ignore
|
|
30
|
-
this.setDataStmts.push(`if (key.length === ${name.length} && (memory.compare(changetype<usize>("${name}"), changetype<usize>(key), ${name.length}) == 0)) {
|
|
38
|
+
this.currentClass.setDataStmts.push(`if (key.length === ${name.length} && (memory.compare(changetype<usize>("${name}"), changetype<usize>(key), ${name.length}) == 0)) {
|
|
31
39
|
this.${name} = JSON.parseObjectValue<${type}>(value);
|
|
32
40
|
return;
|
|
33
41
|
}
|
|
@@ -38,19 +46,43 @@ class AsJSONTransform extends ClassDecorator {
|
|
|
38
46
|
//);
|
|
39
47
|
}
|
|
40
48
|
visitClassDeclaration(node) {
|
|
49
|
+
var _a, _b, _c;
|
|
41
50
|
if (!node.members) {
|
|
42
51
|
return;
|
|
43
52
|
}
|
|
44
|
-
this.currentClass =
|
|
53
|
+
this.currentClass = {
|
|
54
|
+
name: toString(node.name),
|
|
55
|
+
keys: [],
|
|
56
|
+
values: [],
|
|
57
|
+
types: [],
|
|
58
|
+
parent: node.extendsType ? toString(node.extendsType) : "",
|
|
59
|
+
node: node,
|
|
60
|
+
encodeStmts: [],
|
|
61
|
+
setDataStmts: []
|
|
62
|
+
};
|
|
63
|
+
if (this.currentClass.parent.length > 0) {
|
|
64
|
+
const parentSchema = this.schemasList.map((v) => {
|
|
65
|
+
if (v.name == this.currentClass.parent) {
|
|
66
|
+
return v;
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
if (parentSchema.length > 0) {
|
|
70
|
+
(_a = parentSchema[0]) === null || _a === void 0 ? void 0 : _a.encodeStmts.push(((_b = parentSchema[0]) === null || _b === void 0 ? void 0 : _b.encodeStmts.pop()) + ",");
|
|
71
|
+
this.currentClass.encodeStmts.push(...(_c = parentSchema[0]) === null || _c === void 0 ? void 0 : _c.encodeStmts);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
//console.log("Class extends " + this.currentClass.parent + ", but parent class not found. Maybe add the @json decorator over parent class?")
|
|
75
|
+
}
|
|
76
|
+
}
|
|
45
77
|
this.visit(node.members);
|
|
46
78
|
const serializedProp = '__JSON_Serialized: string = "";';
|
|
47
79
|
let serializeFunc = "";
|
|
48
|
-
if (this.encodeStmts.length > 0) {
|
|
49
|
-
const stmt = this.encodeStmts[this.encodeStmts.length - 1];
|
|
50
|
-
this.encodeStmts[this.encodeStmts.length - 1] = stmt.slice(0, stmt.length - 1);
|
|
80
|
+
if (this.currentClass.encodeStmts.length > 0) {
|
|
81
|
+
const stmt = this.currentClass.encodeStmts[this.currentClass.encodeStmts.length - 1];
|
|
82
|
+
this.currentClass.encodeStmts[this.currentClass.encodeStmts.length - 1] = stmt.slice(0, stmt.length - 1);
|
|
51
83
|
serializeFunc = `
|
|
52
84
|
__JSON_Serialize(): string {
|
|
53
|
-
return \`{${this.encodeStmts.join("")}}\`;
|
|
85
|
+
return \`{${this.currentClass.encodeStmts.join("")}}\`;
|
|
54
86
|
}
|
|
55
87
|
`;
|
|
56
88
|
}
|
|
@@ -61,44 +93,21 @@ class AsJSONTransform extends ClassDecorator {
|
|
|
61
93
|
}
|
|
62
94
|
`;
|
|
63
95
|
}
|
|
64
|
-
/*const deserializeFunc = `
|
|
65
|
-
__JSON_Deserialize<T>(values: Map<string, string>): T {
|
|
66
|
-
${
|
|
67
|
-
process.argv.includes("--debugJSON")
|
|
68
|
-
? this.checkDecodeStmts.join("else")
|
|
69
|
-
: ""
|
|
70
|
-
}
|
|
71
|
-
return {
|
|
72
|
-
${
|
|
73
|
-
// @ts-ignore
|
|
74
|
-
this.decodeStmts.join("")
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
`;*/
|
|
79
96
|
const setKeyFunc = `
|
|
80
97
|
__JSON_Set_Key(key: string, value: string): void {
|
|
81
98
|
${
|
|
82
99
|
// @ts-ignore
|
|
83
|
-
this.setDataStmts.join("")}
|
|
100
|
+
this.currentClass.setDataStmts.join("")}
|
|
84
101
|
}
|
|
85
102
|
`;
|
|
86
|
-
//console.log(
|
|
87
|
-
this.encodeStmts = [];
|
|
88
|
-
//this.decodeStmts = [];
|
|
89
|
-
this.setDataStmts = [];
|
|
90
|
-
//this.checkDecodeStmts = [];
|
|
103
|
+
//console.log(serializeFunc)
|
|
91
104
|
const serializedProperty = SimpleParser.parseClassMember(serializedProp, node);
|
|
92
105
|
node.members.push(serializedProperty);
|
|
93
106
|
const serializeMethod = SimpleParser.parseClassMember(serializeFunc, node);
|
|
94
107
|
node.members.push(serializeMethod);
|
|
95
|
-
//const deserializeMethod = SimpleParser.parseClassMember(
|
|
96
|
-
// deserializeFunc,
|
|
97
|
-
// node
|
|
98
|
-
//);
|
|
99
|
-
//node.members.push(deserializeMethod);
|
|
100
108
|
const setDataMethod = SimpleParser.parseClassMember(setKeyFunc, node);
|
|
101
109
|
node.members.push(setDataMethod);
|
|
110
|
+
this.schemasList.push(this.currentClass);
|
|
102
111
|
}
|
|
103
112
|
get name() {
|
|
104
113
|
return "json";
|
package/transform/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@json-as/transform",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.7",
|
|
4
4
|
"description": "JSON encoder/decoder for AssemblyScript",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"author": "Jairus Tanaka",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"devDependencies": {},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"visitor-as": "^0.
|
|
13
|
+
"visitor-as": "^0.11.3"
|
|
14
14
|
},
|
|
15
15
|
"repository": {
|
|
16
16
|
"type": "git",
|
package/transform/src/index.ts
CHANGED
|
@@ -10,15 +10,22 @@ import {
|
|
|
10
10
|
import { getName, toString } from "visitor-as/dist/utils.js";
|
|
11
11
|
import { SimpleParser } from "visitor-as/dist/index.js";
|
|
12
12
|
|
|
13
|
-
class
|
|
14
|
-
public
|
|
15
|
-
public
|
|
13
|
+
class SchemaData {
|
|
14
|
+
public keys: string[] = [];
|
|
15
|
+
public values: string[] = [];
|
|
16
|
+
public types: string[] = [];
|
|
17
|
+
public name: string = "";
|
|
18
|
+
public parent: string = "";
|
|
19
|
+
public node!: ClassDeclaration;
|
|
16
20
|
public encodeStmts: string[] = [];
|
|
17
|
-
//public decodeStmts: string[] = [];
|
|
18
21
|
public setDataStmts: string[] = [];
|
|
19
|
-
|
|
22
|
+
}
|
|
23
|
+
class AsJSONTransform extends ClassDecorator {
|
|
24
|
+
public schemasList: SchemaData[] = [];
|
|
25
|
+
public currentClass!: SchemaData;
|
|
26
|
+
public sources: Source[] = [];
|
|
20
27
|
|
|
21
|
-
visitMethodDeclaration(): void {}
|
|
28
|
+
visitMethodDeclaration(): void { }
|
|
22
29
|
visitFieldDeclaration(node: FieldDeclaration): void {
|
|
23
30
|
const lineText = toString(node);
|
|
24
31
|
if (lineText.startsWith("private")) return;
|
|
@@ -29,17 +36,17 @@ class AsJSONTransform extends ClassDecorator {
|
|
|
29
36
|
|
|
30
37
|
let type = getName(node.type);
|
|
31
38
|
// @ts-ignore
|
|
32
|
-
this.encodeStmts.push(
|
|
39
|
+
this.currentClass.encodeStmts.push(
|
|
33
40
|
`"${name}":\${JSON.stringify<${type}>(this.${name})},`
|
|
34
41
|
);
|
|
35
42
|
|
|
36
43
|
// @ts-ignore
|
|
37
44
|
//this.decodeStmts.push(
|
|
38
|
-
|
|
45
|
+
// `${name}: JSON.parseObjectValue<${type}>(values.get("${name}")),\n`
|
|
39
46
|
//);
|
|
40
47
|
|
|
41
48
|
// @ts-ignore
|
|
42
|
-
this.setDataStmts.push(
|
|
49
|
+
this.currentClass.setDataStmts.push(
|
|
43
50
|
`if (key.length === ${name.length} && (memory.compare(changetype<usize>("${name}"), changetype<usize>(key), ${name.length}) == 0)) {
|
|
44
51
|
this.${name} = JSON.parseObjectValue<${type}>(value);
|
|
45
52
|
return;
|
|
@@ -57,7 +64,30 @@ class AsJSONTransform extends ClassDecorator {
|
|
|
57
64
|
return;
|
|
58
65
|
}
|
|
59
66
|
|
|
60
|
-
this.currentClass =
|
|
67
|
+
this.currentClass = {
|
|
68
|
+
name: toString(node.name),
|
|
69
|
+
keys: [],
|
|
70
|
+
values: [],
|
|
71
|
+
types: [],
|
|
72
|
+
parent: node.extendsType ? toString(node.extendsType) : "",
|
|
73
|
+
node: node,
|
|
74
|
+
encodeStmts: [],
|
|
75
|
+
setDataStmts: []
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (this.currentClass.parent.length > 0) {
|
|
79
|
+
const parentSchema = this.schemasList.map((v) => {
|
|
80
|
+
if (v.name == this.currentClass.parent) {
|
|
81
|
+
return v;
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
if (parentSchema.length > 0) {
|
|
85
|
+
parentSchema[0]?.encodeStmts.push(parentSchema[0]?.encodeStmts.pop() + ",")
|
|
86
|
+
this.currentClass.encodeStmts.push(...parentSchema[0]?.encodeStmts)
|
|
87
|
+
} else {
|
|
88
|
+
//console.log("Class extends " + this.currentClass.parent + ", but parent class not found. Maybe add the @json decorator over parent class?")
|
|
89
|
+
}
|
|
90
|
+
}
|
|
61
91
|
|
|
62
92
|
this.visit(node.members);
|
|
63
93
|
|
|
@@ -65,15 +95,15 @@ class AsJSONTransform extends ClassDecorator {
|
|
|
65
95
|
|
|
66
96
|
let serializeFunc = "";
|
|
67
97
|
|
|
68
|
-
if (this.encodeStmts.length > 0) {
|
|
69
|
-
const stmt = this.encodeStmts[this.encodeStmts.length - 1]!;
|
|
70
|
-
this.encodeStmts[this.encodeStmts.length - 1] = stmt!.slice(
|
|
98
|
+
if (this.currentClass.encodeStmts.length > 0) {
|
|
99
|
+
const stmt = this.currentClass.encodeStmts[this.currentClass.encodeStmts.length - 1]!;
|
|
100
|
+
this.currentClass.encodeStmts[this.currentClass.encodeStmts.length - 1] = stmt!.slice(
|
|
71
101
|
0,
|
|
72
102
|
stmt.length - 1
|
|
73
103
|
);
|
|
74
104
|
serializeFunc = `
|
|
75
105
|
__JSON_Serialize(): string {
|
|
76
|
-
return \`{${this.encodeStmts.join("")}}\`;
|
|
106
|
+
return \`{${this.currentClass.encodeStmts.join("")}}\`;
|
|
77
107
|
}
|
|
78
108
|
`;
|
|
79
109
|
} else {
|
|
@@ -83,34 +113,16 @@ class AsJSONTransform extends ClassDecorator {
|
|
|
83
113
|
}
|
|
84
114
|
`;
|
|
85
115
|
}
|
|
86
|
-
|
|
87
|
-
__JSON_Deserialize<T>(values: Map<string, string>): T {
|
|
88
|
-
${
|
|
89
|
-
process.argv.includes("--debugJSON")
|
|
90
|
-
? this.checkDecodeStmts.join("else")
|
|
91
|
-
: ""
|
|
92
|
-
}
|
|
93
|
-
return {
|
|
94
|
-
${
|
|
95
|
-
// @ts-ignore
|
|
96
|
-
this.decodeStmts.join("")
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
`;*/
|
|
116
|
+
|
|
101
117
|
const setKeyFunc = `
|
|
102
118
|
__JSON_Set_Key(key: string, value: string): void {
|
|
103
119
|
${
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
120
|
+
// @ts-ignore
|
|
121
|
+
this.currentClass.setDataStmts.join("")
|
|
122
|
+
}
|
|
107
123
|
}
|
|
108
124
|
`
|
|
109
|
-
//console.log(
|
|
110
|
-
this.encodeStmts = [];
|
|
111
|
-
//this.decodeStmts = [];
|
|
112
|
-
this.setDataStmts = [];
|
|
113
|
-
//this.checkDecodeStmts = [];
|
|
125
|
+
//console.log(serializeFunc)
|
|
114
126
|
const serializedProperty = SimpleParser.parseClassMember(
|
|
115
127
|
serializedProp,
|
|
116
128
|
node
|
|
@@ -120,16 +132,13 @@ class AsJSONTransform extends ClassDecorator {
|
|
|
120
132
|
const serializeMethod = SimpleParser.parseClassMember(serializeFunc, node);
|
|
121
133
|
node.members.push(serializeMethod);
|
|
122
134
|
|
|
123
|
-
//const deserializeMethod = SimpleParser.parseClassMember(
|
|
124
|
-
// deserializeFunc,
|
|
125
|
-
// node
|
|
126
|
-
//);
|
|
127
|
-
//node.members.push(deserializeMethod);
|
|
128
135
|
const setDataMethod = SimpleParser.parseClassMember(
|
|
129
136
|
setKeyFunc,
|
|
130
137
|
node
|
|
131
138
|
);
|
|
132
139
|
node.members.push(setDataMethod);
|
|
140
|
+
|
|
141
|
+
this.schemasList.push(this.currentClass);
|
|
133
142
|
}
|
|
134
143
|
get name(): string {
|
|
135
144
|
return "json";
|
package/assembly/json.ts
DELETED
|
@@ -1,451 +0,0 @@
|
|
|
1
|
-
import { StringSink } from "as-string-sink/assembly";
|
|
2
|
-
import { isSpace } from "util/string";
|
|
3
|
-
import {
|
|
4
|
-
backSlashCode,
|
|
5
|
-
commaCode,
|
|
6
|
-
eCode,
|
|
7
|
-
fCode,
|
|
8
|
-
leftBraceCode,
|
|
9
|
-
leftBracketCode,
|
|
10
|
-
nCode,
|
|
11
|
-
quoteCode,
|
|
12
|
-
rightBraceCode,
|
|
13
|
-
rightBracketCode,
|
|
14
|
-
tCode,
|
|
15
|
-
} from "./chars";
|
|
16
|
-
import { unsafeCharCodeAt } from "./util";
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* JSON Encoder/Decoder for AssemblyScript
|
|
20
|
-
*/
|
|
21
|
-
export class JSON {
|
|
22
|
-
/**
|
|
23
|
-
* Stringifies valid JSON data.
|
|
24
|
-
* ```js
|
|
25
|
-
* JSON.stringify<T>(data)
|
|
26
|
-
* ```
|
|
27
|
-
* @param data T
|
|
28
|
-
* @returns string
|
|
29
|
-
*/
|
|
30
|
-
static stringify<T>(data: T): string {
|
|
31
|
-
// String
|
|
32
|
-
if (isString<T>()) {
|
|
33
|
-
return '"' + (<string>data).replaceAll('"', '\\"') + '"';
|
|
34
|
-
}
|
|
35
|
-
// Boolean
|
|
36
|
-
else if (isBoolean<T>()) {
|
|
37
|
-
return data ? "true" : "false";
|
|
38
|
-
}
|
|
39
|
-
// Nullable
|
|
40
|
-
else if (isNullable<T>() && data == null) {
|
|
41
|
-
return "null";
|
|
42
|
-
}
|
|
43
|
-
// Integers/Floats
|
|
44
|
-
// @ts-ignore
|
|
45
|
-
else if ((isInteger<T>() || isFloat<T>()) && isFinite(data)) {
|
|
46
|
-
// @ts-ignore
|
|
47
|
-
return data.toString();
|
|
48
|
-
}
|
|
49
|
-
// Class-Based serialization
|
|
50
|
-
// @ts-ignore
|
|
51
|
-
else if (isDefined(data.__JSON_Serialize)) {
|
|
52
|
-
// @ts-ignore
|
|
53
|
-
//if (isNullable<T>()) return "null";
|
|
54
|
-
// @ts-ignore
|
|
55
|
-
return data.__JSON_Serialize();
|
|
56
|
-
}
|
|
57
|
-
// ArrayLike
|
|
58
|
-
else if (isArrayLike<T>()) {
|
|
59
|
-
let result = new StringSink("[");
|
|
60
|
-
// @ts-ignore
|
|
61
|
-
if (data.length == 0) return "[]";
|
|
62
|
-
// @ts-ignore
|
|
63
|
-
for (let i = 0; i < data.length - 1; i++) {
|
|
64
|
-
// @ts-ignore
|
|
65
|
-
result.write(JSON.stringify(unchecked(data[i])) + ",");
|
|
66
|
-
}
|
|
67
|
-
// @ts-ignore
|
|
68
|
-
result.write(JSON.stringify(unchecked(data[data.length - 1])));
|
|
69
|
-
result.write("]");
|
|
70
|
-
return result.toString();
|
|
71
|
-
} else {
|
|
72
|
-
return "null";
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Parses valid JSON strings into their original format.
|
|
77
|
-
* ```js
|
|
78
|
-
* JSON.parse<T>(data)
|
|
79
|
-
* ```
|
|
80
|
-
* @param data string
|
|
81
|
-
* @returns T
|
|
82
|
-
*/
|
|
83
|
-
static parse<T>(data: string): T {
|
|
84
|
-
let type!: T;
|
|
85
|
-
if (isString<T>()) {
|
|
86
|
-
// @ts-ignore
|
|
87
|
-
return parseString(data);
|
|
88
|
-
} else if (isBoolean<T>()) {
|
|
89
|
-
// @ts-ignore
|
|
90
|
-
return parseBoolean<T>(data);
|
|
91
|
-
} else if (isFloat<T>() || isInteger<T>()) {
|
|
92
|
-
return parseNumber<T>(data);
|
|
93
|
-
} else if (isArrayLike<T>()) {
|
|
94
|
-
// @ts-ignore
|
|
95
|
-
return parseArray<T>(data.trimStart());
|
|
96
|
-
// @ts-ignore
|
|
97
|
-
} else if (isNullable<T>() && data == "null") {
|
|
98
|
-
// @ts-ignore
|
|
99
|
-
return null;
|
|
100
|
-
// @ts-ignore
|
|
101
|
-
} else if (isDefined(type.__JSON_Deserialize)) {
|
|
102
|
-
return parseObject<T>(data.trimStart());
|
|
103
|
-
} else {
|
|
104
|
-
// @ts-ignore
|
|
105
|
-
return null;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
private static parseObjectValue<T>(data: string): T {
|
|
109
|
-
let type!: T;
|
|
110
|
-
if (isString<T>()) {
|
|
111
|
-
// @ts-ignore
|
|
112
|
-
return data.replaceAll('\\"', '"');
|
|
113
|
-
} else if (isBoolean<T>()) {
|
|
114
|
-
// @ts-ignore
|
|
115
|
-
return parseBoolean<T>(data);
|
|
116
|
-
} else if (isFloat<T>() || isInteger<T>()) {
|
|
117
|
-
return parseNumber<T>(data);
|
|
118
|
-
} else if (isArrayLike<T>()) {
|
|
119
|
-
// @ts-ignore
|
|
120
|
-
return parseArray<T>(data);
|
|
121
|
-
// @ts-ignore
|
|
122
|
-
} else if (isNullable<T>() && data == "null") {
|
|
123
|
-
// @ts-ignore
|
|
124
|
-
return null;
|
|
125
|
-
// @ts-ignore
|
|
126
|
-
} else if (isDefined(type.__JSON_Deserialize)) {
|
|
127
|
-
// @ts-ignore
|
|
128
|
-
//if (isNullable<T>()) return null;
|
|
129
|
-
return parseObject<T>(data);
|
|
130
|
-
} else {
|
|
131
|
-
// @ts-ignore
|
|
132
|
-
//return null;
|
|
133
|
-
throw new Error(`Could not parse value: ${data}`);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// @ts-ignore
|
|
139
|
-
@inline
|
|
140
|
-
function parseString(data: string): string {
|
|
141
|
-
return data.slice(1, data.length - 1).replaceAll('\\"', '"');
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// @ts-ignore
|
|
145
|
-
@inline
|
|
146
|
-
function parseBoolean<T extends boolean>(data: string): T {
|
|
147
|
-
if (data.length > 3 && data.startsWith("true")) return <T>true;
|
|
148
|
-
else if (data.length > 4 && data.startsWith("false")) return <T>false;
|
|
149
|
-
else throw new Error(`JSON: Cannot parse "${data}" as boolean`);
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// @ts-ignore
|
|
153
|
-
@inline
|
|
154
|
-
function parseNumber<T>(data: string): T {
|
|
155
|
-
let type: T;
|
|
156
|
-
// @ts-ignore
|
|
157
|
-
if (type instanceof f64) return F64.parseFloat(data);
|
|
158
|
-
// @ts-ignore
|
|
159
|
-
else if (type instanceof f32) return F32.parseFloat(data);
|
|
160
|
-
// @ts-ignore
|
|
161
|
-
else if (type instanceof u64) return U64.parseInt(data);
|
|
162
|
-
// @ts-ignore
|
|
163
|
-
else if (type instanceof u32) return U32.parseInt(data);
|
|
164
|
-
// @ts-ignore
|
|
165
|
-
else if (type instanceof u8) return U8.parseInt(data);
|
|
166
|
-
// @ts-ignore
|
|
167
|
-
else if (type instanceof u16) return U16.parseInt(data);
|
|
168
|
-
// @ts-ignore
|
|
169
|
-
else if (type instanceof i64) return I64.parseInt(data);
|
|
170
|
-
// @ts-ignore
|
|
171
|
-
else if (type instanceof i32) return I32.parseInt(data);
|
|
172
|
-
// @ts-ignore
|
|
173
|
-
else if (type instanceof i16) return I16.parseInt(data);
|
|
174
|
-
// @ts-ignore
|
|
175
|
-
else if (type instanceof i8) return I8.parseInt(data);
|
|
176
|
-
else
|
|
177
|
-
throw new Error(
|
|
178
|
-
`JSON: Cannot parse invalid data into a number. Either "${data}" is not a valid number, or <${nameof<T>()}> is an invald number type.`
|
|
179
|
-
);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// @ts-ignore
|
|
183
|
-
@inline
|
|
184
|
-
export function parseObject<T>(data: string): T {
|
|
185
|
-
let schema: T = changetype<T>(__new(offsetof<T>(), idof<T>()));
|
|
186
|
-
const result = new Map<string, string>();
|
|
187
|
-
let key = "";
|
|
188
|
-
let isKey = false;
|
|
189
|
-
let depth = 1;
|
|
190
|
-
let char = 0;
|
|
191
|
-
let outerLoopIndex = 1;
|
|
192
|
-
for (; outerLoopIndex < data.length - 1; outerLoopIndex++) {
|
|
193
|
-
char = unsafeCharCodeAt(data, outerLoopIndex);
|
|
194
|
-
if (char === leftBracketCode) {
|
|
195
|
-
for (
|
|
196
|
-
let arrayValueIndex = outerLoopIndex;
|
|
197
|
-
arrayValueIndex < data.length - 1;
|
|
198
|
-
arrayValueIndex++
|
|
199
|
-
) {
|
|
200
|
-
char = unsafeCharCodeAt(data, arrayValueIndex);
|
|
201
|
-
if (char === leftBracketCode) {
|
|
202
|
-
depth = depth << 1;
|
|
203
|
-
} else if (char === rightBracketCode) {
|
|
204
|
-
depth = depth >> 1;
|
|
205
|
-
if (depth === 1) {
|
|
206
|
-
++arrayValueIndex;
|
|
207
|
-
result.set(key, data.slice(outerLoopIndex, arrayValueIndex));
|
|
208
|
-
outerLoopIndex = arrayValueIndex;
|
|
209
|
-
isKey = false;
|
|
210
|
-
break;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
} else if (char === leftBraceCode) {
|
|
215
|
-
for (
|
|
216
|
-
let objectValueIndex = outerLoopIndex;
|
|
217
|
-
objectValueIndex < data.length - 1;
|
|
218
|
-
objectValueIndex++
|
|
219
|
-
) {
|
|
220
|
-
char = unsafeCharCodeAt(data, objectValueIndex);
|
|
221
|
-
if (char === leftBraceCode) {
|
|
222
|
-
depth = depth << 1;
|
|
223
|
-
} else if (char === rightBraceCode) {
|
|
224
|
-
depth = depth >> 1;
|
|
225
|
-
if (depth === 1) {
|
|
226
|
-
++objectValueIndex;
|
|
227
|
-
result.set(key, data.slice(outerLoopIndex, objectValueIndex));
|
|
228
|
-
outerLoopIndex = objectValueIndex;
|
|
229
|
-
isKey = false;
|
|
230
|
-
break;
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
} else if (char === quoteCode) {
|
|
235
|
-
for (
|
|
236
|
-
let stringValueIndex = ++outerLoopIndex;
|
|
237
|
-
stringValueIndex < data.length - 1;
|
|
238
|
-
stringValueIndex++
|
|
239
|
-
) {
|
|
240
|
-
char = unsafeCharCodeAt(data, stringValueIndex);
|
|
241
|
-
if (
|
|
242
|
-
char === quoteCode &&
|
|
243
|
-
unsafeCharCodeAt(data, stringValueIndex - 1) !== backSlashCode
|
|
244
|
-
) {
|
|
245
|
-
if (isKey === false) {
|
|
246
|
-
key = data.slice(outerLoopIndex, stringValueIndex);
|
|
247
|
-
isKey = true;
|
|
248
|
-
} else {
|
|
249
|
-
result.set(key, data.slice(outerLoopIndex, stringValueIndex));
|
|
250
|
-
isKey = false;
|
|
251
|
-
}
|
|
252
|
-
outerLoopIndex = ++stringValueIndex;
|
|
253
|
-
break;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
} else if (char == nCode) {
|
|
257
|
-
result.set(key, "null");
|
|
258
|
-
isKey = false;
|
|
259
|
-
} else if (
|
|
260
|
-
char === tCode &&
|
|
261
|
-
unsafeCharCodeAt(data, ++outerLoopIndex) === "r".charCodeAt(0) &&
|
|
262
|
-
unsafeCharCodeAt(data, ++outerLoopIndex) === "u".charCodeAt(0) &&
|
|
263
|
-
unsafeCharCodeAt(data, ++outerLoopIndex) === eCode
|
|
264
|
-
) {
|
|
265
|
-
result.set(key, "true");
|
|
266
|
-
isKey = false;
|
|
267
|
-
} else if (
|
|
268
|
-
char === fCode &&
|
|
269
|
-
unsafeCharCodeAt(data, ++outerLoopIndex) === "a".charCodeAt(0) &&
|
|
270
|
-
unsafeCharCodeAt(data, ++outerLoopIndex) === "l".charCodeAt(0) &&
|
|
271
|
-
unsafeCharCodeAt(data, ++outerLoopIndex) === "s".charCodeAt(0) &&
|
|
272
|
-
unsafeCharCodeAt(data, ++outerLoopIndex) === eCode
|
|
273
|
-
) {
|
|
274
|
-
result.set(key, "false");
|
|
275
|
-
isKey = false;
|
|
276
|
-
} else if ((char >= 48 && char <= 57) || char === 45) {
|
|
277
|
-
let numberValueIndex = ++outerLoopIndex;
|
|
278
|
-
for (; numberValueIndex < data.length; numberValueIndex++) {
|
|
279
|
-
char = unsafeCharCodeAt(data, numberValueIndex);
|
|
280
|
-
if (char === commaCode || char === rightBraceCode || isSpace(char)) {
|
|
281
|
-
result.set(key, data.slice(outerLoopIndex - 1, numberValueIndex));
|
|
282
|
-
outerLoopIndex = numberValueIndex;
|
|
283
|
-
isKey = false;
|
|
284
|
-
break;
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
// @ts-ignore
|
|
290
|
-
//const deserialized =
|
|
291
|
-
//changetype<nonnull<T>>(schema).__JSON_Deserialize<T>(result);
|
|
292
|
-
//heap.free(changetype<usize>(schema));
|
|
293
|
-
return changetype<nonnull<T>>(schema).__JSON_Deserialize<T>(result);
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
// @ts-ignore
|
|
297
|
-
@inline
|
|
298
|
-
// @ts-ignore
|
|
299
|
-
export function parseArray<T extends unknown[]>(data: string): T {
|
|
300
|
-
let type!: valueof<T>;
|
|
301
|
-
if (type instanceof String) {
|
|
302
|
-
return <T>parseStringArray(data);
|
|
303
|
-
} else if (isBoolean<valueof<T>>()) {
|
|
304
|
-
// @ts-ignore
|
|
305
|
-
return parseBooleanArray<T>(data);
|
|
306
|
-
} else if (isFloat<valueof<T>>() || isInteger<valueof<T>>()) {
|
|
307
|
-
// @ts-ignore
|
|
308
|
-
return parseNumberArray<T>(data);
|
|
309
|
-
} else if (isArrayLike<valueof<T>>()) {
|
|
310
|
-
// @ts-ignore
|
|
311
|
-
return parseArrayArray<T>(data);
|
|
312
|
-
// @ts-ignore
|
|
313
|
-
} else if (isDefined(type.__JSON_Deserialize)) {
|
|
314
|
-
// @ts-ignore
|
|
315
|
-
return parseObjectArray<T>(data);
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
// @ts-ignore
|
|
320
|
-
@inline
|
|
321
|
-
export function parseStringArray(data: string): string[] {
|
|
322
|
-
const result: string[] = [];
|
|
323
|
-
let lastPos = 0;
|
|
324
|
-
let instr = false;
|
|
325
|
-
for (let i = 1; i < data.length - 1; i++) {
|
|
326
|
-
if (unsafeCharCodeAt(data, i) === quoteCode) {
|
|
327
|
-
if (instr === false) {
|
|
328
|
-
instr = true;
|
|
329
|
-
lastPos = i;
|
|
330
|
-
} else if (unsafeCharCodeAt(data, i - 1) !== backSlashCode) {
|
|
331
|
-
instr = false;
|
|
332
|
-
result.push(data.slice(lastPos + 1, i).replaceAll('\\"', '"'));
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
return result;
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
// @ts-ignore
|
|
340
|
-
@inline
|
|
341
|
-
export function parseBooleanArray<T extends boolean[]>(data: string): T {
|
|
342
|
-
const result = instantiate<T>();
|
|
343
|
-
let lastPos = 1;
|
|
344
|
-
let char = 0;
|
|
345
|
-
for (let i = 1; i < data.length - 1; i++) {
|
|
346
|
-
char = unsafeCharCodeAt(data, i);
|
|
347
|
-
/*// if char == "t" && i+3 == "e"
|
|
348
|
-
if (char === tCode && data.charCodeAt(i + 3) === eCode) {
|
|
349
|
-
//i += 3;
|
|
350
|
-
result.push(parseBoolean<valueof<T>>(data.slice(lastPos, i+2)));
|
|
351
|
-
//i++;
|
|
352
|
-
} else if (char === fCode && data.charCodeAt(i + 4) === eCode) {
|
|
353
|
-
//i += 4;
|
|
354
|
-
result.push(parseBoolean<valueof<T>>(data.slice(lastPos, i+3)));
|
|
355
|
-
//i++;
|
|
356
|
-
}*/
|
|
357
|
-
if (char === tCode || char === fCode) {
|
|
358
|
-
lastPos = i;
|
|
359
|
-
} else if (char === eCode) {
|
|
360
|
-
i++;
|
|
361
|
-
result.push(parseBoolean<valueof<T>>(data.slice(lastPos, i)));
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
return result;
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
// @ts-ignore
|
|
368
|
-
@inline
|
|
369
|
-
export function parseNumberArray<T extends number[]>(data: string): T {
|
|
370
|
-
const result = instantiate<T>();
|
|
371
|
-
let lastPos = 0;
|
|
372
|
-
let char = 0;
|
|
373
|
-
let i = 1;
|
|
374
|
-
for (; i < data.length - 1; i++) {
|
|
375
|
-
char = unsafeCharCodeAt(data, i);
|
|
376
|
-
if ((lastPos === 0 && char >= 48 && char <= 57) || char === 45) {
|
|
377
|
-
lastPos = i;
|
|
378
|
-
} else if ((isSpace(char) || char == commaCode) && lastPos > 0) {
|
|
379
|
-
result.push(parseNumber<valueof<T>>(data.slice(lastPos, i)));
|
|
380
|
-
lastPos = 0;
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
for (; i > lastPos - 1; i--) {
|
|
384
|
-
char = unsafeCharCodeAt(data, i);
|
|
385
|
-
if (char !== rightBracketCode) {
|
|
386
|
-
result.push(parseNumber<valueof<T>>(data.slice(lastPos, i + 1)));
|
|
387
|
-
break;
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
return result;
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
// @ts-ignore
|
|
394
|
-
@inline
|
|
395
|
-
export function parseArrayArray<T extends unknown[][]>(data: string): T {
|
|
396
|
-
const result = instantiate<T>();
|
|
397
|
-
let char = 0;
|
|
398
|
-
let lastPos = 0;
|
|
399
|
-
let depth = 1;
|
|
400
|
-
let i = 1;
|
|
401
|
-
// Find start of bracket
|
|
402
|
-
//for (; unsafeCharCodeAt(data, i) !== leftBracketCode; i++) {}
|
|
403
|
-
//i++;
|
|
404
|
-
for (; i < data.length - 1; i++) {
|
|
405
|
-
char = unsafeCharCodeAt(data, i);
|
|
406
|
-
if (char === leftBracketCode) {
|
|
407
|
-
if (depth === 1) {
|
|
408
|
-
lastPos = i;
|
|
409
|
-
}
|
|
410
|
-
// Shifting is 6% faster than incrementing
|
|
411
|
-
depth = depth << 1;
|
|
412
|
-
} else if (char === rightBracketCode) {
|
|
413
|
-
depth = depth >> 1;
|
|
414
|
-
if (depth === 1) {
|
|
415
|
-
i++;
|
|
416
|
-
result.push(JSON.parse<valueof<T>>(data.slice(lastPos, i)));
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
return result;
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
// @ts-ignore
|
|
424
|
-
@inline
|
|
425
|
-
export function parseObjectArray<T extends unknown[][]>(data: string): T {
|
|
426
|
-
const result = instantiate<T>();
|
|
427
|
-
let char = 0;
|
|
428
|
-
let lastPos = 1;
|
|
429
|
-
let depth = 1;
|
|
430
|
-
let i = 1;
|
|
431
|
-
// Find start of bracket
|
|
432
|
-
//for (; unsafeCharCodeAt(data, i) !== leftBracketCode; i++) { }
|
|
433
|
-
//i++;
|
|
434
|
-
for (; i < data.length - 1; i++) {
|
|
435
|
-
char = unsafeCharCodeAt(data, i);
|
|
436
|
-
if (char === leftBraceCode) {
|
|
437
|
-
if (depth === 1) {
|
|
438
|
-
lastPos = i;
|
|
439
|
-
}
|
|
440
|
-
// Shifting is 6% faster than incrementing
|
|
441
|
-
depth = depth << 1;
|
|
442
|
-
} else if (char === rightBraceCode) {
|
|
443
|
-
depth = depth >> 1;
|
|
444
|
-
if (depth === 1) {
|
|
445
|
-
i++;
|
|
446
|
-
result.push(JSON.parse<valueof<T>>(data.slice(lastPos, i)));
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
return result;
|
|
451
|
-
}
|