lib/sys/src/apple/foundation.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

 1 const std = @import("std");
 2 const apple = @import("root.zig");
 3 
 4 pub const NSUInteger = u64;
 5 pub const NSInteger = i64;
 6 pub const String = *opaque {};
 7 pub const Error = *opaque {};
 8 
 9 const utf8_string_encoding: NSUInteger = 4;
10 
11 pub const AutoreleasePool = struct {
12     handle: apple.objc.Id,
13 
14     pub fn init() ?AutoreleasePool {
15         const pool_class = apple.objc.class("NSAutoreleasePool") orelse return null;
16         const allocated = apple.objc.send(?apple.objc.Id, pool_class, apple.objc.selector("alloc"), .{}) orelse return null;
17         const initialized = apple.objc.send(?apple.objc.Id, allocated, apple.objc.selector("init"), .{}) orelse return null;
18         return .{ .handle = initialized };
19     }
20 
21     pub fn deinit(self: *AutoreleasePool) void {
22         apple.objc.send(void, self.handle, apple.objc.selector("drain"), .{});
23         self.* = undefined;
24     }
25 };
26 
27 pub fn stringFromBytes(bytes: []const u8) ?String {
28     if (bytes.len == 0) return null;
29     const string_class = apple.objc.class("NSString") orelse return null;
30     const allocated = apple.objc.send(?apple.objc.Id, string_class, apple.objc.selector("alloc"), .{}) orelse return null;
31     return apple.objc.send(
32         ?String,
33         allocated,
34         apple.objc.selector("initWithBytes:length:encoding:"),
35         .{ bytes.ptr, bytes.len, utf8_string_encoding },
36     );
37 }
38 
39 /// The string's UTF-8 bytes, valid while the string lives and the current autorelease pool stands.
40 pub fn utf8(string: String) ?[*:0]const u8 {
41     return apple.objc.send(?[*:0]const u8, @ptrCast(string), apple.objc.selector("UTF8String"), .{});
42 }
43 
44 /// The error's localized description, autoreleased.
45 pub fn errorDescription(error_object: Error) ?String {
46     return apple.objc.send(?String, @ptrCast(error_object), apple.objc.selector("localizedDescription"), .{});
47 }
48 
49 pub fn errorCode(error_object: Error) NSInteger {
50     return apple.objc.send(NSInteger, @ptrCast(error_object), apple.objc.selector("code"), .{});
51 }
52 
53 test "Foundation uses the 64-bit Apple scalar ABI" {
54     try std.testing.expectEqual(@as(usize, 8), @sizeOf(NSUInteger));
55     try std.testing.expectEqual(@as(usize, 8), @sizeOf(NSInteger));
56     try std.testing.expectEqual(@sizeOf(usize), @sizeOf(String));
57     try std.testing.expectEqual(@sizeOf(usize), @sizeOf(Error));
58     try std.testing.expectEqual(@sizeOf(usize), @sizeOf(AutoreleasePool));
59 }