diff --git a/assembly/deserialize/array/array.ts b/assembly/deserialize/array/array.ts new file mode 100644 index 0000000..d8b33ec --- /dev/null +++ b/assembly/deserialize/array/array.ts @@ -0,0 +1,13 @@ +import { fCode, tCode } from "../../src/chars"; +import { unsafeCharCodeAt } from "../../src/util"; + +/** + * Deserialize a string to type array + * @param data data to parse + * @returns boolean + */ +// @ts-ignore: Decorator +@inline export function deserializeArray(data: string, start: i32 = 0, end = data.length): T { + if (start - end < 3) return instantiate(); + +} \ No newline at end of file diff --git a/assembly/deserialize/array/boolean.ts b/assembly/deserialize/array/boolean.ts new file mode 100644 index 0000000..176553d --- /dev/null +++ b/assembly/deserialize/array/boolean.ts @@ -0,0 +1,19 @@ +import { eCode, fCode, tCode } from "../../src/chars"; +import { unsafeCharCodeAt } from "../../src/util"; +import { deserializeBoolean } from "../boolean"; + +// @ts-ignore: Decorator +@inline export function deserializeooleanArray(data: string): T { + const result = instantiate(); + let lastPos = 1; + for (let i = 1; i < data.length - 1; i++) { + const char = unsafeCharCodeAt(data, i); + if (char === tCode || char === fCode) { + lastPos = i; + } else if (char === eCode) { + i++; + result.push(deserializeBoolean(data, lastPos, i)); + } + } + return result; + } \ No newline at end of file diff --git a/assembly/deserialize/array/string.ts b/assembly/deserialize/array/string.ts new file mode 100644 index 0000000..54a2c52 --- /dev/null +++ b/assembly/deserialize/array/string.ts @@ -0,0 +1,29 @@ +import { backSlashCode, quoteCode } from "../../src/chars"; +import { unsafeCharCodeAt } from "../../src/util"; +import { deserializeString } from "../string"; + +// @ts-ignore: Decorator +@inline export function deserializeStringArray(data: string): string[] { + const result: string[] = []; + let lastPos = 0; + let instr = false; + let escaping = false;v + for (let i = 1; i < data.length - 1; i++) { + const char = unsafeCharCodeAt(data, i); + if (char === backSlashCode && !escaping) { + escaping = true; + } else { + if (char === quoteCode && !escaping) { + if (instr === false) { + instr = true; + lastPos = i; + } else { + instr = false; + result.push(deserializeString(data, lastPos, i)); + } + } + escaping = false; + } + } + return result; +} \ No newline at end of file diff --git a/assembly/deserialize/boolean.ts b/assembly/deserialize/boolean.ts index 24bb7c8..5d17b53 100644 --- a/assembly/deserialize/boolean.ts +++ b/assembly/deserialize/boolean.ts @@ -7,9 +7,12 @@ import { unsafeCharCodeAt } from "../src/util"; * @returns boolean */ // @ts-ignore: Decorator -@inline export function deserializeBoolean(data: string): boolean { - const firstChar = unsafeCharCodeAt(data, 0); - if (data.length === 4 && firstChar === tCode && load(changetype(data)) === 28429475166421108) return true; - else if (data.length === 5 && firstChar === fCode && load(changetype(data), 2) === 28429466576093281) return false; +@inline export function deserializeBoolean(data: string, start: i32 = 0, end: i32 = 0): boolean { + if (!end) end = data.length; + const len = end - start; + const ptr = changetype(data) + (start << 1); + const firstChar = unsafeCharCodeAt(data, start); + if (len === 4 && firstChar === tCode && load(ptr) === 28429475166421108) return true; + else if (len === 5 && firstChar === fCode && load(ptr, 2) === 28429466576093281) return false; return false//ERROR(`Expected to find boolean, but found "${data.slice(0, 100)}" instead!`); } \ No newline at end of file diff --git a/assembly/deserialize/string.ts b/assembly/deserialize/string.ts index 04d53f4..0439b3f 100644 --- a/assembly/deserialize/string.ts +++ b/assembly/deserialize/string.ts @@ -1,12 +1,27 @@ -import { StringSink } from "as-string-sink/assembly"; +import { __atoi_fast } from "../src/util"; import { unsafeCharCodeAt } from "../src/util"; -import { bCode, backSlashCode, backspaceCode, carriageReturnCode, fCode, formFeedCode, forwardSlashCode, nCode, newLineCode, quoteCode, rCode, tCode, tabCode, uCode } from "../src/chars"; -import { Product, ProductValue } from "../product"; +import { + bCode, + fCode, + nCode, + uCode, + rCode, + tCode, + tabCode, + quoteCode, + newLineCode, + formFeedCode, + backSlashCode, + backspaceCode, + forwardSlashCode, + carriageReturnCode +} from "../src/chars"; +import { Sink } from "../src/sink"; // @ts-ignore: Decorator @inline export function deserializeString(data: string, start: i32 = 0, end: i32 = 0): string { end = end || data.length - 1; - let result = StringSink.withCapacity(end - start - 1); + let result = Sink.withCapacity(end - start - 1); const firstChar = unsafeCharCodeAt(data, start); const lastChar = unsafeCharCodeAt(data, end); if (firstChar !== quoteCode || lastChar !== quoteCode) { @@ -76,80 +91,4 @@ import { Product, ProductValue } from "../product"; result.write(data, last, end); } return result.toString(); -} - - -// @ts-ignore: Decorator -@inline export function _deserializeString(data: string, start: i32 = 0, end: i32 = 0): string { - end = end || data.length - 1; - let result = StringSink.withCapacity(end - start - 1); - const firstChar = unsafeCharCodeAt(data, start); - const lastChar = unsafeCharCodeAt(data, end); - if (firstChar !== quoteCode || lastChar !== quoteCode) { - abort(`Expected string to start and end with ", but got ${data.slice(0, 100)} instead!`); - } - let last = start + 1; - for (let i = last; i < end; i++) { - if (unsafeCharCodeAt(data, i) !== backSlashCode) { - continue; - } - const char = unsafeCharCodeAt(data, ++i); - result.write(data, last, i - 1); - switch (char) { - case quoteCode: { - result.writeCodePoint(quoteCode); - last = i + 1; - break; - } - case backSlashCode: { - result.writeCodePoint(backSlashCode); - last = i + 1; - break; - } - case forwardSlashCode: { - result.writeCodePoint(forwardSlashCode); - last = i + 1; - break; - } - case bCode: { - result.writeCodePoint(backspaceCode); - last = i + 1; - break; - } - case fCode: { - result.writeCodePoint(formFeedCode); - last = i + 1; - break; - } - case nCode: { - result.writeCodePoint(newLineCode); - last = i + 1; - break; - } - case rCode: { - result.writeCodePoint(carriageReturnCode); - last = i + 1; - break; - } - case tCode: { - result.writeCodePoint(tabCode); - last = i + 1; - break; - } - case uCode: { - const code = u16.parse(data.slice(i + 1, i + 5), 16); - result.writeCodePoint(code); - i += 4; - last = i + 1; - break; - } - default: { - abort(`Cannot parse "${data.slice(0, 100)}" as string. Invalid escape sequence: \\${data.charAt(i)}`); - } - } - } - if (end > last) { - result.write(data, last, end); - } - return result.toString(); } \ No newline at end of file diff --git a/assembly/src/sink.ts b/assembly/src/sink.ts index c912929..921fe4a 100644 --- a/assembly/src/sink.ts +++ b/assembly/src/sink.ts @@ -158,6 +158,18 @@ export class Sink { return this; } + @inline writeCodePoint16(code: i32): Sink { + this.ensureCapacity(2); + + let offset = this.offset; + let dest = changetype(this.buffer) + offset; + + store(dest, code); + this.offset = offset + 2; + + return this; + } + @inline writeCodePointUnsafe(code: i32): Sink { this.ensureCapacity(2);