import { JSON } from "../.."; import { BACK_SLASH, COMMA, CHAR_F, BRACE_LEFT, BRACKET_LEFT, CHAR_N, QUOTE, BRACE_RIGHT, BRACKET_RIGHT, CHAR_T, COLON } from "../../custom/chars"; import { isSpace } from "../../util"; export function deserializeMap>(srcStart: usize, srcEnd: usize, dst: usize): T { const out = changetype(dst || __new(offsetof(), idof())); // @ts-ignore: type if (!isString>() && !isInteger>() && !isFloat>()) ERROR("Map key must also be a valid JSON key!"); const srcPtr = srcStart; let key: string | null = null; let isKey = false; let depth = 0; let lastIndex = 0; // while (srcStart < srcEnd && isSpace(load(srcStart))) srcStart += 2; // while (srcEnd > srcStart && isSpace(load(srcEnd))) srcEnd -= 2; while (srcStart < srcEnd) { let code = load(srcStart); // while (isSpace(code)) code = load(srcStart += 2); if (key == null) { if (code == QUOTE && load(srcStart - 2) !== BACK_SLASH) { if (isKey) { key = sliceTo(lastIndex, srcStart); while (isSpace((code = load((srcStart += 2))))) { /* empty */ } if (code !== COLON) throw new Error("Expected ':' after key at position " + (srcStart - srcPtr).toString()); isKey = false; } else { isKey = true; lastIndex = srcStart + 2; } } // isKey = !isKey; srcStart += 2; } else { // @ts-ignore: type if (isString>() && code == QUOTE) { lastIndex = srcStart; srcStart += 2; while (srcStart < srcEnd) { const code = load(srcStart); if (code == QUOTE && load(srcStart - 2) !== BACK_SLASH) { while (isSpace(load((srcStart += 2)))) { /* empty */ } // @ts-ignore: type out.set(key, JSON.__deserialize>(lastIndex, srcStart)); key = null; break; } srcStart += 2; } // @ts-ignore: type } else if ((!isBoolean>() && isInteger>() && code - 48 <= 9) || code == 45) { lastIndex = srcStart; srcStart += 2; while (srcStart < srcEnd) { const code = load(srcStart); if (code == COMMA || isSpace(code) || code == BRACE_RIGHT) { // @ts-ignore: type out.set(key, JSON.__deserialize>(lastIndex, srcStart)); while (isSpace(load((srcStart += 2)))) { /* empty */ } key = null; break; } srcStart += 2; } // @ts-ignore: type } else if (isArray>() && code == BRACKET_LEFT) { lastIndex = srcStart; depth++; srcStart += 2; while (srcStart < srcEnd) { const code = load(srcStart); if (((code ^ BRACE_RIGHT) | (code ^ BRACKET_RIGHT)) == 32) { if (--depth == 0) { // @ts-ignore: type out.set(key, JSON.__deserialize>(lastIndex, srcStart)); while (isSpace(load((srcStart += 2)))) { /* empty */ } key = null; break; } } else if (code == BRACKET_LEFT) depth++; srcStart += 2; } // @ts-ignore: type } else if (isDefined(changetype>>(0).__DESERIALIZE) && code == BRACE_LEFT) { lastIndex = srcStart; depth++; srcStart += 2; while (srcStart < srcEnd) { const code = load(srcStart); if (code == BRACE_RIGHT) { if (--depth == 0) { // @ts-ignore: type out.set(key, JSON.__deserialize>(lastIndex, srcStart)); while (isSpace(load((srcStart += 2)))) { /* empty */ } key = null; break; } } else if (code == BRACE_LEFT) depth++; srcStart += 2; } // @ts-ignore: type } else if (isBoolean>() && code == CHAR_T) { if (load(srcStart) == 28429475166421108) { // @ts-ignore: type out.set(key, JSON.__deserialize>(srcStart, (srcStart += 8))); while (isSpace(load((srcStart += 2)))) { /* empty */ } key = null; } // @ts-ignore: type } else if (isBoolean>() && code == CHAR_F) { if (load(srcStart, 2) == 28429466576093281) { // @ts-ignore: type out.set(key, JSON.__deserialize>(srcStart, (srcStart += 10))); while (isSpace(load((srcStart += 2)))) { /* empty */ } key = null; } } else if ((isNullable() || nameof() == "usize") && code == CHAR_N) { if (load(srcStart) == 30399761348886638) { // @ts-ignore: type out.set(key, JSON.__deserialize>(srcStart, (srcStart += 8))); while (isSpace(load((srcStart += 2)))) { /* empty */ } } } else { // @ts-ignore: type throw new Error("Unexpected character " + String.fromCharCode(code) + " or type " + nameof>() + " does not match found type!"); } } } return out; } function sliceTo(srcStart: usize, srcEnd: usize): string { const dstSize = srcEnd - srcStart; const dst = __new(dstSize, idof()); memory.copy(dst, srcStart, dstSize); return changetype(dst); }