Write a single integer as LEB128 to the given writer.
pub fn writeLeb128(w: *Writer, value: anytype) Error!void
pub fn writeLeb128(w: *Writer, value: anytype) Error!void {
const T = @TypeOf(value);
const info = switch (@typeInfo(T)) {
.int => |info| info,
else => @compileError(@typeName(T) ++ " not supported"),
};
const BoundInt = @Int(info.signedness, 7);
if (info.bits <= 7 or (value >= std.math.minInt(BoundInt) and value <= std.math.maxInt(BoundInt))) {
const Bits = @Int(info.signedness, 8);
const byte = switch (info.signedness) {
.signed => @as(Bits, @intCast(value)) & 0x7F,
.unsigned => @as(Bits, @intCast(value)),
};
try w.writeByte(@bitCast(byte));
return;
}
const Byte = packed struct { bits: u7, more: bool };
const Int = std.math.ByteAlignedInt(T);
const max_bytes = @divFloor(info.bits - 1, 7) + 1;
const sign_value = value >> (info.bits - 1);
var val: Int = value;
for (0..max_bytes) |_| {
const more = switch (info.signedness) {
.signed => val >> 6 != sign_value,
.unsigned => val > std.math.maxInt(u7),
};
try w.writeByte(@bitCast(@as(Byte, .{
.bits = @intCast(val & 0x7F),
.more = more,
})));
if (!more) return;
val >>= 7;
} else unreachable;
}