Skip to content

Commit 6e0743c

Browse files
authored
Feature ASCII encoding and decoding (#27)
* start implementation * fix operator grouping, now to optimize * remove lookup table, switch to simple bitwise * mask with shorter literal, remove explicit cast * add decorator
1 parent d3ac890 commit 6e0743c

File tree

3 files changed

+54
-0
lines changed

3 files changed

+54
-0
lines changed

assembly/buffer/index.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,34 @@ export class Buffer extends Uint8Array {
287287
}
288288

289289
export namespace Buffer {
290+
export namespace ASCII {
291+
export function encode(str: string): ArrayBuffer {
292+
let length = str.length;
293+
let output = __alloc(length, idof<ArrayBuffer>());
294+
for (let i = 0; i < length; i++) {
295+
let char = load<u16>(changetype<usize>(str) + <usize>(i << 1));
296+
store<u8>(output + <usize>i, char & 0x7F);
297+
}
298+
return changetype<ArrayBuffer>(output);
299+
}
300+
301+
export function decode(buffer: ArrayBuffer): String {
302+
return decodeUnsafe(changetype<usize>(buffer), buffer.byteLength);
303+
}
304+
305+
// @ts-ignore: decorator
306+
@unsafe export function decodeUnsafe(pointer: usize, length: i32): String {
307+
let result = __alloc(<usize>length << 1, idof<string>());
308+
309+
for (let i = 0; i < length; i++) {
310+
let byte = load<u8>(pointer + <usize>i);
311+
store<u16>(result + <usize>(i << 1), byte & 0x7F);
312+
}
313+
314+
return changetype<String>(result);
315+
}
316+
}
317+
290318
export namespace HEX {
291319
/** Calculates the byte length of the specified string when encoded as HEX. */
292320
export function byteLength(str: string): i32 {
@@ -358,6 +386,7 @@ export namespace Buffer {
358386
}
359387

360388
/** Decodes a chunk of memory to a utf16le encoded string in hex format. */
389+
// @ts-ignore: decorator
361390
@unsafe export function decodeUnsafe(ptr: usize, length: i32): string {
362391
let stringByteLength = length << 2; // length * (2 bytes per char) * (2 chars per input byte)
363392
let result = __alloc(stringByteLength, idof<String>());
@@ -374,6 +403,7 @@ export namespace Buffer {
374403
}
375404

376405
/** Calculates the two char combination from the byte. */
406+
// @ts-ignore: decorator
377407
@inline function charsFromByte(byte: u32): u32 {
378408
let hi = (byte >>> 4) & 0xF;
379409
let lo = byte & 0xF;

assembly/node.d.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ declare class Buffer extends Uint8Array {
8686
}
8787

8888
declare namespace Buffer {
89+
/** The HEX encoding and decoding namespace. */
8990
export namespace HEX {
9091
/** Creates an ArrayBuffer from a given string that is encoded in the hex format. */
9192
export function encode(str: string): ArrayBuffer;
@@ -94,4 +95,13 @@ declare namespace Buffer {
9495
/** Decodes a chunk of memory to a utf16le encoded string in hex format. */
9596
export function decodeUnsafe(ptr: usize, byteLength: i32): string;
9697
}
98+
/** The ASCII encoding and decoding namespace. */
99+
export namespace ASCII {
100+
/** Creates an ArrayBuffer from a given string that is encoded in the ASCII format. */
101+
export function encode(str: string): ArrayBuffer;
102+
/** Creates a string from a given ArrayBuffer that is decoded into ASCII format. */
103+
export function decode(buffer: ArrayBuffer): string;
104+
/** Decodes a chunk of memory to a utf16le encoded string in ASCII format. */
105+
export function decodeUnsafe(ptr: usize, byteLength: i32): string;
106+
}
97107
}

tests/buffer.spec.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,4 +550,18 @@ describe("buffer", () => {
550550
let decoded = Buffer.HEX.decode(exampleBuffer.buffer);
551551
expect(decoded).toStrictEqual(expected);
552552
});
553+
554+
test("#ASCII.encode", () => {
555+
let actual = "D34dB3eF";
556+
let exampleBuffer = create<Buffer>([0x44, 0x33, 0x34, 0x64, 0x42, 0x33, 0x65, 0x46]);
557+
let encoded = Buffer.ASCII.encode(actual);
558+
expect(encoded).toStrictEqual(exampleBuffer.buffer);
559+
});
560+
561+
test("#ASCII.decode", () => {
562+
let expected = create<Buffer>([0x44, 0x33, 0x34, 0x64, 0x42, 0x33, 0x65, 0x46]);
563+
let example = "D34dB3eF";
564+
let encoded = Buffer.ASCII.decode(expected.buffer);
565+
expect(encoded).toStrictEqual(example);
566+
});
553567
});

0 commit comments

Comments
 (0)