std.io.Writer: add support for non-power-of-two int sizes
This commit is contained in:
@@ -46,39 +46,34 @@ pub fn Writer(
|
||||
}
|
||||
|
||||
/// Write a native-endian integer.
|
||||
/// TODO audit non-power-of-two int sizes
|
||||
pub fn writeIntNative(self: Self, comptime T: type, value: T) Error!void {
|
||||
var bytes: [(@typeInfo(T).Int.bits + 7) / 8]u8 = undefined;
|
||||
mem.writeIntNative(T, &bytes, value);
|
||||
mem.writeIntNative(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value);
|
||||
return self.writeAll(&bytes);
|
||||
}
|
||||
|
||||
/// Write a foreign-endian integer.
|
||||
/// TODO audit non-power-of-two int sizes
|
||||
pub fn writeIntForeign(self: Self, comptime T: type, value: T) Error!void {
|
||||
var bytes: [(@typeInfo(T).Int.bits + 7) / 8]u8 = undefined;
|
||||
mem.writeIntForeign(T, &bytes, value);
|
||||
mem.writeIntForeign(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value);
|
||||
return self.writeAll(&bytes);
|
||||
}
|
||||
|
||||
/// TODO audit non-power-of-two int sizes
|
||||
pub fn writeIntLittle(self: Self, comptime T: type, value: T) Error!void {
|
||||
var bytes: [(@typeInfo(T).Int.bits + 7) / 8]u8 = undefined;
|
||||
mem.writeIntLittle(T, &bytes, value);
|
||||
mem.writeIntLittle(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value);
|
||||
return self.writeAll(&bytes);
|
||||
}
|
||||
|
||||
/// TODO audit non-power-of-two int sizes
|
||||
pub fn writeIntBig(self: Self, comptime T: type, value: T) Error!void {
|
||||
var bytes: [(@typeInfo(T).Int.bits + 7) / 8]u8 = undefined;
|
||||
mem.writeIntBig(T, &bytes, value);
|
||||
mem.writeIntBig(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value);
|
||||
return self.writeAll(&bytes);
|
||||
}
|
||||
|
||||
/// TODO audit non-power-of-two int sizes
|
||||
pub fn writeInt(self: Self, comptime T: type, value: T, endian: std.builtin.Endian) Error!void {
|
||||
var bytes: [(@typeInfo(T).Int.bits + 7) / 8]u8 = undefined;
|
||||
mem.writeInt(T, &bytes, value, endian);
|
||||
mem.writeInt(std.math.ByteAlignedInt(@TypeOf(value)), &bytes, value, endian);
|
||||
return self.writeAll(&bytes);
|
||||
}
|
||||
|
||||
|
||||
@@ -1122,6 +1122,23 @@ pub fn isPowerOfTwo(v: anytype) bool {
|
||||
return (v & (v - 1)) == 0;
|
||||
}
|
||||
|
||||
/// Aligns the given integer type bit width to a width divisible by 8.
|
||||
pub fn ByteAlignedInt(comptime T: type) type {
|
||||
const info = @typeInfo(T).Int;
|
||||
const bits = (info.bits + 7) / 8 * 8;
|
||||
const extended_type = std.meta.Int(info.signedness, bits);
|
||||
return extended_type;
|
||||
}
|
||||
|
||||
test "ByteAlignedInt" {
|
||||
try testing.expect(ByteAlignedInt(u0) == u0);
|
||||
try testing.expect(ByteAlignedInt(i0) == i0);
|
||||
try testing.expect(ByteAlignedInt(u3) == u8);
|
||||
try testing.expect(ByteAlignedInt(u8) == u8);
|
||||
try testing.expect(ByteAlignedInt(i111) == i112);
|
||||
try testing.expect(ByteAlignedInt(u129) == u136);
|
||||
}
|
||||
|
||||
/// Rounds the given floating point number to an integer, away from zero.
|
||||
/// Uses a dedicated hardware instruction when available.
|
||||
/// This is the same as calling the builtin @round
|
||||
|
||||
Reference in New Issue
Block a user