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/synthetic/Bytes.zig | |
| parent | 55c138263e190a1e79d4b997bfb9397306c0ec1f (diff) | |
feat: finish ghostty pane backend integration
Diffstat (limited to 'vendor/libghostty-vt/src/synthetic/Bytes.zig')
| -rw-r--r-- | vendor/libghostty-vt/src/synthetic/Bytes.zig | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/vendor/libghostty-vt/src/synthetic/Bytes.zig b/vendor/libghostty-vt/src/synthetic/Bytes.zig new file mode 100644 index 00000000..7d4c34a3 --- /dev/null +++ b/vendor/libghostty-vt/src/synthetic/Bytes.zig @@ -0,0 +1,119 @@ +//! Generates bytes. +const Bytes = @This(); + +const std = @import("std"); +const Generator = @import("Generator.zig"); + +/// Random number generator. +rand: std.Random, + +/// The minimum and maximum length of the generated bytes. +min_len: usize = 1, +max_len: usize = std.math.maxInt(usize), + +/// The possible bytes that can be generated. If a byte is duplicated +/// in the alphabet, it will be more likely to be generated. That's a +/// side effect of the generator, not an intended use case. +alphabet: ?[]const u8 = null, + +/// Generate an alphabet given a function that returns true/false for a +/// given byte. +pub fn generateAlphabet(comptime func: fn (u8) bool) []const u8 { + @setEvalBranchQuota(3000); + var count = 0; + for (0..256) |c| { + if (func(c)) count += 1; + } + var alphabet: [count]u8 = undefined; + var i = 0; + for (0..256) |c| { + if (func(c)) { + alphabet[i] = c; + i += 1; + } + } + const result = alphabet; + return &result; +} + +pub fn generator(self: *Bytes) Generator { + return .init(self, next); +} + +/// Return a copy of the Bytes, but with a new alphabet. +pub fn newAlphabet(self: *const Bytes, new_alphabet: ?[]const u8) Bytes { + return .{ + .rand = self.rand, + .alphabet = new_alphabet, + .min_len = self.min_len, + .max_len = self.max_len, + }; +} + +/// Return a copy of the Bytes, but with a new min_len. The new min +/// len cannot be more than the previous max_len. +pub fn atLeast(self: *const Bytes, new_min_len: usize) Bytes { + return .{ + .rand = self.rand, + .alphabet = self.alphabet, + .min_len = @min(self.max_len, new_min_len), + .max_len = self.max_len, + }; +} + +/// Return a copy of the Bytes, but with a new max_len. The new max_len cannot +/// be more the previous max_len. +pub fn atMost(self: *const Bytes, new_max_len: usize) Bytes { + return .{ + .rand = self.rand, + .alphabet = self.alphabet, + .min_len = @min(self.min_len, @min(self.max_len, new_max_len)), + .max_len = @min(self.max_len, new_max_len), + }; +} + +pub fn next(self: *const Bytes, writer: *std.Io.Writer, max_len: usize) std.Io.Writer.Error!void { + _ = try self.atMost(max_len).write(writer); +} + +pub fn format(self: *const Bytes, writer: *std.Io.Writer) std.Io.Writer.Error!void { + _ = try self.write(writer); +} + +/// Write some random data and return the number of bytes written. +pub fn write(self: *const Bytes, writer: *std.Io.Writer) std.Io.Writer.Error!usize { + std.debug.assert(self.min_len >= 1); + std.debug.assert(self.max_len >= self.min_len); + + const len = self.rand.intRangeAtMostBiased(usize, self.min_len, self.max_len); + + var buf: [8]u8 = undefined; + + var remaining = len; + while (remaining > 0) { + const data = buf[0..@min(remaining, buf.len)]; + self.rand.bytes(data); + if (self.alphabet) |alphabet| { + for (data) |*byte| byte.* = alphabet[byte.* % alphabet.len]; + } + try writer.writeAll(data); + remaining -= data.len; + } + + return len; +} + +test "bytes" { + const testing = std.testing; + var prng = std.Random.DefaultPrng.init(0); + var buf: [256]u8 = undefined; + var writer: std.Io.Writer = .fixed(&buf); + var v: Bytes = .{ + .rand = prng.random(), + .min_len = buf.len, + .max_len = buf.len, + }; + const gen = v.generator(); + try gen.next(&writer, buf.len); + try testing.expectEqual(buf.len, writer.buffered().len); +} |
