aboutsummaryrefslogtreecommitdiff
path: root/vendor/libghostty-vt/src/simd/base64.zig
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-04-04 19:22:04 +0300
committerCan Celik <ogulcancelik@gmail.com>2026-04-05 01:23:06 +0300
commit41dd733ca7123c9ac4bfc6c781697a660e95b052 (patch)
tree3fc91815ca139ef2e0b281bba0abda4ef15175f4 /vendor/libghostty-vt/src/simd/base64.zig
parent55c138263e190a1e79d4b997bfb9397306c0ec1f (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.zig87
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);
+}