mem: add byteswap array support (#17959)

also make byteswap work with enums
This commit is contained in:
Tristan Ross 2024-01-14 18:06:31 -08:00 committed by GitHub
parent f9d8176e94
commit 9fce1d1ab1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1965,13 +1965,34 @@ pub fn writeVarPackedInt(bytes: []u8, bit_offset: usize, bit_count: usize, value
/// Swap the byte order of all the members of the fields of a struct /// Swap the byte order of all the members of the fields of a struct
/// (Changing their endianness) /// (Changing their endianness)
pub fn byteSwapAllFields(comptime S: type, ptr: *S) void { pub fn byteSwapAllFields(comptime S: type, ptr: *S) void {
if (@typeInfo(S) != .Struct) @compileError("byteSwapAllFields expects a struct as the first argument"); switch (@typeInfo(S)) {
inline for (std.meta.fields(S)) |f| { .Struct => {
if (@typeInfo(f.type) == .Struct) { inline for (std.meta.fields(S)) |f| {
byteSwapAllFields(f.type, &@field(ptr, f.name)); switch (@typeInfo(f.type)) {
} else { .Struct, .Array => byteSwapAllFields(f.type, &@field(ptr, f.name)),
@field(ptr, f.name) = @byteSwap(@field(ptr, f.name)); .Enum => {
} @field(ptr, f.name) = @enumFromInt(@byteSwap(@intFromEnum(@field(ptr, f.name))));
},
else => {
@field(ptr, f.name) = @byteSwap(@field(ptr, f.name));
},
}
}
},
.Array => {
for (ptr) |*item| {
switch (@typeInfo(@TypeOf(item.*))) {
.Struct, .Array => byteSwapAllFields(@TypeOf(item.*), item),
.Enum => {
item.* = @enumFromInt(@byteSwap(@intFromEnum(item.*)));
},
else => {
item.* = @byteSwap(item.*);
},
}
}
},
else => @compileError("byteSwapAllFields expects a struct or array as the first argument"),
} }
} }
@ -1980,21 +2001,25 @@ test "byteSwapAllFields" {
f0: u8, f0: u8,
f1: u16, f1: u16,
f2: u32, f2: u32,
f3: [1]u8,
}; };
const K = extern struct { const K = extern struct {
f0: u8, f0: u8,
f1: T, f1: T,
f2: u16, f2: u16,
f3: [1]u8,
}; };
var s = T{ var s = T{
.f0 = 0x12, .f0 = 0x12,
.f1 = 0x1234, .f1 = 0x1234,
.f2 = 0x12345678, .f2 = 0x12345678,
.f3 = .{0x12},
}; };
var k = K{ var k = K{
.f0 = 0x12, .f0 = 0x12,
.f1 = s, .f1 = s,
.f2 = 0x1234, .f2 = 0x1234,
.f3 = .{0x12},
}; };
byteSwapAllFields(T, &s); byteSwapAllFields(T, &s);
byteSwapAllFields(K, &k); byteSwapAllFields(K, &k);
@ -2002,11 +2027,13 @@ test "byteSwapAllFields" {
.f0 = 0x12, .f0 = 0x12,
.f1 = 0x3412, .f1 = 0x3412,
.f2 = 0x78563412, .f2 = 0x78563412,
.f3 = .{0x12},
}, s); }, s);
try std.testing.expectEqual(K{ try std.testing.expectEqual(K{
.f0 = 0x12, .f0 = 0x12,
.f1 = s, .f1 = s,
.f2 = 0x3412, .f2 = 0x3412,
.f3 = .{0x12},
}, k); }, k);
} }