authorgravatar for tristan.ross@midstall.comTristan Ross <tristan.ross@midstall.com> 2024-01-14 18:06:31-08:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-01-14 21:06:31-05:00
log9fce1d1ab19159cf86b22e805cdf3b73f7f10a57
tree695cbf9e4fc838b901ebf500288aba17a6f6e23c
parentf9d8176e94cf355dc5c4c35fbdd7e125eb29bcef
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

mem: add byteswap array support (#17959)

also make byteswap work with enums

1 files changed, 34 insertions(+), 7 deletions(-)

lib/std/mem.zig+34-7
......@@ -1965,13 +1965,34 @@ pub fn writeVarPackedInt(bytes: []u8, bit_offset: usize, bit_count: usize, value
19651965/// Swap the byte order of all the members of the fields of a struct
19661966/// (Changing their endianness)
19671967pub fn byteSwapAllFields(comptime S: type, ptr: *S) void {
1968 if (@typeInfo(S) != .Struct) @compileError("byteSwapAllFields expects a struct as the first argument");
1969 inline for (std.meta.fields(S)) |f| {
1970 if (@typeInfo(f.type) == .Struct) {
1971 byteSwapAllFields(f.type, &@field(ptr, f.name));
1972 } else {
1973 @field(ptr, f.name) = @byteSwap(@field(ptr, f.name));
1974 }
1968 switch (@typeInfo(S)) {
1969 .Struct => {
1970 inline for (std.meta.fields(S)) |f| {
1971 switch (@typeInfo(f.type)) {
1972 .Struct, .Array => byteSwapAllFields(f.type, &@field(ptr, f.name)),
1973 .Enum => {
1974 @field(ptr, f.name) = @enumFromInt(@byteSwap(@intFromEnum(@field(ptr, f.name))));
1975 },
1976 else => {
1977 @field(ptr, f.name) = @byteSwap(@field(ptr, f.name));
1978 },
1979 }
1980 }
1981 },
1982 .Array => {
1983 for (ptr) |*item| {
1984 switch (@typeInfo(@TypeOf(item.*))) {
1985 .Struct, .Array => byteSwapAllFields(@TypeOf(item.*), item),
1986 .Enum => {
1987 item.* = @enumFromInt(@byteSwap(@intFromEnum(item.*)));
1988 },
1989 else => {
1990 item.* = @byteSwap(item.*);
1991 },
1992 }
1993 }
1994 },
1995 else => @compileError("byteSwapAllFields expects a struct or array as the first argument"),
19751996 }
19761997}
19771998
......@@ -1980,21 +2001,25 @@ test "byteSwapAllFields" {
19802001 f0: u8,
19812002 f1: u16,
19822003 f2: u32,
2004 f3: [1]u8,
19832005 };
19842006 const K = extern struct {
19852007 f0: u8,
19862008 f1: T,
19872009 f2: u16,
2010 f3: [1]u8,
19882011 };
19892012 var s = T{
19902013 .f0 = 0x12,
19912014 .f1 = 0x1234,
19922015 .f2 = 0x12345678,
2016 .f3 = .{0x12},
19932017 };
19942018 var k = K{
19952019 .f0 = 0x12,
19962020 .f1 = s,
19972021 .f2 = 0x1234,
2022 .f3 = .{0x12},
19982023 };
19992024 byteSwapAllFields(T, &s);
20002025 byteSwapAllFields(K, &k);
......@@ -2002,11 +2027,13 @@ test "byteSwapAllFields" {
20022027 .f0 = 0x12,
20032028 .f1 = 0x3412,
20042029 .f2 = 0x78563412,
2030 .f3 = .{0x12},
20052031 }, s);
20062032 try std.testing.expectEqual(K{
20072033 .f0 = 0x12,
20082034 .f1 = s,
20092035 .f2 = 0x3412,
2036 .f3 = .{0x12},
20102037 }, k);
20112038}
20122039