diff --git a/assembly/deserialize/number.ts b/assembly/deserialize/number.ts index 62ce244..1dd8b53 100644 --- a/assembly/deserialize/number.ts +++ b/assembly/deserialize/number.ts @@ -3,10 +3,9 @@ import { snip_fast } from "../src/util"; // @ts-ignore: Decorator @inline export function deserializeNumber(data: string, start: i32 = 0, end: i32 = 0): T { - end = end || data.length - 1; if (isInteger()) { // @ts-ignore - return snip_fast(data.slice(start, end)); + return snip_fast(data, start, end || data.length << 1); } // @ts-ignore const type: T = 0; diff --git a/assembly/deserialize/string.ts b/assembly/deserialize/string.ts index 90f2535..a23c047 100644 --- a/assembly/deserialize/string.ts +++ b/assembly/deserialize/string.ts @@ -24,14 +24,15 @@ import { Sink } from "../src/sink"; let result = Sink.withCapacity(end - start - 1); const firstChar = unsafeCharCodeAt(data, start); const lastChar = unsafeCharCodeAt(data, end); + if (firstChar !== quoteCode || lastChar !== quoteCode) { throw new Error(`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; - } + if (unsafeCharCodeAt(data, i) !== backSlashCode) continue; + const char = unsafeCharCodeAt(data, ++i); result.write(data, last, i - 1); switch (char) { @@ -87,8 +88,10 @@ import { Sink } from "../src/sink"; } } } + if (end > last) { result.write(data, last, end); } + return result.toString(); } \ No newline at end of file diff --git a/assembly/deserialize/unknown.ts b/assembly/deserialize/unknown.ts index e4ea6ed..be8f794 100644 --- a/assembly/deserialize/unknown.ts +++ b/assembly/deserialize/unknown.ts @@ -26,7 +26,7 @@ import { deserializeString } from "./string"; return Result.Ok(JSON.Value.from(true)); } else if ( firstChar === fCode - && load(changetype(data), 2) === 28429466576093281 // "alse" + && load(changetype(data), 2) === 28429466576093281 // "false" ) { return Result.Ok(JSON.Value.from(false)); } diff --git a/assembly/src/util.ts b/assembly/src/util.ts index dd3ed56..607f0a0 100644 --- a/assembly/src/util.ts +++ b/assembly/src/util.ts @@ -88,15 +88,15 @@ import { Product } from "../product"; * @param str - Any number. Can include scientific notation. */ // @ts-ignore: Decorator -@inline export function snip_fast(str: string, len: u32 = 0, offset: u32 = 0): T { +@inline export function snip_fast(str: string, start: u32 = 0, end: u32 = str.length << 1): T { + let val: T = 0 as T; + const len: u32 = end - start; if (isSigned()) { const firstChar: u32 = load(changetype(str)); if (firstChar === 48) return 0 as T; const isNegative = firstChar === 45; // Check if the number is negative - let val: T = 0 as T; - if (len == 0) len = u32(str.length << 1); if (isNegative) { - offset += 2; + let offset: u32 = 2; if (len >= 4) { // 32-bit route for (; offset < (len - 3); offset += 4) { @@ -146,6 +146,7 @@ import { Product } from "../product"; } return -val as T; } else { + let offset: u32 = 0; if (len >= 4) { // Duplet 16 bit lane load for (; offset < (len - 3); offset += 4) { @@ -198,7 +199,7 @@ import { Product } from "../product"; const firstChar: u32 = load(changetype(str)); if (firstChar === 48) return 0 as T; let val: T = 0 as T; - if (len == 0) len = u32(str.length << 1); + let offset: u32 = 0; if (len >= 4) { // Duplet 16 bit lane load for (; offset < (len - 3); offset += 4) { diff --git a/assembly/test.ts b/assembly/test.ts index 473d514..9a03359 100644 --- a/assembly/test.ts +++ b/assembly/test.ts @@ -3,10 +3,12 @@ import { deserializeArray } from "./deserialize/array/array"; import { deserializeBooleanArray } from "./deserialize/array/boolean"; import { deserializeNumberArray } from "./deserialize/array/number"; import { deserializeStringArray } from "./deserialize/array/string"; +import { deserializeNumber } from "./deserialize/number"; import { utoa32 } from "./serialize/integer"; import { Sink } from "./src/sink"; import { describe, expect } from "as-test/assembly"; -/* +import { __atoi_fast } from "./src/util"; + describe("Serialize String", () => { expect(JSON.serialize("hello world").toString()).toBe("\"hello world\""); }); @@ -128,7 +130,11 @@ map.set("z", JSON.Value.from(-5.6)); describe("Serialize Maps", () => { expect(JSON.serialize(map).toString()).toBe("{\"x\":3.4,\"y\":1.2,\"z\":-5.6}"); }); -*/ + +describe("Deserialize Number", () => { + expect(JSON.serialize(deserializeNumber("1234e3")).toString()).toBe("1234000"); +}) +/* describe("Deserialize String[]", () => { expect(JSON.serialize(deserializeStringArray("[\"hello\",\"world\"]")).toString()).toBe("[\"hello\",\"world\"]"); @@ -144,4 +150,4 @@ describe("Deserialize Boolean[]", () => { describe("Deserialize [][]", () => { deserializeArray("[[[]],[[[]]]]") -}); \ No newline at end of file +});*/ \ No newline at end of file