first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,90 @@
# `@suaveplan/license` — codec/bitpack
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Bit-precise pack/unpack primitives used to serialise the 72-bit license
payload into 9 bytes. Plain `DataView` / typed-array slicing can only
write whole bytes, so we walk the buffer bit-by-bit. Two thin classes
hold the cursor: `SimpleBitPacker` writes MSB-first, `SimpleBitUnpacker`
reads MSB-first. Both round-trip identically to upstream's
`@suaveplan/license` bitpacker.
## Features
- `packUint(value, bits)` — writes an unsigned integer in `[0, 2^bits)`
using `bits` bits; raises `LicenseError(LICENSE.PAYLOAD_OUT_OF_RANGE)`
when the value exceeds the declared width or is negative.
- `unpackUint(bits)` — reads the next `bits`-wide unsigned integer;
raises `LicenseError(LICENSE.MALFORMED)` when the read would underflow
the buffer.
- `getBytes()` / `getBitCount()` / `getBitPosition()` introspection
helpers used by the spec-conformance tests.
## Usage: Basic
```ts
import {
SimpleBitPacker,
SimpleBitUnpacker,
} from "@suaveplan/license/codec/bitpack/bitpack";
const p = new SimpleBitPacker();
p.packUint(2, 3); // 3-bit version
p.packUint(17, 5); // 5-bit signingKeyId
const bytes = p.getBytes();
const u = new SimpleBitUnpacker(bytes);
const version = u.unpackUint(3); // 2
const keyId = u.unpackUint(5); // 17
```
## Usage: Advanced
Round-tripping a full 72-bit payload:
```ts
import { FIELD_BITS } from "@suaveplan/license/constants/constants";
import {
SimpleBitPacker,
SimpleBitUnpacker,
} from "@suaveplan/license/codec/bitpack/bitpack";
const p = new SimpleBitPacker();
for (const [_field, bits] of Object.entries(FIELD_BITS)) {
p.packUint(0, bits);
}
const bytes = p.getBytes(); // 9 bytes
const u = new SimpleBitUnpacker(bytes);
for (const [_field, bits] of Object.entries(FIELD_BITS)) {
u.unpackUint(bits); // === 0
}
```
## API Reference
### `class SimpleBitPacker`
- `packUint(value: number, bits: number): void` — write an unsigned
integer; throws on overflow / negative.
- `getBytes(): Uint8Array` — snapshot the packed bytes.
- `getBitCount(): number` — total bits written.
### `class SimpleBitUnpacker`
- `constructor(buffer: Uint8Array)` — wrap a byte buffer.
- `unpackUint(bits: number): number` — read the next integer; throws
`MALFORMED` on underflow.
- `getBitPosition(): number` — current read cursor.
## Implementation Notes
The packer grows its internal `number[]` buffer one byte at a time
because the upstream layout is small (9 bytes) and pre-sizing would
require knowing the total bit count in advance. The `1 << bits` overflow
check is safe for the bit widths used by the license schema (≤19 bits);
for wider integers, callers should use a dedicated bigint bitpacker.