commit e4abdf5a133ac4822644da1dabd5437ac751d78d (tree)
parent f657767b600064c520fac0e72da6016508a8b601
Author: Andrew Kelley <andrew@ziglang.org>
Date: Sun, 20 Jul 2025 11:23:12 -0700
std.Io.Reader: fix takeStruct/peekStruct packed
closes #24516
Diffstat:
1 file changed, 23 insertions(+), 2 deletions(-)
diff --git a/lib/std/Io/Reader.zig b/lib/std/Io/Reader.zig
@@ -1148,7 +1148,7 @@ pub inline fn takeStruct(r: *Reader, comptime T: type, endian: std.builtin.Endia
return res;
},
.@"packed" => {
- return takeInt(r, info.backing_integer.?, endian);
+ return @bitCast(try takeInt(r, info.backing_integer.?, endian));
},
},
else => @compileError("not a struct"),
@@ -1173,7 +1173,7 @@ pub inline fn peekStruct(r: *Reader, comptime T: type, endian: std.builtin.Endia
return res;
},
.@"packed" => {
- return peekInt(r, info.backing_integer.?, endian);
+ return @bitCast(try peekInt(r, info.backing_integer.?, endian));
},
},
else => @compileError("not a struct"),
@@ -1724,6 +1724,27 @@ test "takeDelimiterInclusive when it rebases" {
}
}
+test "takeStruct and peekStruct packed" {
+ var r: Reader = .fixed(&.{ 0b11110000, 0b00110011 });
+ const S = packed struct(u16) { a: u2, b: u6, c: u7, d: u1 };
+
+ try testing.expectEqual(@as(S, .{
+ .a = 0b11,
+ .b = 0b001100,
+ .c = 0b1110000,
+ .d = 0b1,
+ }), try r.peekStruct(S, .big));
+
+ try testing.expectEqual(@as(S, .{
+ .a = 0b11,
+ .b = 0b001100,
+ .c = 0b1110000,
+ .d = 0b1,
+ }), try r.takeStruct(S, .big));
+
+ try testing.expectError(error.EndOfStream, r.takeStruct(S, .little));
+}
+
/// Provides a `Reader` implementation by passing data from an underlying
/// reader through `Hasher.update`.
///