3.7 KiB
buffer-utils
(no submodules)
Purpose
Provides a compact set of pure binary-reading helpers that operate directly on Uint8Array values. These utilities abstract away the bit-shifting and byte-ordering arithmetic that every audio-format parser needs, reducing the risk of off-by-one errors and making parser code easier to read and test in isolation.
All helpers are environment-agnostic — they use only the Uint8Array and TextDecoder web-standard APIs, so they work identically in Node.js 18+, Deno, and modern browsers without any polyfills.
Features
- Unsigned/signed integer readers:
readUint8,readUint16BE,readUint16LE,readUint32BE,readUint32LE,readInt32BE - String decoder with
"utf8"(TextDecoder) and"latin1"(char-code loop) encodings readSyncsafeIntfor ID3v2 syncsafe 28-bit integersconcatBuffersfor building test fixtures and merging partial reads- Every function returns a sensible default (
0/"") on out-of-bounds access rather than throwing
Usage: Basic Example
import {
readUint32BE,
readString,
} from "@suaveplan/audio-metadata";
const buf = new Uint8Array([0x00, 0x00, 0x04, 0x00]);
const size = readUint32BE(buf, 0); // 1024
const text = new Uint8Array([0x48, 0x69]);
readString(text, 0, 2); // "Hi"
Usage: Advanced Example
import {
readSyncsafeInt,
readUint16BE,
concatBuffers,
} from "@suaveplan/audio-metadata";
// Decode an ID3v2 tag size from a header
const header = new Uint8Array([0x49, 0x44, 0x33, 0x03, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01]);
const tagSize = readSyncsafeInt(header, 6); // 257
// Build a larger test buffer by concatenating parts
const part1 = new Uint8Array([0x52, 0x49, 0x46, 0x46]);
const part2 = new Uint8Array([0x00, 0x10, 0x00, 0x00]);
const combined = concatBuffers(part1, part2); // "RIFF" + size bytes
API Reference
readUint8(buf, offset)
Returns buf[offset] as a number (0–255), or 0 if out of bounds.
readUint16BE(buf, offset)
Reads two bytes at offset as a big-endian unsigned 16-bit integer.
readUint16LE(buf, offset)
Reads two bytes at offset as a little-endian unsigned 16-bit integer.
readUint32BE(buf, offset)
Reads four bytes at offset as a big-endian unsigned 32-bit integer.
readUint32LE(buf, offset)
Reads four bytes at offset as a little-endian unsigned 32-bit integer.
readInt32BE(buf, offset)
Reads four bytes at offset as a big-endian signed 32-bit integer. Converts unsigned values ≥ 0x80000000 to their negative two's-complement equivalents.
readString(buf, offset, length, encoding?)
Decodes length bytes starting at offset.
encoding = "utf8"(default): usesTextDecoder("utf-8")for correct multi-byte handling.encoding = "latin1": maps each byte to its Unicode code point — necessary for ID3v1 and some legacy ID3v2 fields.
readSyncsafeInt(buf, offset)
Reads four bytes at offset and decodes them as an ID3v2 syncsafe integer (28-bit value, MSB of each byte ignored). Returns a plain number.
concatBuffers(a, b)
Returns a new Uint8Array containing all bytes of a followed by all bytes of b.
Implementation Notes
The >>> 0 cast after bit-shifting operations ensures the result is treated as an unsigned 32-bit integer in JavaScript, preventing sign-extension surprises with values whose MSB is set. The readUint32BE implementation uses multiplication by 0x1000000 instead of << 24 to avoid the signed-integer trap that << 24 introduces for bytes with the high bit set. Out-of-bounds array reads return undefined in JavaScript, which is coerced to 0 via the ?? 0 fallback — this trades silent safety for parser robustness with truncated buffers.