I have a function, that casts bytes to a type; well I'm slowly working on it. While working with pointer casting and giving up on slices (if []u8 has a defined memory layout correct me.) i tried also [*c]u8, which in comptime works just fine, but for runtime values, returns null. Is there any fancy pointer checking/ signing going on?
#ptrFromInt bug?
1 messages · Page 1 of 1 (latest)
const std = @import("std");
pub fn bitCast(comptime T: type, bytes: []const u8, offset: usize, endian: std.builtin.Endian) ?T {
const type_info = @typeInfo(T);
const type_size = @bitSizeOf(T);
std.debug.assert(bytes.len * 8 >= offset + type_size);
switch (type_info) {
.@"anyframe",
// ...
=> @compileError(std.fmt.comptimePrint(
"Type `{}` doesn't have a defined memory layout",
.{T},
)),
.type => return type,
.void => return void{},
.bool => return std.mem.readPackedInt(u1, bytes, offset, endian) == 1,
.int => return std.mem.readPackedInt(T, bytes, offset, endian),
.float => |fi| return @bitCast(std.mem.readPackedInt(std.meta.Int(.unsigned, fi.bits), bytes, offset, endian)),
.pointer => |pi| {
if (pi.size == .slice) @compileError("Slices aren't allowed");
const val = std.mem.readPackedInt(usize, bytes, offset, endian);
if ((!pi.is_allowzero) and val == 0) return null;
return @ptrFromInt(val);
},
else => {
// @compileLog(type_info, type_size);
unreachable;
},
}
}
test "bitCast" {
const a =
@as(?[*c]u8, @as([*c]u8, @ptrFromInt(1)));
// when b is evaluated in runtime it always returns null only for [*c]u8 type
const b =
// comptime // if we force b, to be calculated in comptime everything works, and the following test passes.
bitCast([*c]u8, &.{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, 0, .big);
std.log.err("{?*} {?*}", .{ a, b });
try std.testing.expectEqual(a, b);
}