Skip to content

Instantly share code, notes, and snippets.

@RReverser
Created February 20, 2020 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RReverser/1547a1e0fdf1a661497d70a51b9e615c to your computer and use it in GitHub Desktop.
Save RReverser/1547a1e0fdf1a661497d70a51b9e615c to your computer and use it in GitHub Desktop.
const TEXT_ENCODER = new TextEncoder();
const WASM_PAGE_SIZE = 1 << 16;
function encodeStringToBinary(str) {
// Initially allocate enough space for the case where 1 char requires 1 byte (ASCII-only).
let dest = new WebAssembly.Memory({ initial: Math.ceil(str.length / WASM_PAGE_SIZE) });
let writePos = 0;
for (;;) {
// Write starting from the last written position.
let { read, written } = TEXT_ENCODER.encodeInto(str, new Uint8Array(dest.buffer, writePos));
// `read` is number of characters read from the string.
// Slice them away to update the string to the leftover:
str = str.slice(read);
// If we don't have anything left, leave the loop:
if (!str) break;
// `write` is a number of bytes written to the output buffer.
// First, update the write position:
writePos += written;
// Now, the only reason we are here is that there wasn't enough space in the output buffer.
// This is where growable WebAssembly.Memory comes in handy!
// Let's add one more page:
dest.grow(1);
}
// If we're here, it means we've finally processed the whole string.
// `writePos` contains the total number of bytes written, let's use it and return a view:
return new Uint8Array(dest.buffer, 0, writePos);
}
var hugeRandomString = Array.from({ length: 1 << 20 }, () => String.fromCodePoint(0 | Math.random() * 0x110000)).join();
console.log(encodeStringToBinary(hugeRandomString));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment