Spaces:
Sleeping
Sleeping
| /** | |
| * Protobuf wire format codec β zero-dependency, schema-less. | |
| * | |
| * Wire types: | |
| * 0 = Varint (int32, uint64, bool, enum) | |
| * 1 = Fixed64 (double, fixed64) | |
| * 2 = LenDelim (string, bytes, embedded messages) | |
| * 5 = Fixed32 (float, fixed32) | |
| */ | |
| // βββ Varint ββββββββββββββββββββββββββββββββββββββββββββββββ | |
| export function encodeVarint(value) { | |
| const bytes = []; | |
| let v = Number(value); | |
| if (v < 0) { | |
| const big = BigInt(v) & 0xFFFFFFFFFFFFFFFFn; | |
| let b = big; | |
| for (let i = 0; i < 10; i++) { | |
| bytes.push(Number(b & 0x7Fn) | (i < 9 ? 0x80 : 0)); | |
| b >>= 7n; | |
| } | |
| return Buffer.from(bytes); | |
| } | |
| do { | |
| let byte = v & 0x7F; | |
| v >>>= 7; | |
| if (v > 0) byte |= 0x80; | |
| bytes.push(byte); | |
| } while (v > 0); | |
| return Buffer.from(bytes); | |
| } | |
| export function decodeVarint(buf, offset = 0) { | |
| let result = 0, shift = 0, pos = offset; | |
| while (pos < buf.length) { | |
| const byte = buf[pos++]; | |
| result |= (byte & 0x7F) << shift; | |
| if (!(byte & 0x80)) break; | |
| shift += 7; | |
| if (shift >= 64) throw new Error('Varint overflow'); | |
| } | |
| return { value: result >>> 0, length: pos - offset }; | |
| } | |
| // βββ Field-level writers (standalone functions) ββββββββββββ | |
| function makeTag(field, wireType) { | |
| return encodeVarint((field << 3) | wireType); | |
| } | |
| /** Write a varint field (wire type 0). */ | |
| export function writeVarintField(field, value) { | |
| return Buffer.concat([makeTag(field, 0), encodeVarint(value)]); | |
| } | |
| /** Write a length-delimited string field (wire type 2). */ | |
| export function writeStringField(field, str) { | |
| if (!str && str !== '') return Buffer.alloc(0); | |
| const data = Buffer.from(str, 'utf-8'); | |
| return Buffer.concat([makeTag(field, 2), encodeVarint(data.length), data]); | |
| } | |
| /** Write a length-delimited bytes field (wire type 2). */ | |
| export function writeBytesField(field, data) { | |
| const buf = Buffer.isBuffer(data) ? data : Buffer.from(data); | |
| return Buffer.concat([makeTag(field, 2), encodeVarint(buf.length), buf]); | |
| } | |
| /** Write an embedded message field (wire type 2). */ | |
| export function writeMessageField(field, msgBuf) { | |
| if (!msgBuf || msgBuf.length === 0) return Buffer.alloc(0); | |
| return Buffer.concat([makeTag(field, 2), encodeVarint(msgBuf.length), msgBuf]); | |
| } | |
| /** Write a fixed64 field (wire type 1). */ | |
| export function writeFixed64Field(field, buf8) { | |
| return Buffer.concat([makeTag(field, 1), buf8]); | |
| } | |
| /** Write a bool field (wire type 0), only if true. */ | |
| export function writeBoolField(field, value) { | |
| if (!value) return Buffer.alloc(0); | |
| return writeVarintField(field, 1); | |
| } | |
| // βββ Parser ββββββββββββββββββββββββββββββββββββββββββββββββ | |
| /** | |
| * Parse a protobuf buffer into an array of { field, wireType, value }. | |
| * For varint (0): value is a Number. | |
| * For lendelim (2): value is a Buffer (caller decides string vs message). | |
| * For fixed64 (1): value is an 8-byte Buffer. | |
| * For fixed32 (5): value is a 4-byte Buffer. | |
| */ | |
| export function parseFields(buf) { | |
| const fields = []; | |
| let pos = 0; | |
| while (pos < buf.length) { | |
| const tag = decodeVarint(buf, pos); | |
| pos += tag.length; | |
| const fieldNum = tag.value >>> 3; | |
| const wireType = tag.value & 0x07; | |
| let value; | |
| switch (wireType) { | |
| case 0: { // varint | |
| const v = decodeVarint(buf, pos); | |
| pos += v.length; | |
| value = v.value; | |
| break; | |
| } | |
| case 1: { // fixed64 | |
| value = buf.subarray(pos, pos + 8); | |
| pos += 8; | |
| break; | |
| } | |
| case 2: { // length-delimited | |
| const len = decodeVarint(buf, pos); | |
| pos += len.length; | |
| value = buf.subarray(pos, pos + len.value); | |
| pos += len.value; | |
| break; | |
| } | |
| case 5: { // fixed32 | |
| value = buf.subarray(pos, pos + 4); | |
| pos += 4; | |
| break; | |
| } | |
| default: | |
| throw new Error(`Unknown wire type ${wireType} at offset ${pos}`); | |
| } | |
| fields.push({ field: fieldNum, wireType, value }); | |
| } | |
| return fields; | |
| } | |
| /** Get first field matching number and optional wire type. */ | |
| export function getField(fields, num, wireType) { | |
| return fields.find(f => f.field === num && (wireType === undefined || f.wireType === wireType)) || null; | |
| } | |
| /** Get all fields matching number. */ | |
| export function getAllFields(fields, num) { | |
| return fields.filter(f => f.field === num); | |
| } | |