Skip to content

Commit

Permalink
finish arbitrary array deserialization
Browse files Browse the repository at this point in the history
  • Loading branch information
JairusSW committed Jan 17, 2025
1 parent c97f121 commit f023966
Show file tree
Hide file tree
Showing 8 changed files with 346 additions and 52 deletions.
22 changes: 9 additions & 13 deletions assembly/deserialize/simple/arbitrary.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
import { JSON } from "../..";
import { unsafeCharCodeAt } from "../../custom/util";
import { deserializeArray } from "./array";
import { deserializeBoolean } from "./bool";
import { deserializeFloat } from "./float";
import { deserializeInteger } from "./integer";
import { deserializeObject } from "./object";
import { deserializeString } from "./string";

// @ts-ignore
@inline export function deserializeArbitrary(srcStart: usize, srcEnd: usize, dst: usize = 0): JSON.Value {
const firstChar = unsafeCharCodeAt(data, 0);

if (firstChar == 34) return JSON.Value.from(deserializeString(data));
if (firstChar == 123) return JSON.Value.from(deserializeObject(data));
if (firstChar > 47 && firstChar < 58) return JSON.Value.from(data.includes(".") ? deserializeInteger<u64>(data) : deserializeFloat<f64>(data));
if (firstChar == 45) return JSON.Value.from(data.includes(".") ? deserializeInteger<i64>(data) : deserializeFloat<f64>(data));
if (firstChar == 91) {
// array
}
if (firstChar == 116 || firstChar == 102) return JSON.Value.from(deserializeBoolean(data));
@inline export function deserializeArbitrary(srcStart: usize, srcEnd: usize, dst: usize): JSON.Value {
const firstChar = load<u16>(srcStart);
if (firstChar == 34) return JSON.Value.from(deserializeString(srcStart, srcEnd, dst));
else if (firstChar == 123) return JSON.Value.from(deserializeObject(srcStart, srcEnd, dst));
else if (firstChar - 48 <= 9 || firstChar == 45) return JSON.Value.from(deserializeFloat<f64>(srcStart, srcEnd));
else if (firstChar == 91) {
return JSON.Value.from(deserializeArray<JSON.Value[]>(srcStart, srcEnd, dst));
} else if (firstChar == 116 || firstChar == 102) return JSON.Value.from(deserializeBoolean(srcStart, srcEnd));
return unreachable();
}
18 changes: 12 additions & 6 deletions assembly/deserialize/simple/array.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { JSON } from "../..";
import { deserializeArbitraryArray } from "./array/arbitrary";
import { deserializeArrayArray } from "./array/array";
import { deserializeBooleanArray } from "./array/bool";
import { deserializeFloatArray } from "./array/float";
Expand All @@ -20,17 +22,21 @@ export function deserializeArray<T extends unknown[]>(srcStart: usize, srcEnd: u
// @ts-ignore
return deserializeFloatArray<T>(srcStart, srcEnd, dst);
} else if (isArrayLike<valueof<T>>()) {
// @ts-ignore
// @ts-ignore: type
return deserializeArrayArray<T>(srcStart, srcEnd, dst);
} else if (isMap<valueof<T>>()) {
return deserializeMapArray<T>(srcStart, srcEnd, dst);
} else if (isManaged<valueof<T>>() || isReference<valueof<T>>()) {
const type = changetype<nonnull<valueof<T>>>(0);
// @ts-ignore
if (isDefined(type.__DESERIALIZE)) {
if (type instanceof JSON.Value) {
// @ts-ignore: type
return deserializeArbitraryArray(srcStart, srcEnd, dst);
} else if (type instanceof Map) {
// @ts-ignore: type
return deserializeMapArray<T>(srcStart, srcEnd, dst);
// @ts-ignore: defined by transform
} else if (isDefined(type.__DESERIALIZE)) {
return deserializeObjectArray<T>(srcStart, srcEnd, dst);
}
throw new Error("Could not parse array of type " + nameof<T>() + "! Make sure to add the @json decorator over classes!");
throw new Error("Could not parse array of type " + nameof<T>() + "!");
} else {
throw new Error("Could not parse array of type " + nameof<T>() + "!");
}
Expand Down
113 changes: 113 additions & 0 deletions assembly/deserialize/simple/array/arbitrary.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { BACK_SLASH, BRACE_LEFT, BRACE_RIGHT, BRACKET_LEFT, BRACKET_RIGHT, CHAR_F, CHAR_N, CHAR_T, COMMA, QUOTE } from "../../../custom/chars";
import { JSON } from "../../../";
import { isSpace } from "util/string";
import { ptrToStr } from "../../../util/ptrToStr";

export function deserializeArbitraryArray(srcStart: usize, srcEnd: usize, dst: usize): JSON.Value[] {
const out: JSON.Value[] = [];
let lastIndex: usize = 0;
let depth: u32 = 0;
while (srcStart < srcEnd) {
const code = load<u16>(srcStart);
if (code == QUOTE) {
lastIndex = srcStart;
srcStart += 2;
while (srcStart < srcEnd) {
const code = load<u16>(srcStart);
if (code == QUOTE && load<u16>(srcStart - 2) !== BACK_SLASH) {
while (isSpace(load<u16>((srcStart += 2)))) {
/* empty */
}
console.log("Value (string): " + ptrToStr(lastIndex, srcStart));
// @ts-ignore: exists
out.push(JSON.__deserialize<valueof<T>>(lastIndex, srcStart));
break;
}
srcStart += 2;
}
} else if (code - 48 <= 9 || code == 45) {
lastIndex = srcStart;
srcStart += 2;
while (srcStart < srcEnd) {
const code = load<u16>(srcStart);
if (code == COMMA || code == BRACE_RIGHT || isSpace(code)) {
// @ts-ignore: type
out.push(JSON.__deserialize<valueof<T>>(lastIndex, srcStart));
console.log("Value (number): " + ptrToStr(lastIndex, srcStart));
while (isSpace(load<u16>((srcStart += 2)))) {
/* empty */
}
break;
}
srcStart += 2;
}
} else if (code == BRACE_LEFT) {
lastIndex = srcStart;
depth++;
srcStart += 2;
while (srcStart < srcEnd) {
const code = load<u16>(srcStart);
if (code == BRACE_RIGHT) {
if (--depth == 0) {
// @ts-ignore: type
out.push(JSON.__deserialize<valueof<T>>(lastIndex, srcStart));
console.log("Value (object): " + ptrToStr(lastIndex, srcStart));
while (isSpace(load<u16>((srcStart += 2)))) {
/* empty */
}
break;
}
} else if (code == BRACE_LEFT) depth++;
srcStart += 2;
}
} else if (code == BRACKET_LEFT) {
lastIndex = srcStart;
depth++;
srcStart += 2;
while (srcStart < srcEnd) {
const code = load<u16>(srcStart);
if (code == BRACKET_RIGHT) {
if (--depth == 0) {
// @ts-ignore: type
out.push(JSON.__deserialize<valueof<T>>(lastIndex, srcStart));
console.log("Value (array): " + ptrToStr(lastIndex, srcStart));
while (isSpace(load<u16>((srcStart += 2)))) {
/* empty */
}
break;
}
} else if (code == BRACKET_LEFT) depth++;
srcStart += 2;
}
} else if (code == CHAR_T) {
if (load<u64>(srcStart) == 28429475166421108) {
// @ts-ignore: type
out.push(JSON.__deserialize<valueof<T>>(lastIndex, srcStart += 8));
console.log("Value (bool): " + ptrToStr(srcStart - 8, srcStart));
while (isSpace(load<u16>((srcStart += 2)))) {
/* empty */
}
}
} else if (code == CHAR_F) {
if (load<u64>(srcStart, 2) == 28429466576093281) {
// @ts-ignore: type
out.push(JSON.__deserialize<valueof<T>>(lastIndex, srcStart += 10));
console.log("Value (bool): " + ptrToStr(srcStart - 10, srcStart));
while (isSpace(load<u16>((srcStart += 2)))) {
/* empty */
}
}
} else if (code == CHAR_N) {
if (load<u64>(srcStart) == 30399761348886638) {
// @ts-ignore: type
out.push(JSON.__deserialize<valueof<T>>(lastIndex, srcStart += 8));
console.log("Value (null): " + ptrToStr(srcStart - 8, srcStart));
while (isSpace(load<u16>((srcStart += 2)))) {
/* empty */
}
}
}
srcStart += 2;
}
return out;
}
24 changes: 22 additions & 2 deletions assembly/deserialize/simple/object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export function deserializeObject<T>(srcStart: usize, srcEnd: usize, dst: usize)
srcStart += 2;
while (srcStart < srcEnd) {
const code = load<u16>(srcStart);
if (((code ^ BRACE_RIGHT) | (code ^ BRACKET_RIGHT)) == 32) {
if (code == BRACE_RIGHT) {
if (--depth == 0) {
// @ts-ignore: exists
out.__DESERIALIZE(keyStart, keyEnd, lastIndex, srcStart, dst);
Expand All @@ -87,7 +87,27 @@ export function deserializeObject<T>(srcStart: usize, srcEnd: usize, dst: usize)
}
break;
}
} else if (((code ^ BRACE_LEFT) | (code ^ BRACKET_LEFT)) == 220) depth++;
} else if (code == BRACE_LEFT) depth++;
srcStart += 2;
}
} else if (code == BRACKET_LEFT) {
lastIndex = srcStart;
depth++;
srcStart += 2;
while (srcStart < srcEnd) {
const code = load<u16>(srcStart);
if (code == BRACKET_RIGHT) {
if (--depth == 0) {
// @ts-ignore: exists
out.__DESERIALIZE(keyStart, keyEnd, lastIndex, srcStart, dst);
console.log("Value (array): " + ptrToStr(lastIndex, srcStart));
keyStart = 0;
while (isSpace(load<u16>((srcStart += 2)))) {
/* empty */
}
break;
}
} else if (code == BRACKET_LEFT) depth++;
srcStart += 2;
}
} else if (code == CHAR_T) {
Expand Down
16 changes: 11 additions & 5 deletions assembly/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,18 @@ import { deserializeObject } from "./deserialize/simple/object";
import { bytes } from "./util";
@json
class Vec3 {
x: i16 = 1
y: i16 = 2;
z: i16 = 3;
x: i16 = 1;
yy: i16 = 2;
zzz: i16 = 3;
xxxx: i16 = 4;
yyyyy: i16 = 5;
zzzzzz: i16 = 6;
xxxxxxx: i16 = 7;
yyyyyyyy: i16 = 8;
zzzzzzzzz: i16 = 9;
}

const serialized = JSON.stringify(new Vec3());
let serialized = JSON.stringify(new Vec3());
console.log("Serialized: " + serialized);
const deserialized = deserializeObject<Vec3>(changetype<usize>(serialized), changetype<usize>(serialized) + bytes(serialized), changetype<usize>(new Vec3()));
let deserialized = deserializeObject<Vec3>(changetype<usize>(serialized), changetype<usize>(serialized) + bytes(serialized), changetype<usize>(new Vec3()));
console.log("Deserialized: " + JSON.stringify(deserialized));
92 changes: 80 additions & 12 deletions transform/lib/index.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion transform/lib/index.js.map

Large diffs are not rendered by default.

Loading

0 comments on commit f023966

Please sign in to comment.