1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
const Kitty = @This();
const std = @import("std");
const Allocator = std.mem.Allocator;
const synthetic = @import("../main.zig");
const log = std.log.scoped(.@"kitty-gen");
pub const Options = struct {
/// The base64 payload length of each command in bytes, rounded
/// down to a multiple of four. Kitty clients typically chunk
/// payloads at 4096 bytes.
@"data-len": usize = 4096,
};
opts: Options,
/// The buffer a single generated sequence is written into. Sized to
/// the payload length plus room for the control data and terminator.
buf: []u8,
/// Create a new Kitty graphics sequence generator for the given arguments.
pub fn create(
alloc: Allocator,
opts: Options,
) !*Kitty {
const ptr = try alloc.create(Kitty);
errdefer alloc.destroy(ptr);
const buf = try alloc.alloc(u8, opts.@"data-len" + 128);
errdefer alloc.free(buf);
ptr.* = .{ .opts = opts, .buf = buf };
return ptr;
}
pub fn destroy(self: *Kitty, alloc: Allocator) void {
alloc.free(self.buf);
alloc.destroy(self);
}
pub fn run(self: *Kitty, writer: *std.Io.Writer, rand: std.Random) !void {
var gen: synthetic.Kitty = .{
.rand = rand,
.data_len = self.opts.@"data-len",
};
while (true) {
var fixed: std.Io.Writer = .fixed(self.buf);
try gen.next(&fixed, self.buf.len);
writer.writeAll(fixed.buffered()) catch |err| switch (err) {
error.WriteFailed => return,
};
}
}
test Kitty {
const testing = std.testing;
const alloc = testing.allocator;
const impl: *Kitty = try .create(alloc, .{});
defer impl.destroy(alloc);
var prng = std.Random.DefaultPrng.init(1);
const rand = prng.random();
var buf: [8192]u8 = undefined;
var writer: std.Io.Writer = .fixed(&buf);
try impl.run(&writer, rand);
}
|