mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-25 13:16:11 +03:00
terminal/kitty-gfx: clean up a lot more memory management
This commit is contained in:
@ -30,16 +30,13 @@ pub const CommandParser = struct {
|
|||||||
/// is 10 characters (4294967295).
|
/// is 10 characters (4294967295).
|
||||||
kv_temp: [10]u8 = undefined,
|
kv_temp: [10]u8 = undefined,
|
||||||
kv_temp_len: u4 = 0,
|
kv_temp_len: u4 = 0,
|
||||||
|
kv_current: u8 = 0, // Current kv key
|
||||||
/// Current kv key
|
|
||||||
kv_current: u8 = 0,
|
|
||||||
|
|
||||||
/// This is the list of bytes that contains both KV data and final
|
/// This is the list of bytes that contains both KV data and final
|
||||||
/// data. You shouldn't access this directly.
|
/// data. You shouldn't access this directly.
|
||||||
data: std.ArrayListUnmanaged(u8) = .{},
|
data: std.ArrayList(u8),
|
||||||
|
|
||||||
/// Internal state for parsing.
|
/// Internal state for parsing.
|
||||||
data_i: usize = 0,
|
|
||||||
state: State = .control_key,
|
state: State = .control_key,
|
||||||
|
|
||||||
const State = enum {
|
const State = enum {
|
||||||
@ -54,19 +51,21 @@ pub const CommandParser = struct {
|
|||||||
data,
|
data,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Initialize the parser. The allocator given will be used only for
|
/// Initialize the parser. The allocator given will be used for both
|
||||||
/// temporary state and nothing long-lived.
|
/// temporary data and long-lived values such as the final image blob.
|
||||||
pub fn init(alloc: Allocator) CommandParser {
|
pub fn init(alloc: Allocator) CommandParser {
|
||||||
var arena = ArenaAllocator.init(alloc);
|
var arena = ArenaAllocator.init(alloc);
|
||||||
errdefer arena.deinit();
|
errdefer arena.deinit();
|
||||||
return .{
|
return .{
|
||||||
.arena = arena,
|
.arena = arena,
|
||||||
|
.data = std.ArrayList(u8).init(alloc),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *CommandParser) void {
|
pub fn deinit(self: *CommandParser) void {
|
||||||
// We don't free the hash map or array list because its in the arena
|
// We don't free the hash map because its in the arena
|
||||||
self.arena.deinit();
|
self.arena.deinit();
|
||||||
|
self.data.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Feed a single byte to the parser.
|
/// Feed a single byte to the parser.
|
||||||
@ -110,7 +109,7 @@ pub const CommandParser = struct {
|
|||||||
else => {},
|
else => {},
|
||||||
},
|
},
|
||||||
|
|
||||||
.data => try self.data.append(self.arena.allocator(), c),
|
.data => try self.data.append(c),
|
||||||
}
|
}
|
||||||
|
|
||||||
// We always add to our data list because this is our stable
|
// We always add to our data list because this is our stable
|
||||||
@ -122,7 +121,7 @@ pub const CommandParser = struct {
|
|||||||
///
|
///
|
||||||
/// The allocator given will be used for the long-lived data
|
/// The allocator given will be used for the long-lived data
|
||||||
/// of the final command.
|
/// of the final command.
|
||||||
pub fn complete(self: *CommandParser, alloc: Allocator) !Command {
|
pub fn complete(self: *CommandParser) !Command {
|
||||||
switch (self.state) {
|
switch (self.state) {
|
||||||
// We can't ever end in the control key state and be valid.
|
// We can't ever end in the control key state and be valid.
|
||||||
// This means the command looked something like "a=1,b"
|
// This means the command looked something like "a=1,b"
|
||||||
@ -172,10 +171,7 @@ pub const CommandParser = struct {
|
|||||||
.control = control,
|
.control = control,
|
||||||
.quiet = quiet,
|
.quiet = quiet,
|
||||||
.data = if (self.data.items.len == 0) "" else data: {
|
.data = if (self.data.items.len == 0) "" else data: {
|
||||||
// This is not the most efficient thing to do but it's easy
|
break :data try self.data.toOwnedSlice();
|
||||||
// and we can always optimize this later. Images are not super
|
|
||||||
// common, especially large ones.
|
|
||||||
break :data try alloc.dupe(u8, self.data.items[self.data_i..]);
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -768,7 +764,7 @@ test "transmission command" {
|
|||||||
|
|
||||||
const input = "f=24,s=10,v=20";
|
const input = "f=24,s=10,v=20";
|
||||||
for (input) |c| try p.feed(c);
|
for (input) |c| try p.feed(c);
|
||||||
const command = try p.complete(alloc);
|
const command = try p.complete();
|
||||||
defer command.deinit(alloc);
|
defer command.deinit(alloc);
|
||||||
|
|
||||||
try testing.expect(command.control == .transmit);
|
try testing.expect(command.control == .transmit);
|
||||||
@ -786,7 +782,7 @@ test "query command" {
|
|||||||
|
|
||||||
const input = "i=31,s=1,v=1,a=q,t=d,f=24;AAAA";
|
const input = "i=31,s=1,v=1,a=q,t=d,f=24;AAAA";
|
||||||
for (input) |c| try p.feed(c);
|
for (input) |c| try p.feed(c);
|
||||||
const command = try p.complete(alloc);
|
const command = try p.complete();
|
||||||
defer command.deinit(alloc);
|
defer command.deinit(alloc);
|
||||||
|
|
||||||
try testing.expect(command.control == .query);
|
try testing.expect(command.control == .query);
|
||||||
@ -806,7 +802,7 @@ test "display command" {
|
|||||||
|
|
||||||
const input = "a=p,U=1,i=31,c=80,r=120";
|
const input = "a=p,U=1,i=31,c=80,r=120";
|
||||||
for (input) |c| try p.feed(c);
|
for (input) |c| try p.feed(c);
|
||||||
const command = try p.complete(alloc);
|
const command = try p.complete();
|
||||||
defer command.deinit(alloc);
|
defer command.deinit(alloc);
|
||||||
|
|
||||||
try testing.expect(command.control == .display);
|
try testing.expect(command.control == .display);
|
||||||
@ -824,7 +820,7 @@ test "delete command" {
|
|||||||
|
|
||||||
const input = "a=d,d=p,x=3,y=4";
|
const input = "a=d,d=p,x=3,y=4";
|
||||||
for (input) |c| try p.feed(c);
|
for (input) |c| try p.feed(c);
|
||||||
const command = try p.complete(alloc);
|
const command = try p.complete();
|
||||||
defer command.deinit(alloc);
|
defer command.deinit(alloc);
|
||||||
|
|
||||||
try testing.expect(command.control == .delete);
|
try testing.expect(command.control == .delete);
|
||||||
@ -844,7 +840,7 @@ test "ignore unknown keys (long)" {
|
|||||||
|
|
||||||
const input = "f=24,s=10,v=20,hello=world";
|
const input = "f=24,s=10,v=20,hello=world";
|
||||||
for (input) |c| try p.feed(c);
|
for (input) |c| try p.feed(c);
|
||||||
const command = try p.complete(alloc);
|
const command = try p.complete();
|
||||||
defer command.deinit(alloc);
|
defer command.deinit(alloc);
|
||||||
|
|
||||||
try testing.expect(command.control == .transmit);
|
try testing.expect(command.control == .transmit);
|
||||||
@ -862,7 +858,7 @@ test "ignore very long values" {
|
|||||||
|
|
||||||
const input = "f=24,s=10,v=2000000000000000000000000000000000000000";
|
const input = "f=24,s=10,v=2000000000000000000000000000000000000000";
|
||||||
for (input) |c| try p.feed(c);
|
for (input) |c| try p.feed(c);
|
||||||
const command = try p.complete(alloc);
|
const command = try p.complete();
|
||||||
defer command.deinit(alloc);
|
defer command.deinit(alloc);
|
||||||
|
|
||||||
try testing.expect(command.control == .transmit);
|
try testing.expect(command.control == .transmit);
|
||||||
|
Reference in New Issue
Block a user