Skip to content

Commit 8446389

Browse files
committed
feat: implement full arbitrary object support
1 parent a6a19c7 commit 8446389

File tree

5 files changed

+179
-3
lines changed

5 files changed

+179
-3
lines changed

assembly/deserialize/simple/arbitrary.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ import { JSON } from "../..";
22
import { deserializeArray } from "./array";
33
import { deserializeBoolean } from "./bool";
44
import { deserializeFloat } from "./float";
5-
import { deserializeStruct } from "./struct";
65
import { deserializeString } from "./string";
6+
import { deserializeObject } from "./object";
77

88
export function deserializeArbitrary(srcStart: usize, srcEnd: usize, dst: usize): JSON.Value {
99
const firstChar = load<u16>(srcStart);
1010
if (firstChar == 34) return JSON.Value.from(deserializeString(srcStart, srcEnd, dst));
11-
else if (firstChar == 123) return JSON.Value.from(deserializeStruct(srcStart, srcEnd, dst));
11+
else if (firstChar == 123) return JSON.Value.from(deserializeObject(srcStart, srcEnd, dst));
1212
else if (firstChar - 48 <= 9 || firstChar == 45) return JSON.Value.from(deserializeFloat<f64>(srcStart, srcEnd));
1313
else if (firstChar == 91) {
1414
return JSON.Value.from(deserializeArray<JSON.Value[]>(srcStart, srcEnd, dst));
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
import { JSON } from "../..";
2+
import { BACK_SLASH, COMMA, CHAR_F, BRACE_LEFT, BRACKET_LEFT, CHAR_N, QUOTE, BRACE_RIGHT, BRACKET_RIGHT, CHAR_T } from "../../custom/chars";
3+
import { isSpace } from "../../util";
4+
import { ptrToStr } from "../../util/ptrToStr";
5+
import { deserializeArbitrary } from "./arbitrary";
6+
7+
export function deserializeObject(srcStart: usize, srcEnd: usize, dst: usize): JSON.Obj {
8+
const out = new JSON.Obj();
9+
10+
let keyStart: usize = 0;
11+
let keyEnd: usize = 0;
12+
let isKey = false;
13+
let depth = 0;
14+
let lastIndex: usize = 0;
15+
16+
// while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
17+
// while (srcEnd > srcStart && isSpace(load<u16>(srcEnd))) srcEnd -= 2;
18+
srcStart += 2;
19+
while (srcStart < srcEnd) {
20+
let code = load<u16>(srcStart); // while (isSpace(code)) code = load<u16>(srcStart += 2);
21+
if (keyStart == 0) {
22+
if (code == QUOTE && load<u16>(srcStart - 2) !== BACK_SLASH) {
23+
if (isKey) {
24+
keyStart = lastIndex;
25+
keyEnd = srcStart;
26+
console.log("Key: " + ptrToStr(keyStart, keyEnd));
27+
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart + 2)));
28+
srcStart += 2;
29+
// while (isSpace((code = load<u16>((srcStart += 2))))) {
30+
// /* empty */
31+
// }
32+
// if (code !== COLON) throw new Error("Expected ':' after key at position " + (srcStart - srcPtr).toString());
33+
isKey = false;
34+
} else {
35+
// console.log("Got key start");
36+
isKey = true; // i don't like this
37+
lastIndex = srcStart + 2;
38+
}
39+
}
40+
// isKey = !isKey;
41+
srcStart += 2;
42+
} else {
43+
if (code == QUOTE) {
44+
lastIndex = srcStart;
45+
srcStart += 2;
46+
while (srcStart < srcEnd) {
47+
const code = load<u16>(srcStart);
48+
if (code == QUOTE && load<u16>(srcStart - 2) !== BACK_SLASH) {
49+
console.log("Value (string): " + ptrToStr(lastIndex, srcStart + 2));
50+
out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, srcStart + 2, dst));
51+
// while (isSpace(load<u16>(srcStart))) srcStart += 2;
52+
srcStart += 4;
53+
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
54+
keyStart = 0;
55+
break;
56+
}
57+
srcStart += 2;
58+
}
59+
} else if (code - 48 <= 9 || code == 45) {
60+
lastIndex = srcStart;
61+
srcStart += 2;
62+
while (srcStart < srcEnd) {
63+
const code = load<u16>(srcStart);
64+
if (code == COMMA || code == BRACE_RIGHT || isSpace(code)) {
65+
console.log("Value (number): " + ptrToStr(lastIndex, srcStart));
66+
out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, srcStart, dst));
67+
// while (isSpace(load<u16>((srcStart += 2)))) {
68+
// /* empty */
69+
// }
70+
srcStart += 2;
71+
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
72+
keyStart = 0;
73+
break;
74+
}
75+
srcStart += 2;
76+
}
77+
} else if (code == BRACE_LEFT) {
78+
lastIndex = srcStart;
79+
depth++;
80+
srcStart += 2;
81+
while (srcStart < srcEnd) {
82+
const code = load<u16>(srcStart);
83+
if (code == BRACE_RIGHT) {
84+
if (--depth == 0) {
85+
console.log("Value (object): " + ptrToStr(lastIndex, srcStart + 2));
86+
out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, srcStart += 2, dst));
87+
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
88+
keyStart = 0;
89+
// while (isSpace(load<u16>(srcStart))) {
90+
// /* empty */
91+
// }
92+
break;
93+
}
94+
} else if (code == BRACE_LEFT) depth++;
95+
srcStart += 2;
96+
}
97+
} else if (code == BRACKET_LEFT) {
98+
lastIndex = srcStart;
99+
depth++;
100+
srcStart += 2;
101+
while (srcStart < srcEnd) {
102+
const code = load<u16>(srcStart);
103+
if (code == BRACKET_RIGHT) {
104+
if (--depth == 0) {
105+
console.log("Value (array): " + ptrToStr(lastIndex, srcStart + 2));
106+
out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, srcStart += 2, dst));
107+
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
108+
keyStart = 0;
109+
// while (isSpace(load<u16>((srcStart += 2)))) {
110+
// /* empty */
111+
// }
112+
break;
113+
}
114+
} else if (code == BRACKET_LEFT) depth++;
115+
srcStart += 2;
116+
}
117+
} else if (code == CHAR_T) {
118+
if (load<u64>(srcStart) == 28429475166421108) {
119+
console.log("Value (bool): " + ptrToStr(srcStart, srcStart + 8));
120+
out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, srcStart += 8, dst));
121+
// while (isSpace(load<u16>((srcStart += 2)))) {
122+
// /* empty */
123+
// }
124+
srcStart += 2;
125+
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)) + " " + (srcStart < srcEnd).toString());
126+
keyStart = 0;
127+
}
128+
} else if (code == CHAR_F) {
129+
if (load<u64>(srcStart, 2) == 28429466576093281) {
130+
console.log("Value (bool): " + ptrToStr(srcStart, srcStart + 10));
131+
out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, srcStart += 10, dst));
132+
// while (isSpace(load<u16>((srcStart += 2)))) {
133+
// /* empty */
134+
// }
135+
srcStart += 2;
136+
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
137+
keyStart = 0;
138+
}
139+
} else if (code == CHAR_N) {
140+
if (load<u64>(srcStart) == 30399761348886638) {
141+
console.log("Value (null): " + ptrToStr(srcStart, srcStart + 8));
142+
out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, srcStart += 8, dst));
143+
// while (isSpace(load<u16>((srcStart += 2)))) {
144+
/* empty */
145+
// }
146+
srcStart += 2;
147+
// console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
148+
keyStart = 0;
149+
}
150+
}
151+
}
152+
}
153+
return out;
154+
}

