mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-06-11 01:48:39 +03:00
177 lines
4.7 KiB
Zig
177 lines
4.7 KiB
Zig
const std = @import("std");
|
|
const Allocator = std.mem.Allocator;
|
|
const base = @import("base.zig");
|
|
const c = @import("c.zig").c;
|
|
const cftype = @import("type.zig");
|
|
const ComparisonResult = base.ComparisonResult;
|
|
const Range = base.Range;
|
|
|
|
pub const Array = opaque {
|
|
pub fn create(comptime T: type, values: []*const T) Allocator.Error!*Array {
|
|
return CFArrayCreate(
|
|
null,
|
|
@ptrCast(values.ptr),
|
|
@intCast(values.len),
|
|
null,
|
|
) orelse error.OutOfMemory;
|
|
}
|
|
|
|
pub fn release(self: *Array) void {
|
|
cftype.CFRelease(self);
|
|
}
|
|
|
|
pub fn getCount(self: *Array) usize {
|
|
return CFArrayGetCount(self);
|
|
}
|
|
|
|
/// Note the return type is actually a `*const T` but we strip the
|
|
/// constness so that further API calls work correctly. The Foundation
|
|
/// API doesn't properly mark things const/non-const.
|
|
pub fn getValueAtIndex(self: *Array, comptime T: type, idx: usize) *T {
|
|
return @ptrCast(@alignCast(CFArrayGetValueAtIndex(self, idx)));
|
|
}
|
|
|
|
pub extern "c" fn CFArrayCreate(
|
|
allocator: ?*anyopaque,
|
|
values: [*]*const anyopaque,
|
|
num_values: usize,
|
|
callbacks: ?*const anyopaque,
|
|
) ?*Array;
|
|
pub extern "c" fn CFArrayGetCount(*Array) usize;
|
|
pub extern "c" fn CFArrayGetValueAtIndex(*Array, usize) *anyopaque;
|
|
extern "c" var kCFTypeArrayCallBacks: anyopaque;
|
|
};
|
|
|
|
pub const MutableArray = opaque {
|
|
pub fn create() Allocator.Error!*MutableArray {
|
|
return CFArrayCreateMutable(
|
|
null,
|
|
0,
|
|
&c.kCFTypeArrayCallBacks,
|
|
) orelse error.OutOfMemory;
|
|
}
|
|
|
|
pub fn createCopy(array: *Array) Allocator.Error!*MutableArray {
|
|
return CFArrayCreateMutableCopy(
|
|
null,
|
|
0,
|
|
array,
|
|
) orelse error.OutOfMemory;
|
|
}
|
|
|
|
pub fn release(self: *MutableArray) void {
|
|
cftype.CFRelease(self);
|
|
}
|
|
|
|
pub fn appendValue(
|
|
self: *MutableArray,
|
|
comptime Elem: type,
|
|
value: *const Elem,
|
|
) void {
|
|
CFArrayAppendValue(self, @constCast(@ptrCast(value)));
|
|
}
|
|
|
|
pub fn removeValue(self: *MutableArray, idx: usize) void {
|
|
CFArrayRemoveValueAtIndex(self, idx);
|
|
}
|
|
|
|
pub fn sortValues(
|
|
self: *MutableArray,
|
|
comptime Elem: type,
|
|
comptime Context: type,
|
|
context: ?*Context,
|
|
comptime comparator: ?*const fn (
|
|
a: *const Elem,
|
|
b: *const Elem,
|
|
context: ?*Context,
|
|
) callconv(.C) ComparisonResult,
|
|
) void {
|
|
CFArraySortValues(
|
|
self,
|
|
Range.init(0, Array.CFArrayGetCount(@ptrCast(self))),
|
|
comparator,
|
|
context,
|
|
);
|
|
}
|
|
|
|
extern "c" fn CFArrayCreateMutable(
|
|
allocator: ?*anyopaque,
|
|
capacity: usize,
|
|
callbacks: ?*const anyopaque,
|
|
) ?*MutableArray;
|
|
extern "c" fn CFArrayCreateMutableCopy(
|
|
allocator: ?*anyopaque,
|
|
capacity: usize,
|
|
array: *Array,
|
|
) ?*MutableArray;
|
|
extern "c" fn CFArrayAppendValue(
|
|
*MutableArray,
|
|
*anyopaque,
|
|
) void;
|
|
extern "c" fn CFArrayRemoveValueAtIndex(
|
|
*MutableArray,
|
|
usize,
|
|
) void;
|
|
extern "c" fn CFArraySortValues(
|
|
array: *MutableArray,
|
|
range: Range,
|
|
comparator: ?*const anyopaque,
|
|
context: ?*anyopaque,
|
|
) void;
|
|
};
|
|
|
|
test "array" {
|
|
const testing = std.testing;
|
|
|
|
const str = "hello";
|
|
var values = [_]*const u8{ &str[0], &str[1] };
|
|
const arr = try Array.create(u8, &values);
|
|
defer arr.release();
|
|
|
|
try testing.expectEqual(@as(usize, 2), arr.getCount());
|
|
|
|
{
|
|
const ch = arr.getValueAtIndex(u8, 0);
|
|
try testing.expectEqual(@as(u8, 'h'), ch.*);
|
|
}
|
|
|
|
// Can make it mutable
|
|
var mut = try MutableArray.createCopy(arr);
|
|
defer mut.release();
|
|
}
|
|
|
|
test "array sorting" {
|
|
const testing = std.testing;
|
|
|
|
const str = "hello";
|
|
var values = [_]*const u8{ &str[0], &str[1] };
|
|
const arr = try Array.create(u8, &values);
|
|
defer arr.release();
|
|
const mut = try MutableArray.createCopy(arr);
|
|
defer mut.release();
|
|
|
|
mut.sortValues(
|
|
u8,
|
|
void,
|
|
null,
|
|
struct {
|
|
fn compare(a: *const u8, b: *const u8, _: ?*void) callconv(.C) ComparisonResult {
|
|
if (a.* > b.*) return .greater;
|
|
if (a.* == b.*) return .equal;
|
|
return .less;
|
|
}
|
|
}.compare,
|
|
);
|
|
|
|
{
|
|
const mutarr: *Array = @ptrCast(mut);
|
|
const ch = mutarr.getValueAtIndex(u8, 0);
|
|
try testing.expectEqual(@as(u8, 'e'), ch.*);
|
|
}
|
|
{
|
|
const mutarr: *Array = @ptrCast(mut);
|
|
const ch = mutarr.getValueAtIndex(u8, 1);
|
|
try testing.expectEqual(@as(u8, 'h'), ch.*);
|
|
}
|
|
}
|