diff options
| author | Can Celik <ogulcancelik@gmail.com> | 2026-04-04 19:22:04 +0300 |
|---|---|---|
| committer | Can Celik <ogulcancelik@gmail.com> | 2026-04-05 01:23:06 +0300 |
| commit | 41dd733ca7123c9ac4bfc6c781697a660e95b052 (patch) | |
| tree | 3fc91815ca139ef2e0b281bba0abda4ef15175f4 /vendor/libghostty-vt/src/simd/base64.zig | |
| parent | 55c138263e190a1e79d4b997bfb9397306c0ec1f (diff) | |
feat: finish ghostty pane backend integration
Diffstat (limited to 'vendor/libghostty-vt/src/simd/base64.zig')
| -rw-r--r-- | vendor/libghostty-vt/src/simd/base64.zig | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/vendor/libghostty-vt/src/simd/base64.zig b/vendor/libghostty-vt/src/simd/base64.zig new file mode 100644 index 00000000..81feeb72 --- /dev/null +++ b/vendor/libghostty-vt/src/simd/base64.zig @@ -0,0 +1,87 @@ +const std = @import("std"); +const options = @import("build_options"); +const assert = @import("../quirks.zig").inlineAssert; +const scalar_decoder = @import("base64_scalar.zig").scalar_decoder; + +const log = std.log.scoped(.simd_base64); + +pub fn maxLen(input: []const u8) usize { + if (comptime options.simd) return ghostty_simd_base64_max_length( + input.ptr, + input.len, + ); + + return maxLenScalar(input); +} + +fn maxLenScalar(input: []const u8) usize { + return scalar_decoder.calcSizeForSlice(scalarInput(input)) catch |err| { + log.warn("failed to calculate base64 size for payload: {}", .{err}); + return 0; + }; +} + +pub fn decode(input: []const u8, output: []u8) error{Base64Invalid}![]const u8 { + if (comptime options.simd) { + const res = ghostty_simd_base64_decode( + input.ptr, + input.len, + output.ptr, + ); + if (res < 0) return error.Base64Invalid; + return output[0..@intCast(res)]; + } + + return decodeScalar(input, output); +} + +fn decodeScalar( + input_raw: []const u8, + output: []u8, +) error{Base64Invalid}![]const u8 { + const input = scalarInput(input_raw); + const size = maxLenScalar(input); + if (size == 0) return ""; + assert(output.len >= size); + scalar_decoder.decode( + output, + scalarInput(input), + ) catch return error.Base64Invalid; + return output[0..size]; +} + +/// For non-SIMD enabled builds, we trim the padding from the end of the +/// base64 input in order to get identical output with the SIMD version. +fn scalarInput(input: []const u8) []const u8 { + var i: usize = 0; + while (input[input.len - i - 1] == '=') i += 1; + return input[0 .. input.len - i]; +} + +// base64.cpp +extern "c" fn ghostty_simd_base64_max_length( + input: [*]const u8, + len: usize, +) usize; +extern "c" fn ghostty_simd_base64_decode( + input: [*]const u8, + len: usize, + output: [*]u8, +) isize; + +test "base64 maxLen" { + const testing = std.testing; + const len = maxLen("aGVsbG8gd29ybGQ="); + try testing.expectEqual(11, len); +} + +test "base64 decode" { + const testing = std.testing; + const alloc = testing.allocator; + const input = "aGVsbG8gd29ybGQ="; + const len = maxLen(input); + const output = try alloc.alloc(u8, len); + defer alloc.free(output); + const str = try decode(input, output); + try testing.expectEqualStrings("hello world", str); +} |
