2022-10-01 11:06:07 -07:00

56 lines
1.6 KiB
Zig

const std = @import("std");
const Allocator = std.mem.Allocator;
const cftype = @import("type.zig");
pub const Array = opaque {
pub fn create(comptime T: type, values: []*const T) Allocator.Error!*Array {
return CFArrayCreate(
null,
@ptrCast([*]*const anyopaque, values.ptr),
@intCast(usize, 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(*T, 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;
};
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.*);
}
}