assembly/index.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import { bytes } from "./util";
2626
import { deserializeArbitrary } from "./deserialize/simple/arbitrary";
2727
import { SERIALIZE_ESCAPE_TABLE } from "./globals/tables";
2828
import { serializeObject } from "./serialize/simple/object";
29+
import { deserializeObject } from "./deserialize/simple/object";
2930

3031
export type Raw = string;
3132

@@ -192,6 +193,9 @@ export namespace JSON {
192193
} else if (type instanceof JSON.Value) {
193194
// @ts-ignore
194195
return deserializeArbitrary(dataPtr, dataPtr + dataSize, 0);
196+
} else if (type instanceof JSON.Obj) {
197+
// @ts-ignore
198+
return deserializeObject(dataPtr, dataPtr + dataSize, 0);
195199
} else if (type instanceof JSON.Box) {
196200
// @ts-ignore
197201
return new JSON.Box(parseBox(data, changetype<nonnull<T>>(0).value));
@@ -483,6 +487,8 @@ export namespace JSON {
483487
serializeMap(changetype<nonnull<T>>(src));
484488
} else if (src instanceof JSON.Value) {
485489
serializeArbitrary(src);
490+
} else if (src instanceof JSON.Obj) {
491+
serializeObject(src);
486492
} else if (src instanceof JSON.Box) {
487493
__serialize(src.value);
488494
} else {
@@ -514,6 +520,9 @@ export namespace JSON {
514520
} else if (type instanceof Date) {
515521
// @ts-ignore: type
516522
return deserializeDate(srcStart, srcEnd);
523+
} else if (type instanceof JSON.Value) {
524+
// @ts-ignore: type
525+
return deserializeArbitrary(srcStart, srcEnd, 0);
517526
} else if (type instanceof JSON.Box) {
518527
// @ts-ignore: type
519528
return new JSON.Box(deserializeBox(srcStart, srcEnd, dst, changetype<nonnull<T>>(0).value));

assembly/serialize/simple/arbitrary.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { serializeArray } from "./array";
33
import { serializeBool } from "./bool";
44
import { serializeFloat } from "./float";
55
import { serializeInteger } from "./integer";
6+
import { serializeObject } from "./object";
67
import { serializeString } from "./string";
78

89
export function serializeArbitrary(src: JSON.Value): void {
@@ -35,6 +36,10 @@ export function serializeArbitrary(src: JSON.Value): void {
3536
serializeArray(src.get<JSON.Value[]>());
3637
break;
3738
}
39+
case JSON.Types.Object: {
40+
serializeObject(src.get<JSON.Obj>());
41+
break;
42+
}
3843
default: {
3944
const fn = JSON.Value.METHODS.get(src.type - JSON.Types.Struct);
4045
const ptr = src.get<usize>();

assembly/test.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,12 @@ a4.set("z", 9.8);
6464
a4.set("obj", obj)
6565
a4.set<boolean>("bool", false);
6666

67-
console.log("a4: " + JSON.stringify(a4));
67+
console.log("a4: " + JSON.stringify(a4));
68+
69+
const a5 = JSON.parse<JSON.Obj>('{"foo":"bar"}');
70+
71+
console.log("a5: " + JSON.stringify(a5));
72+
73+
const a6 = JSON.parse<JSON.Obj>('{"x":1.5,"y":5.4,"z":9.8,"obj":{"foo":"bar"}}');
74+
75+
console.log("a6: " + JSON.stringify(a6));

0 commit comments

Comments
 (0)