json-as 1.0.0-beta.1 → 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 +275 -25
- package/assembly/__benches__/misc.bench.ts +0 -1
- package/assembly/__benches__/string.bench.ts +23 -0
- package/assembly/__benches__/struct.bench.ts +21 -0
- package/assembly/__tests__/arbitrary.spec.ts +1 -1
- 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/as-bs.d.ts +53 -0
- package/assembly/custom/bench.ts +26 -0
- package/assembly/deserialize/simple/array/arbitrary.ts +1 -2
- 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 +14 -3
- package/assembly/deserialize/simple/array.ts +3 -0
- package/assembly/deserialize/simple/map.ts +92 -67
- package/assembly/deserialize/simple/object.ts +3 -2
- package/assembly/deserialize/simple/raw.ts +6 -0
- package/assembly/deserialize/simple/struct.ts +29 -16
- package/assembly/index.d.ts +15 -1
- package/assembly/index.ts +94 -13
- package/assembly/serialize/simd/string.ts +0 -1
- 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 +0 -1
- package/assembly/serialize/simple/raw.ts +14 -0
- package/assembly/serialize/simple/string.ts +0 -1
- package/assembly/test.ts +69 -28
- package/bench/bench.ts +15 -0
- package/bench/schemas.ts +5 -0
- package/bench/string.bench.ts +16 -0
- package/index.ts +1 -1
- package/lib/tsconfig.json +8 -0
- package/package.json +9 -6
- package/run-tests.sh +1 -1
- package/transform/lib/index.js +120 -46
- package/transform/lib/index.js.map +1 -1
- package/transform/src/index.ts +137 -54
- package/.gitmodules +0 -0
- package/as-test.config.json +0 -18
- package/modules/as-bs/LICENSE +0 -21
- package/modules/as-bs/README.md +0 -95
- package/modules/as-bs/assembly/state.ts +0 -8
- 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
- /package/{modules/as-bs/assembly/index.ts → lib/as-bs.ts} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { JSON } from "..";
|
|
2
|
-
import { describe, expect } from "
|
|
2
|
+
import { describe, expect } from "./lib";
|
|
3
3
|
|
|
4
4
|
describe("Should serialize floats", () => {
|
|
5
5
|
expect(JSON.stringify<f64>(7.23)).toBe("7.23");
|
|
@@ -34,9 +34,9 @@ describe("Should deserialize floats", () => {
|
|
|
34
34
|
|
|
35
35
|
expect(JSON.parse<f64>("0.000001").toString()).toBe("0.000001");
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
expect(JSON.parse<f64>("1e-7").toString()).toBe(1e-7.toString());
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
expect(JSON.parse<f64>("100000000000000000000.0").toString()).toBe(1e20.toString());
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
expect(JSON.parse<f64>("1e+21").toString()).toBe(1e21.toString());
|
|
42
42
|
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { JSON } from "..";
|
|
2
|
+
import { describe, expect } from "./lib";
|
|
3
|
+
|
|
4
|
+
describe("Should serialize JSON.Raw", () => {
|
|
5
|
+
expect(JSON.stringify<JSON.Raw>(JSON.Raw.from('{"x":1.0,"y":2.0,"z":3.0}'))).toBe('{"x":1.0,"y":2.0,"z":3.0}');
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
describe("Should deserialize JSON.Raw", () => {
|
|
9
|
+
expect(JSON.parse<JSON.Raw>('{"x":1.0,"y":2.0,"z":3.0}').toString()).toBe('{"x":1.0,"y":2.0,"z":3.0}');
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
describe("Should serialize Map<string, JSON.Raw>", () => {
|
|
13
|
+
const m1 = new Map<string, JSON.Raw>();
|
|
14
|
+
m1.set("hello", new JSON.Raw("\"world\""));
|
|
15
|
+
m1.set("pos", new JSON.Raw("{\"x\":1.0,\"y\":2.0,\"z\":3.0}"));
|
|
16
|
+
|
|
17
|
+
expect(JSON.stringify(m1)).toBe('{"hello":"world","pos":{"x":1.0,"y":2.0,"z":3.0}}');
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
describe("Should deserialize Map<string, JSON.Raw>", () => {
|
|
21
|
+
const m1 = JSON.parse<Map<string, JSON.Raw>>('{"hello":"world","pos":{"x":1.0,"y":2.0,"z":3.0}}');
|
|
22
|
+
expect(JSON.stringify(m1)).toBe('{"hello":"world","pos":{"x":1.0,"y":2.0,"z":3.0}}');
|
|
23
|
+
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { JSON } from "..";
|
|
2
|
-
import { describe, expect } from "
|
|
2
|
+
import { describe, expect } from "./lib";
|
|
3
3
|
|
|
4
|
-
describe("Should serialize
|
|
4
|
+
describe("Should serialize structs", () => {
|
|
5
5
|
expect(
|
|
6
6
|
JSON.stringify<Vec3>({
|
|
7
7
|
x: 3.4,
|
|
@@ -38,7 +38,7 @@ describe("Should serialize objects", () => {
|
|
|
38
38
|
expect(JSON.stringify<ObjWithStrangeKey<string>>({ data: "foo" })).toBe('{"a\\\\\\t\\"\\u0002b`c":"foo"}');
|
|
39
39
|
});
|
|
40
40
|
|
|
41
|
-
describe("Should serialize
|
|
41
|
+
describe("Should serialize structs with inheritance", () => {
|
|
42
42
|
const obj = new DerivedObject("1", "2");
|
|
43
43
|
|
|
44
44
|
expect(JSON.stringify(obj)).toBe('{"a":"1","b":"2"}');
|
|
@@ -52,6 +52,21 @@ describe("Should ignore properties decorated with @omit", () => {
|
|
|
52
52
|
).toBe('{"y":1,"x":1,"z":1}');
|
|
53
53
|
});
|
|
54
54
|
|
|
55
|
+
describe("Should deserialize structs", () => {
|
|
56
|
+
expect(
|
|
57
|
+
JSON.stringify(JSON.parse<Vec3>('{"x":3.4,"y":1.2,"z":8.3}')),
|
|
58
|
+
).toBe('{"x":3.4,"y":1.2,"z":8.3}');
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
describe("Should deserialize structs with whitespace", () => {
|
|
62
|
+
expect(
|
|
63
|
+
JSON.stringify(JSON.parse<Vec3>(' { "x" : 3.4 , "y" : 1.2 , "z" : 8.3 } ')),
|
|
64
|
+
).toBe('{"x":3.4,"y":1.2,"z":8.3}');
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// describe("Should serialize Suite struct", () => {
|
|
68
|
+
|
|
69
|
+
// });
|
|
55
70
|
|
|
56
71
|
@json
|
|
57
72
|
class BaseObject {
|
|
@@ -99,7 +114,6 @@ class ObjWithString {
|
|
|
99
114
|
|
|
100
115
|
@json
|
|
101
116
|
class ObjWithStrangeKey<T> {
|
|
102
|
-
|
|
103
117
|
@alias('a\\\t"\x02b`c')
|
|
104
118
|
data!: T;
|
|
105
119
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { JSON } from "../";
|
|
2
|
-
import { describe, expect } from "
|
|
2
|
+
import { describe, expect } from "./lib";
|
|
3
3
|
import { DerivedObject, Null, ObjWithStrangeKey, ObjectWithFloat, OmitIf, Player, Vec3 } from "./types";
|
|
4
4
|
|
|
5
5
|
// describe("Should serialize objects", () => {
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Central buffer namespace for managing memory operations.
|
|
3
|
+
*/
|
|
4
|
+
declare namespace bs {
|
|
5
|
+
/** Current buffer pointer. */
|
|
6
|
+
export let buffer: ArrayBuffer;
|
|
7
|
+
|
|
8
|
+
/** Current offset within the buffer. */
|
|
9
|
+
export let offset: usize;
|
|
10
|
+
|
|
11
|
+
/** Proposed size of output. */
|
|
12
|
+
export let stackSize: usize;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Ensures the buffer size is at least the proposed size.
|
|
16
|
+
* If necessary, reallocates the buffer to the exact new size.
|
|
17
|
+
* @param size - The size to propose.
|
|
18
|
+
*/
|
|
19
|
+
export function ensureSize(size: u32): void;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Proposes that the buffer size should be at least the given size.
|
|
23
|
+
* If necessary, reallocates the buffer to the exact new size.
|
|
24
|
+
* @param size - The size to propose.
|
|
25
|
+
*/
|
|
26
|
+
export function proposeSize(size: u32): void;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Increases the proposed size by nextPowerOf2(n + 64) if necessary.
|
|
30
|
+
* If necessary, reallocates the buffer to the exact new size.
|
|
31
|
+
* @param size - The size to grow by.
|
|
32
|
+
*/
|
|
33
|
+
export function growSize(size: u32): void;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Resizes the buffer to the specified size.
|
|
37
|
+
* @param newSize - The new buffer size.
|
|
38
|
+
*/
|
|
39
|
+
export function resize(newSize: u32): void;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Copies the buffer's content to a new object of a specified type.
|
|
43
|
+
* @returns The new object containing the buffer's content.
|
|
44
|
+
*/
|
|
45
|
+
export function out<T>(): T;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Copies the buffer's content to a given destination pointer.
|
|
49
|
+
* @param dst - The destination pointer.
|
|
50
|
+
* @returns The destination pointer cast to the specified type.
|
|
51
|
+
*/
|
|
52
|
+
export function outTo<T>(dst: usize): T;
|
|
53
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export function bench(description: string, routine: () => void, ops: u64 = 1_000_000): void {
|
|
2
|
+
console.log(" - Benchmarking " + description);
|
|
3
|
+
const start = Date.now();
|
|
4
|
+
let count = ops;
|
|
5
|
+
while (count != 0) {
|
|
6
|
+
routine();
|
|
7
|
+
count--;
|
|
8
|
+
}
|
|
9
|
+
const elapsed = Date.now() - start;
|
|
10
|
+
|
|
11
|
+
let opsPerSecond = (ops * 1000) / elapsed;
|
|
12
|
+
|
|
13
|
+
console.log(` Completed benchmark in ${formatNumber(elapsed)}ms at ${formatNumber(opsPerSecond)} ops/s\n`);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function formatNumber(n: u64): string {
|
|
17
|
+
let str = n.toString();
|
|
18
|
+
let len = str.length;
|
|
19
|
+
let result = "";
|
|
20
|
+
let commaOffset = len % 3;
|
|
21
|
+
for (let i = 0; i < len; i++) {
|
|
22
|
+
if (i > 0 && (i - commaOffset) % 3 == 0) result += ",";
|
|
23
|
+
result += str.charAt(i);
|
|
24
|
+
}
|
|
25
|
+
return result;
|
|
26
|
+
}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { BACK_SLASH, BRACE_LEFT, BRACE_RIGHT, BRACKET_LEFT, BRACKET_RIGHT, CHAR_F, CHAR_N, CHAR_T, COMMA, QUOTE } from "../../../custom/chars";
|
|
2
2
|
import { JSON } from "../../../";
|
|
3
3
|
import { isSpace } from "util/string";
|
|
4
|
-
import { ptrToStr } from "../../../util/ptrToStr";
|
|
5
4
|
|
|
6
5
|
export function deserializeArbitraryArray(srcStart: usize, srcEnd: usize, dst: usize): JSON.Value[] {
|
|
7
|
-
const out =
|
|
6
|
+
const out = changetype<JSON.Value[]>(dst || changetype<usize>(instantiate<JSON.Value[]>()));
|
|
8
7
|
let lastIndex: usize = 0;
|
|
9
8
|
let depth: u32 = 0;
|
|
10
9
|
// if (load<u16>(srcStart) != BRACKET_LEFT)
|
|
@@ -2,15 +2,16 @@ import { BRACKET_LEFT, BRACKET_RIGHT } from "../../../custom/chars";
|
|
|
2
2
|
import { JSON } from "../../../";
|
|
3
3
|
|
|
4
4
|
export function deserializeArrayArray<T extends unknown[][]>(srcStart: usize, srcEnd: usize, dst: usize): T {
|
|
5
|
-
const out = dst
|
|
5
|
+
const out = changetype<nonnull<T>>(dst || changetype<usize>(instantiate<T>()));
|
|
6
6
|
let lastIndex: usize = 0;
|
|
7
7
|
let depth: u32 = 0;
|
|
8
|
-
|
|
8
|
+
srcStart += 2;
|
|
9
|
+
while (srcStart < srcEnd - 2) {
|
|
9
10
|
const code = load<u16>(srcStart);
|
|
10
11
|
if (code == BRACKET_LEFT && depth++ == 0) {
|
|
11
12
|
lastIndex = srcStart;
|
|
12
13
|
} else if (code == BRACKET_RIGHT && --depth == 0) {
|
|
13
|
-
out.push(JSON.__deserialize<valueof<T>>(lastIndex, srcStart));
|
|
14
|
+
out.push(JSON.__deserialize<valueof<T>>(lastIndex, srcStart + 2));
|
|
14
15
|
}
|
|
15
16
|
srcStart += 2;
|
|
16
17
|
}
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { CHAR_E, CHAR_F, CHAR_T } from "../../../custom/chars";
|
|
2
|
-
|
|
3
1
|
export function deserializeBooleanArray<T extends boolean[]>(srcStart: usize, srcEnd: usize, dst: usize): T {
|
|
4
|
-
const out = dst
|
|
2
|
+
const out = changetype<nonnull<T>>(dst || changetype<usize>(instantiate<T>()));
|
|
3
|
+
srcStart += 2; // skip [
|
|
5
4
|
while (srcStart < srcEnd) {
|
|
6
|
-
const
|
|
7
|
-
if (
|
|
5
|
+
const block = load<u64>(srcStart);
|
|
6
|
+
if (block == 28429475166421108) {
|
|
8
7
|
out.push(true);
|
|
9
8
|
srcStart += 10;
|
|
10
|
-
} else if (
|
|
9
|
+
} else if (block == 32370086184550502 && load<u16>(srcStart, 8) == 101) {
|
|
11
10
|
out.push(false);
|
|
12
11
|
srcStart += 12;
|
|
12
|
+
} else {
|
|
13
|
+
srcStart += 2;
|
|
13
14
|
}
|
|
14
|
-
srcStart += 2;
|
|
15
15
|
}
|
|
16
16
|
return out;
|
|
17
17
|
}
|
|
@@ -3,7 +3,7 @@ import { COMMA, BRACE_RIGHT, BRACKET_RIGHT } from "../../../custom/chars";
|
|
|
3
3
|
import { JSON } from "../../..";
|
|
4
4
|
|
|
5
5
|
export function deserializeFloatArray<T extends number[]>(srcStart: usize, srcEnd: usize, dst: usize): T {
|
|
6
|
-
const out = dst
|
|
6
|
+
const out = changetype<nonnull<T>>(dst || changetype<usize>(instantiate<T>()));
|
|
7
7
|
let lastIndex: usize = 0;
|
|
8
8
|
while (srcStart < srcEnd) {
|
|
9
9
|
const code = load<u16>(srcStart);
|
|
@@ -2,7 +2,7 @@ import { atoi, isSpace } from "../../../util";
|
|
|
2
2
|
import { COMMA, BRACKET_RIGHT } from "../../../custom/chars";
|
|
3
3
|
|
|
4
4
|
export function deserializeIntegerArray<T extends number[]>(srcStart: usize, srcEnd: usize, dst: usize): T {
|
|
5
|
-
const out
|
|
5
|
+
const out = changetype<nonnull<T>>(dst || changetype<usize>(instantiate<T>()));
|
|
6
6
|
let lastIndex: usize = 0;
|
|
7
7
|
while (srcStart < srcEnd) {
|
|
8
8
|
const code = load<u16>(srcStart);
|
|
@@ -2,7 +2,7 @@ import { BRACE_LEFT, BRACE_RIGHT } from "../../../custom/chars";
|
|
|
2
2
|
import { JSON } from "../../..";
|
|
3
3
|
|
|
4
4
|
export function deserializeMapArray<T extends Map<any, any>[]>(srcStart: usize, srcEnd: usize, dst: usize): T {
|
|
5
|
-
const out = dst
|
|
5
|
+
const out = changetype<nonnull<T>>(dst || changetype<usize>(instantiate<T>()));
|
|
6
6
|
let lastIndex: usize = 0;
|
|
7
7
|
let depth: u32 = 0;
|
|
8
8
|
while (srcStart < srcEnd) {
|
|
@@ -2,8 +2,8 @@ import { JSON } from "../../..";
|
|
|
2
2
|
import { BACK_SLASH, QUOTE } from "../../../custom/chars";
|
|
3
3
|
|
|
4
4
|
export function deserializeStringArray(srcStart: usize, srcEnd: usize, dst: usize): string[] {
|
|
5
|
-
const out =
|
|
6
|
-
let lastPos = 2;
|
|
5
|
+
const out = changetype<string[]>(dst || changetype<usize>(instantiate<string[]>()));
|
|
6
|
+
let lastPos: usize = 2;
|
|
7
7
|
let inString = false;
|
|
8
8
|
while (srcStart < srcEnd) {
|
|
9
9
|
const code = load<u16>(srcStart);
|
|
@@ -12,7 +12,7 @@ export function deserializeStringArray(srcStart: usize, srcEnd: usize, dst: usiz
|
|
|
12
12
|
inString = true;
|
|
13
13
|
lastPos = srcStart;
|
|
14
14
|
} else if (load<u16>(srcStart - 2) != BACK_SLASH) {
|
|
15
|
-
out.push(JSON.__deserialize<string>(lastPos, srcStart));
|
|
15
|
+
out.push(JSON.__deserialize<string>(lastPos, srcStart + 2));
|
|
16
16
|
inString = false;
|
|
17
17
|
}
|
|
18
18
|
}
|
|
@@ -1,16 +1,27 @@
|
|
|
1
|
-
import { BRACE_LEFT, BRACE_RIGHT } from "../../../custom/chars";
|
|
1
|
+
import { BRACE_LEFT, BRACE_RIGHT, BRACKET_LEFT, BRACKET_RIGHT } from "../../../custom/chars";
|
|
2
2
|
import { JSON } from "../../..";
|
|
3
|
+
import { isSpace } from "util/string";
|
|
3
4
|
|
|
4
5
|
export function deserializeStructArray<T extends unknown[]>(srcStart: usize, srcEnd: usize, dst: usize): T {
|
|
5
|
-
const out = dst
|
|
6
|
+
const out = changetype<nonnull<T>>(dst || changetype<usize>(instantiate<T>()));
|
|
6
7
|
let lastIndex: usize = 0;
|
|
7
8
|
let depth: u32 = 0;
|
|
9
|
+
|
|
10
|
+
while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
|
|
11
|
+
while (srcEnd > srcStart && isSpace(load<u16>(srcEnd - 2))) srcEnd -= 2;
|
|
12
|
+
|
|
13
|
+
if (srcStart - srcEnd == 0)
|
|
14
|
+
throw new Error("Input string had zero length or was all whitespace");
|
|
15
|
+
|
|
16
|
+
if (load<u16>(srcStart) != BRACKET_LEFT) throw new Error("Expected '[' at start of object at position " + (srcEnd - srcStart).toString());
|
|
17
|
+
if (load<u16>(srcEnd - 2) != BRACKET_RIGHT) throw new Error("Expected ']' at end of object at position " + (srcEnd - srcStart).toString());
|
|
18
|
+
|
|
8
19
|
while (srcStart < srcEnd) {
|
|
9
20
|
const code = load<u16>(srcStart);
|
|
10
21
|
if (code == BRACE_LEFT && depth++ == 0) {
|
|
11
22
|
lastIndex = srcStart;
|
|
12
23
|
} else if (code == BRACE_RIGHT && --depth == 0) {
|
|
13
|
-
out.push(JSON.__deserialize<valueof<T>>(lastIndex, srcStart));
|
|
24
|
+
out.push(JSON.__deserialize<valueof<T>>(lastIndex, srcStart += 2));
|
|
14
25
|
}
|
|
15
26
|
srcStart += 2;
|
|
16
27
|
}
|
|
@@ -33,6 +33,9 @@ export function deserializeArray<T extends unknown[]>(srcStart: usize, srcEnd: u
|
|
|
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
40
|
return deserializeStructArray<T>(srcStart, srcEnd, dst);
|
|
38
41
|
}
|
|
@@ -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 (code ==
|
|
89
|
+
if (code == QUOTE) {
|
|
90
|
+
srcStart += 2;
|
|
91
|
+
while (!(load<u16>(srcStart) == QUOTE && load<u16>(srcStart - 2) != BACK_SLASH)) srcStart += 2;
|
|
92
|
+
} else if (code == BRACE_RIGHT) {
|
|
80
93
|
if (--depth == 0) {
|
|
94
|
+
// console.log("Value (object): " + ptrToStr(lastIndex, srcStart + 2));
|
|
81
95
|
// @ts-ignore: type
|
|
82
|
-
out.set(
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
96
|
+
out.set(ptrToStr(keyStart, keyEnd), JSON.__deserialize<valueof<T>>(lastIndex, (srcStart += 2)));
|
|
97
|
+
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
|
|
98
|
+
keyStart = 0;
|
|
99
|
+
// while (isSpace(load<u16>(srcStart))) {
|
|
100
|
+
// /* empty */
|
|
101
|
+
// }
|
|
87
102
|
break;
|
|
88
103
|
}
|
|
89
|
-
} else if (code ==
|
|
104
|
+
} else if (code == BRACE_LEFT) depth++;
|
|
90
105
|
srcStart += 2;
|
|
91
106
|
}
|
|
92
|
-
|
|
93
|
-
} else if (isDefined(changetype<nonnull<valueof<T>>>(0).__DESERIALIZE) && code == BRACE_LEFT) {
|
|
107
|
+
} else if (code == BRACKET_LEFT) {
|
|
94
108
|
lastIndex = srcStart;
|
|
95
109
|
depth++;
|
|
96
110
|
srcStart += 2;
|
|
97
111
|
while (srcStart < srcEnd) {
|
|
98
112
|
const code = load<u16>(srcStart);
|
|
99
|
-
if (code ==
|
|
113
|
+
if (code == BRACKET_RIGHT) {
|
|
100
114
|
if (--depth == 0) {
|
|
115
|
+
// console.log("Value (array): " + ptrToStr(lastIndex, srcStart + 2));
|
|
101
116
|
// @ts-ignore: type
|
|
102
|
-
out.set(
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
117
|
+
out.set(ptrToStr(keyStart, keyEnd), JSON.__deserialize<valueof<T>>(lastIndex, (srcStart += 2)));
|
|
118
|
+
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
|
|
119
|
+
keyStart = 0;
|
|
120
|
+
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
121
|
+
// /* empty */
|
|
122
|
+
// }
|
|
107
123
|
break;
|
|
108
124
|
}
|
|
109
|
-
} else if (code ==
|
|
125
|
+
} else if (code == BRACKET_LEFT) depth++;
|
|
110
126
|
srcStart += 2;
|
|
111
127
|
}
|
|
112
|
-
|
|
113
|
-
} else if (isBoolean<valueof<T>>() && code == CHAR_T) {
|
|
128
|
+
} else if (code == CHAR_T) {
|
|
114
129
|
if (load<u64>(srcStart) == 28429475166421108) {
|
|
130
|
+
// console.log("Value (bool): " + ptrToStr(srcStart, srcStart + 8));
|
|
115
131
|
// @ts-ignore: type
|
|
116
|
-
out.set(
|
|
117
|
-
while (isSpace(load<u16>((srcStart += 2)))) {
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
|
|
132
|
+
out.set(ptrToStr(keyStart, keyEnd), JSON.__deserialize<valueof<T>>(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
|
}
|
|
@@ -13,8 +13,9 @@ export function deserializeObject(srcStart: usize, srcEnd: usize, dst: usize): J
|
|
|
13
13
|
let depth = 0;
|
|
14
14
|
let lastIndex: usize = 0;
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
|
|
17
|
+
while (srcEnd > srcStart && isSpace(load<u16>(srcEnd - 2))) srcEnd -= 2;
|
|
18
|
+
|
|
18
19
|
srcStart += 2;
|
|
19
20
|
while (srcStart < srcEnd) {
|
|
20
21
|
let code = load<u16>(srcStart); // while (isSpace(code)) code = load<u16>(srcStart += 2);
|