Skip to content

Feature ASCII encoding and decoding #27

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions assembly/buffer/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<ArrayBuffer>());
for (let i = 0; i < length; i++) {
let char = load<u16>(changetype<usize>(str) + <usize>(i << 1));
store<u8>(output + <usize>i, char & 0x7F);
}
return changetype<ArrayBuffer>(output);
}

export function decode(buffer: ArrayBuffer): String {
return decodeUnsafe(changetype<usize>(buffer), buffer.byteLength);
}

// @ts-ignore: decorator
@unsafe export function decodeUnsafe(pointer: usize, length: i32): String {
let result = __alloc(<usize>length << 1, idof<string>());

for (let i = 0; i < length; i++) {
let byte = load<u8>(pointer + <usize>i);
store<u16>(result + <usize>(i << 1), byte & 0x7F);
}

return changetype<String>(result);
}
}

export namespace HEX {
/** Calculates the byte length of the specified string when encoded as HEX. */
export function byteLength(str: string): i32 {
Expand Down Expand Up @@ -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<String>());
Expand All @@ -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;
Expand Down
10 changes: 10 additions & 0 deletions assembly/node.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}
}
14 changes: 14 additions & 0 deletions tests/buffer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<Buffer>([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<Buffer>([0x44, 0x33, 0x34, 0x64, 0x42, 0x33, 0x65, 0x46]);
let example = "D34dB3eF";
let encoded = Buffer.ASCII.decode(expected.buffer);
expect(encoded).toStrictEqual(example);
});
});