feature. See also
. The project being documented here (as the example) is the Zig library itself.
mem.writePackedIntBig
fn writePackedIntBig(comptime T: type, bytes: []u8, bit_offset: usize, value: T) void
File
Code
fn writePackedIntBig(comptime T: type, bytes: []u8, bit_offset: usize, value: T) void {
const uN = @Int(.unsigned, @bitSizeOf(T));
const Log2N = std.math.Log2Int(T);
const bit_count = @as(usize, @bitSizeOf(T));
const bit_shift = @as(u3, @intCast(bit_offset % 8));
const byte_count = (bit_shift + bit_count + 7) / 8;
const store_size = (@bitSizeOf(T) + 7) / 8;
const store_tail_bits = @as(u3, @intCast((store_size * 8) - bit_count));
const StoreInt = @Int(.unsigned, store_size * 8);
if (bit_count == 0)
return;
// if bit_offset pushed us over a byte boundary.
const end = bytes.len - (bit_offset / 8);
const write_bytes = bytes[(end - byte_count)..end];
const head = write_bytes[byte_count - 1] & ((@as(u8, 1) << bit_shift) - 1);
var write_value = (@as(StoreInt, @as(uN, @bitCast(value))) << bit_shift) | @as(StoreInt, @intCast(head));
if (bit_shift > store_tail_bits) {
const tail_len = @as(Log2N, @intCast(bit_shift - store_tail_bits));
write_bytes[0] &= ~((@as(u8, 1) << @as(u3, @intCast(tail_len))) - 1);
write_bytes[0] |= @as(u8, @intCast((@as(uN, @bitCast(value)) >> (@as(Log2N, @truncate(bit_count)) -% tail_len))));
} else if (bit_shift < store_tail_bits) {
const tail_len = store_tail_bits - bit_shift;
const tail = write_bytes[0] & (@as(u8, 0xfe) << (7 - tail_len));
write_value |= @as(StoreInt, tail) << (8 * (store_size - 1));
}
writeInt(StoreInt, write_bytes[(byte_count - store_size)..][0..store_size], write_value, .big);
}