Skip to content

Commit

Permalink
README: Improve frozen netstring example (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
gibson042 authored Oct 6, 2024
1 parent 518e86a commit 5bcc6d2
Showing 1 changed file with 25 additions and 20 deletions.
45 changes: 25 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,26 +57,31 @@ The ArrayBuffer `slice` method and TypedArray methods that create new ArrayBuffe
### Represent arbitrary binary data as an immutable [netstring](https://en.wikipedia.org/wiki/Netstring)

```js
// Read data from base64 input and calculate its length.
const data = Uint8Array.fromBase64(inputBase64);
const dataLen = data.length;
const dataLenStr = String(dataLen);
const digitCount = dataLenStr.length;

// Transfer to a new ArrayBuffer with room for the netstring framing.
const tmpBuf = data.buffer.transfer(digitCount + 1 + dataLen + 1);
const tmpArr = new Uint8Array(tmpBuf);
assert(tmpArr.buffer === tmpBuf);

// Frame the data.
tmpArr.copyWithin(digitCount + 1, 0);
for (let i = 0; i < digitCount; i++) tmpArr[i] = dataLenStr.charCodeAt(i);
tmpArr[digitCount] = 0x3A;
tmpArr[tmpArr.length - 1] = 0x2C;

// Transfer to an immutable ArrayBuffer backing a frozen Uint8Array.
const netstringArr = Object.freeze(new Uint8Array(tmpBuf.transferToImmutable()));
assert(tmpBuf.detached);
const consumeIntoNetstring = data => {
// Transfer to a new ArrayBuffer with room for the netstring framing.
// https://en.wikipedia.org/wiki/Netstring
const prefix = new TextEncoder().encode(`${data.length}:`);
const buf = data.buffer.transfer(prefix.length + data.length + 1);

// Frame the data.
const tmpArr = new Uint8Array(buf);
tmpArr.copyWithin(prefix.length, 0);
tmpArr.set(prefix);
tmpArr[tmpArr.length - 1] = 0x2C;

// Transfer to an immutable ArrayBuffer backing a frozen Uint8Array.
const frozenNetstring = Object.freeze(new Uint8Array(buf.transferToImmutable()));
assert(buf.detached);
return frozenNetstring;
};

const input = new TextEncoder().encode('hello world!');
const result = consumeIntoNetstring(input);
assert(Object.isFrozen(result));
try { result[0] = 0; } catch (_err) {}
try { new Uint8Array(result.buffer)[0] = 1; } catch (_err) {}
try { result.buffer.transferToImmutable(); } catch (_err) {}
assert(String.fromCharCode(...result) === '12:hello world!,');
```

## Implementations
Expand Down

0 comments on commit 5bcc6d2

Please sign in to comment.