diff --git a/assembly/buffer/index.ts b/assembly/buffer/index.ts index 1c5a832..627a273 100644 --- a/assembly/buffer/index.ts +++ b/assembly/buffer/index.ts @@ -287,6 +287,34 @@ export class Buffer extends Uint8Array { } export namespace Buffer { + export namespace ASCII { + export function encode(str: string): ArrayBuffer { + let length = str.length; + let output = __alloc(length, idof()); + for (let i = 0; i < length; i++) { + let char = load(changetype(str) + (i << 1)); + store(output + i, char & 0x7F); + } + return changetype(output); + } + + export function decode(buffer: ArrayBuffer): String { + return decodeUnsafe(changetype(buffer), buffer.byteLength); + } + + // @ts-ignore: decorator + @unsafe export function decodeUnsafe(pointer: usize, length: i32): String { + let result = __alloc(length << 1, idof()); + + for (let i = 0; i < length; i++) { + let byte = load(pointer + i); + store(result + (i << 1), byte & 0x7F); + } + + return changetype(result); + } + } + export namespace HEX { /** Calculates the byte length of the specified string when encoded as HEX. */ export function byteLength(str: string): i32 { @@ -358,6 +386,7 @@ export namespace Buffer { } /** Decodes a chunk of memory to a utf16le encoded string in hex format. */ + // @ts-ignore: decorator @unsafe export function decodeUnsafe(ptr: usize, length: i32): string { let stringByteLength = length << 2; // length * (2 bytes per char) * (2 chars per input byte) let result = __alloc(stringByteLength, idof()); @@ -374,6 +403,7 @@ export namespace Buffer { } /** Calculates the two char combination from the byte. */ + // @ts-ignore: decorator @inline function charsFromByte(byte: u32): u32 { let hi = (byte >>> 4) & 0xF; let lo = byte & 0xF; diff --git a/assembly/node.d.ts b/assembly/node.d.ts index 419384a..a276e60 100644 --- a/assembly/node.d.ts +++ b/assembly/node.d.ts @@ -86,6 +86,7 @@ declare class Buffer extends Uint8Array { } declare namespace Buffer { + /** The HEX encoding and decoding namespace. */ export namespace HEX { /** Creates an ArrayBuffer from a given string that is encoded in the hex format. */ export function encode(str: string): ArrayBuffer; @@ -94,4 +95,13 @@ declare namespace Buffer { /** Decodes a chunk of memory to a utf16le encoded string in hex format. */ export function decodeUnsafe(ptr: usize, byteLength: i32): string; } + /** The ASCII encoding and decoding namespace. */ + export namespace ASCII { + /** Creates an ArrayBuffer from a given string that is encoded in the ASCII format. */ + export function encode(str: string): ArrayBuffer; + /** Creates a string from a given ArrayBuffer that is decoded into ASCII format. */ + export function decode(buffer: ArrayBuffer): string; + /** Decodes a chunk of memory to a utf16le encoded string in ASCII format. */ + export function decodeUnsafe(ptr: usize, byteLength: i32): string; + } } diff --git a/tests/buffer.spec.ts b/tests/buffer.spec.ts index b7681a4..dcd4177 100644 --- a/tests/buffer.spec.ts +++ b/tests/buffer.spec.ts @@ -550,4 +550,18 @@ describe("buffer", () => { let decoded = Buffer.HEX.decode(exampleBuffer.buffer); expect(decoded).toStrictEqual(expected); }); + + test("#ASCII.encode", () => { + let actual = "D34dB3eF"; + let exampleBuffer = create([0x44, 0x33, 0x34, 0x64, 0x42, 0x33, 0x65, 0x46]); + let encoded = Buffer.ASCII.encode(actual); + expect(encoded).toStrictEqual(exampleBuffer.buffer); + }); + + test("#ASCII.decode", () => { + let expected = create([0x44, 0x33, 0x34, 0x64, 0x42, 0x33, 0x65, 0x46]); + let example = "D34dB3eF"; + let encoded = Buffer.ASCII.decode(expected.buffer); + expect(encoded).toStrictEqual(example); + }); });