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...@@ -1965,13 +1965,34 @@ pub fn writeVarPackedInt(bytes: []u8, bit_offset: usize, bit_count: usize, value
1965/// Swap the byte order of all the members of the fields of a struct1965/// Swap the byte order of all the members of the fields of a struct
1966/// (Changing their endianness)1966/// (Changing their endianness)
1967pub fn byteSwapAllFields(comptime S: type, ptr: *S) void {1967pub fn byteSwapAllFields(comptime S: type, ptr: *S) void {
1968 if (@typeInfo(S) != .Struct) @compileError("byteSwapAllFields expects a struct as the first argument");1968 switch (@typeInfo(S)) {
1969 inline for (std.meta.fields(S)) |f| {1969 .Struct => {
1970 if (@typeInfo(f.type) == .Struct) {1970 inline for (std.meta.fields(S)) |f| {
1971 byteSwapAllFields(f.type, &@field(ptr, f.name));1971 switch (@typeInfo(f.type)) {
1972 } else {1972 .Struct, .Array => byteSwapAllFields(f.type, &@field(ptr, f.name)),
1973 @field(ptr, f.name) = @byteSwap(@field(ptr, f.name));1973 .Enum => {
1974 }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"),
1975 }1996 }
1976}1997}
19771998
...@@ -1980,21 +2001,25 @@ test "byteSwapAllFields" {...@@ -1980,21 +2001,25 @@ test "byteSwapAllFields" {
1980 f0: u8,2001 f0: u8,
1981 f1: u16,2002 f1: u16,
1982 f2: u32,2003 f2: u32,
2004 f3: [1]u8,
1983 };2005 };
1984 const K = extern struct {2006 const K = extern struct {
1985 f0: u8,2007 f0: u8,
1986 f1: T,2008 f1: T,
1987 f2: u16,2009 f2: u16,
2010 f3: [1]u8,
1988 };2011 };
1989 var s = T{2012 var s = T{
1990 .f0 = 0x12,2013 .f0 = 0x12,
1991 .f1 = 0x1234,2014 .f1 = 0x1234,
1992 .f2 = 0x12345678,2015 .f2 = 0x12345678,
2016 .f3 = .{0x12},
1993 };2017 };
1994 var k = K{2018 var k = K{
1995 .f0 = 0x12,2019 .f0 = 0x12,
1996 .f1 = s,2020 .f1 = s,
1997 .f2 = 0x1234,2021 .f2 = 0x1234,
2022 .f3 = .{0x12},
1998 };2023 };
1999 byteSwapAllFields(T, &s);2024 byteSwapAllFields(T, &s);
2000 byteSwapAllFields(K, &k);2025 byteSwapAllFields(K, &k);
...@@ -2002,11 +2027,13 @@ test "byteSwapAllFields" {...@@ -2002,11 +2027,13 @@ test "byteSwapAllFields" {
2002 .f0 = 0x12,2027 .f0 = 0x12,
2003 .f1 = 0x3412,2028 .f1 = 0x3412,
2004 .f2 = 0x78563412,2029 .f2 = 0x78563412,
2030 .f3 = .{0x12},
2005 }, s);2031 }, s);
2006 try std.testing.expectEqual(K{2032 try std.testing.expectEqual(K{
2007 .f0 = 0x12,2033 .f0 = 0x12,
2008 .f1 = s,2034 .f1 = s,
2009 .f2 = 0x3412,2035 .f2 = 0x3412,
2036 .f3 = .{0x12},
2010 }, k);2037 }, k);
2011}2038}
20122039