Function byteSwapAllFields [src]

Swap the byte order of all the members of the fields of a struct (Changing their endianness)

Prototype

pub fn byteSwapAllFields(comptime S: type, ptr: *S) void

Parameters

S: typeptr: *S

Example

test byteSwapAllFields { const T = extern struct { f0: u8, f1: u16, f2: u32, f3: [1]u8, f4: bool, f5: f32, f6: extern union { f0: u16, f1: u16 }, }; const K = extern struct { f0: u8, f1: T, f2: u16, f3: [1]u8, f4: bool, f5: f32, }; var s = T{ .f0 = 0x12, .f1 = 0x1234, .f2 = 0x12345678, .f3 = .{0x12}, .f4 = true, .f5 = @as(f32, @bitCast(@as(u32, 0x4640e400))), .f6 = .{ .f0 = 0x1234 }, }; var k = K{ .f0 = 0x12, .f1 = s, .f2 = 0x1234, .f3 = .{0x12}, .f4 = false, .f5 = @as(f32, @bitCast(@as(u32, 0x45d42800))), }; byteSwapAllFields(T, &s); byteSwapAllFields(K, &k); try std.testing.expectEqual(T{ .f0 = 0x12, .f1 = 0x3412, .f2 = 0x78563412, .f3 = .{0x12}, .f4 = true, .f5 = @as(f32, @bitCast(@as(u32, 0x00e44046))), .f6 = .{ .f0 = 0x3412 }, }, s); try std.testing.expectEqual(K{ .f0 = 0x12, .f1 = s, .f2 = 0x3412, .f3 = .{0x12}, .f4 = false, .f5 = @as(f32, @bitCast(@as(u32, 0x0028d445))), }, k); }

Source

pub fn byteSwapAllFields(comptime S: type, ptr: *S) void { switch (@typeInfo(S)) { .@"struct" => { 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)), .@"enum" => { @field(ptr, f.name) = @enumFromInt(@byteSwap(@intFromEnum(@field(ptr, f.name)))); }, .bool => {}, .float => |float_info| { @field(ptr, f.name) = @bitCast(@byteSwap(@as(std.meta.Int(.unsigned, float_info.bits), @bitCast(@field(ptr, f.name))))); }, else => { @field(ptr, f.name) = @byteSwap(@field(ptr, f.name)); }, } } }, .@"union" => |union_info| { if (union_info.tag_type != null) { @compileError("byteSwapAllFields expects an untagged union"); } const first_size = @bitSizeOf(union_info.fields[0].type); inline for (union_info.fields) |field| { if (@bitSizeOf(field.type) != first_size) { @compileError("Unable to byte-swap unions with varying field sizes"); } } const BackingInt = std.meta.Int(.unsigned, @bitSizeOf(S)); ptr.* = @bitCast(@byteSwap(@as(BackingInt, @bitCast(ptr.*)))); }, .array => |info| { byteSwapAllElements(info.child, ptr); }, else => { ptr.* = @byteSwap(ptr.*); }, } }