Function readPackedTwosComplement [src]

Read the value of x from a packed memory buffer. Asserts that buffer is large enough to contain a value of bit-size bit_count at offset bit_offset. This is equivalent to loading the value of an integer with bit_count bits as if it were a field in packed memory at the provided bit offset.

Prototype

pub fn readPackedTwosComplement( x: *Mutable, buffer: []const u8, bit_offset: usize, bit_count: usize, endian: Endian, signedness: Signedness, ) void

Parameters

x: *Mutablebuffer: []const u8bit_offset: usizebit_count: usizeendian: Endiansignedness: Signedness

Source

pub fn readPackedTwosComplement( x: *Mutable, buffer: []const u8, bit_offset: usize, bit_count: usize, endian: Endian, signedness: Signedness, ) void { if (bit_count == 0) { x.limbs[0] = 0; x.len = 1; x.positive = true; return; } // Check whether the input is negative var positive = true; if (signedness == .signed) { const total_bits = bit_offset + bit_count; const last_byte = switch (endian) { .little => ((total_bits + 7) / 8) - 1, .big => buffer.len - ((total_bits + 7) / 8), }; const sign_bit = @as(u8, 1) << @as(u3, @intCast((total_bits - 1) % 8)); positive = ((buffer[last_byte] & sign_bit) == 0); } // Copy all complete limbs var carry: u1 = 1; var limb_index: usize = 0; var bit_index: usize = 0; while (limb_index < bit_count / @bitSizeOf(Limb)) : (limb_index += 1) { // Read one Limb of bits var limb = mem.readPackedInt(Limb, buffer, bit_index + bit_offset, endian); bit_index += @bitSizeOf(Limb); // 2's complement (bitwise not, then add carry bit) if (!positive) { const ov = @addWithOverflow(~limb, carry); limb = ov[0]; carry = ov[1]; } x.limbs[limb_index] = limb; } // Copy the remaining bits if (bit_count != bit_index) { // Read all remaining bits var limb = switch (signedness) { .unsigned => mem.readVarPackedInt(Limb, buffer, bit_index + bit_offset, bit_count - bit_index, endian, .unsigned), .signed => b: { const SLimb = std.meta.Int(.signed, @bitSizeOf(Limb)); const limb = mem.readVarPackedInt(SLimb, buffer, bit_index + bit_offset, bit_count - bit_index, endian, .signed); break :b @as(Limb, @bitCast(limb)); }, }; // 2's complement (bitwise not, then add carry bit) if (!positive) { const ov = @addWithOverflow(~limb, carry); assert(ov[1] == 0); limb = ov[0]; } x.limbs[limb_index] = limb; limb_index += 1; } x.positive = positive; x.len = limb_index; x.normalize(x.len); }