W / src /proto.js
Ac66's picture
Upload folder using huggingface_hub
2b64d42 verified
/**
* 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 = [];
// BigInt path for negatives (two's-complement uint64) and any int > 2^31
// since JS `>>>` truncates to uint32 and silently corrupts larger varints.
if (typeof value === 'bigint' || value < 0 || value > 0x7FFFFFFF) {
let b = (typeof value === 'bigint' ? value : BigInt(value)) & 0xFFFFFFFFFFFFFFFFn;
while (true) {
const byte = Number(b & 0x7Fn);
b >>= 7n;
if (b === 0n) { bytes.push(byte); break; }
bytes.push(byte | 0x80);
}
return Buffer.from(bytes);
}
let v = Number(value);
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) {
// Fast path: read up to 4 bytes (28 bits) with plain int math β€” covers
// all field tags and most small ints without touching BigInt. Fall through
// to BigInt for anything larger so uint64 values (request_id, credit
// counters, timestamps) decode accurately without sign/truncation bugs.
let result = 0, shift = 0, pos = offset;
while (pos < buf.length && shift < 28) {
const byte = buf[pos++];
result |= (byte & 0x7F) << shift;
if (!(byte & 0x80)) return { value: result >>> 0, length: pos - offset };
shift += 7;
}
if (pos >= buf.length) throw new Error('Truncated varint');
// Continuation byte needed beyond 28 bits β€” switch to BigInt.
let big = BigInt(result >>> 0);
let bigShift = BigInt(shift);
while (pos < buf.length) {
const byte = buf[pos++];
big |= BigInt(byte & 0x7F) << bigShift;
if (!(byte & 0x80)) {
// Return Number if safely representable, else BigInt.
const asNum = Number(big);
return { value: Number.isSafeInteger(asNum) ? asNum : big, length: pos - offset };
}
bigShift += 7n;
if (bigShift >= 64n) throw new Error('Varint overflow');
}
throw new Error('Truncated varint');
}
// ─── 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 = Number(tag.value) >>> 3;
const wireType = Number(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
if (pos + 8 > buf.length) throw new Error(`truncated fixed64 at offset ${pos}`);
value = buf.subarray(pos, pos + 8);
pos += 8;
break;
}
case 2: { // length-delimited
const len = decodeVarint(buf, pos);
pos += len.length;
const sz = Number(len.value);
if (sz < 0 || pos + sz > buf.length) {
throw new Error(`truncated len-delim field ${fieldNum} at offset ${pos} (need ${sz}, have ${buf.length - pos})`);
}
value = buf.subarray(pos, pos + sz);
pos += sz;
break;
}
case 5: { // fixed32
if (pos + 4 > buf.length) throw new Error(`truncated fixed32 at offset ${pos}`);
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);
}