diff options
| author | Taylan Kammer <taylan.kammer@gmail.com> | 2025-02-17 22:31:16 +0100 |
|---|---|---|
| committer | Taylan Kammer <taylan.kammer@gmail.com> | 2025-02-17 22:31:16 +0100 |
| commit | a81412ea9d85dd1d5d4a065cbf61c1080420860e (patch) | |
| tree | e04f53d434f554c6cb7c6ce7cea9ef99167a039f /src/libzisp/value/sstr.zig | |
| parent | 704411d750dd07da5d2c710807a4dceb671ec8e2 (diff) | |
update
Diffstat (limited to 'src/libzisp/value/sstr.zig')
| -rw-r--r-- | src/libzisp/value/sstr.zig | 64 |
1 files changed, 63 insertions, 1 deletions
diff --git a/src/libzisp/value/sstr.zig b/src/libzisp/value/sstr.zig index 3c0755d..c2b2859 100644 --- a/src/libzisp/value/sstr.zig +++ b/src/libzisp/value/sstr.zig @@ -1,3 +1,65 @@ +const std = @import("std"); + const Value = @import("../value.zig").Value; -// stub +// Zig API + +pub fn check(v: Value) bool { + return v.isPacked() and + !v.sstr.fixnum and + !v.sstr.ptr and + v.sstr.tag == .sstr; +} + +pub fn assert(v: Value) void { + if (!check(v)) { + v.dump(); + @panic("not sstr"); + } +} + +// For now, ignore encoding, just treat it as []u8. + +pub fn isValidSstr(s: []const u8) bool { + if (s.len > 6) { + return false; + } + for (s) |c| { + if (c == 0) { + return false; + } + } + return true; +} + +fn assertValidSstr(s: []const u8) void { + if (!isValidSstr(s)) { + std.debug.print("invalid sstr: {s}", .{s}); + @panic("invalid sstr"); + } +} + +// Different ways of doing the following have been tested, including manual +// shifting and bit masking, but memcpy always wins easily according to our +// micro-benchmarks, both under ReleaseSafe and under ReleaseFast. + +pub fn pack(s: []const u8) Value { + assertValidSstr(s); + var v = Value{ .sstr = .{ .value = 0 } }; + const dest: [*]u8 = @ptrCast(&v.sstr.value); + @memcpy(dest, s); + return v; +} + +// It's tempting to inline for here to eliminate the if statement or prevent +// need of @truncate but all alternatives were a little slower. + +pub fn unpack(v: Value) struct { [6]u8, u3 } { + var s: [6]u8 = undefined; + const src: *const [6]u8 = @ptrCast(&v.sstr.value); + @memcpy(&s, src); + for (0..6) |i| { + if (s[i] == 0) return .{ s, @truncate(i) }; + } + return .{ s, 6 }; +} |
