mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-03-08 02:44:43 +01:00
Properly support passing a packed struct to byteSwapAllFields (#30571)
Reopening [#25698](https://github.com/ziglang/zig/pull/25698) Closes [#25054](https://github.com/ziglang/zig/issues/25054) Reviewed-on: https://codeberg.org/ziglang/zig/pulls/30571 Reviewed-by: Andrew Kelley <andrewrk@noreply.codeberg.org> Co-authored-by: Steven Casper <sebastiancasper3@gmail.com> Co-committed-by: Steven Casper <sebastiancasper3@gmail.com>
This commit is contained in:
parent
e8a2e6578a
commit
8d4a9119b8
1 changed files with 40 additions and 8 deletions
|
|
@ -2252,16 +2252,20 @@ test writeVarPackedInt {
|
|||
/// Swap the byte order of all the members of the fields of a struct
|
||||
/// (Changing their endianness)
|
||||
pub fn byteSwapAllFields(comptime S: type, ptr: *S) void {
|
||||
byteSwapAllFieldsAligned(S, @alignOf(S), ptr);
|
||||
}
|
||||
|
||||
/// Swap the byte order of all the members of the fields of a struct
|
||||
/// (Changing their endianness)
|
||||
pub fn byteSwapAllFieldsAligned(comptime S: type, comptime A: comptime_int, ptr: *align(A) S) void {
|
||||
switch (@typeInfo(S)) {
|
||||
.@"struct" => {
|
||||
inline for (std.meta.fields(S)) |f| {
|
||||
.@"struct" => |struct_info| {
|
||||
if (struct_info.backing_integer) |Int| {
|
||||
ptr.* = @bitCast(@byteSwap(@as(Int, @bitCast(ptr.*))));
|
||||
} else inline for (std.meta.fields(S)) |f| {
|
||||
switch (@typeInfo(f.type)) {
|
||||
.@"struct" => |struct_info| if (struct_info.backing_integer) |Int| {
|
||||
@field(ptr, f.name) = @bitCast(@byteSwap(@as(Int, @bitCast(@field(ptr, f.name)))));
|
||||
} else {
|
||||
byteSwapAllFields(f.type, &@field(ptr, f.name));
|
||||
},
|
||||
.@"union", .array => byteSwapAllFields(f.type, &@field(ptr, f.name)),
|
||||
.@"struct" => byteSwapAllFieldsAligned(f.type, f.alignment, &@field(ptr, f.name)),
|
||||
.@"union", .array => byteSwapAllFieldsAligned(f.type, f.alignment, &@field(ptr, f.name)),
|
||||
.@"enum" => {
|
||||
@field(ptr, f.name) = @enumFromInt(@byteSwap(@intFromEnum(@field(ptr, f.name))));
|
||||
},
|
||||
|
|
@ -2317,6 +2321,20 @@ test byteSwapAllFields {
|
|||
f4: bool,
|
||||
f5: f32,
|
||||
};
|
||||
const P = packed struct(u32) {
|
||||
f0: u1,
|
||||
f1: u7,
|
||||
f2: u4,
|
||||
f3: u4,
|
||||
f4: u16,
|
||||
};
|
||||
const A = extern struct {
|
||||
f0: u32,
|
||||
f1: extern struct {
|
||||
f0: u64,
|
||||
} align(4),
|
||||
f2: u32,
|
||||
};
|
||||
var s = T{
|
||||
.f0 = 0x12,
|
||||
.f1 = 0x1234,
|
||||
|
|
@ -2334,8 +2352,16 @@ test byteSwapAllFields {
|
|||
.f4 = false,
|
||||
.f5 = @as(f32, @bitCast(@as(u32, 0x45d42800))),
|
||||
};
|
||||
var p: P = @bitCast(@as(u32, 0x01234567));
|
||||
var a: A = A{
|
||||
.f0 = 0x12345678,
|
||||
.f1 = .{ .f0 = 0x123456789ABCDEF0 },
|
||||
.f2 = 0x87654321,
|
||||
};
|
||||
byteSwapAllFields(T, &s);
|
||||
byteSwapAllFields(K, &k);
|
||||
byteSwapAllFields(P, &p);
|
||||
byteSwapAllFields(A, &a);
|
||||
try std.testing.expectEqual(T{
|
||||
.f0 = 0x12,
|
||||
.f1 = 0x3412,
|
||||
|
|
@ -2353,6 +2379,12 @@ test byteSwapAllFields {
|
|||
.f4 = false,
|
||||
.f5 = @as(f32, @bitCast(@as(u32, 0x0028d445))),
|
||||
}, k);
|
||||
try std.testing.expectEqual(@as(P, @bitCast(@as(u32, 0x67452301))), p);
|
||||
try std.testing.expectEqual(A{
|
||||
.f0 = 0x78563412,
|
||||
.f1 = .{ .f0 = 0xF0DEBC9A78563412 },
|
||||
.f2 = 0x21436587,
|
||||
}, a);
|
||||
}
|
||||
|
||||
/// Reverses the byte order of all elements in a slice.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue