summaryrefslogtreecommitdiff
path: root/pkg/macos/foundation/url.zig
blob: b48a7181759e2cdd58661fee6027f0124433fdba (plain)
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
const std = @import("std");
const Allocator = std.mem.Allocator;
const foundation = @import("../foundation.zig");
const c = @import("c.zig").c;

pub const URL = opaque {
    pub fn createWithString(str: *foundation.String, base: ?*URL) Allocator.Error!*URL {
        return CFURLCreateWithString(
            null,
            str,
            base,
        ) orelse error.OutOfMemory;
    }

    pub fn createWithFileSystemPath(
        path: *foundation.String,
        style: URLPathStyle,
        dir: bool,
    ) Allocator.Error!*URL {
        return @as(
            ?*URL,
            @ptrFromInt(@intFromPtr(c.CFURLCreateWithFileSystemPath(
                null,
                @ptrCast(path),
                @intFromEnum(style),
                if (dir) 1 else 0,
            ))),
        ) orelse error.OutOfMemory;
    }

    pub fn createStringByReplacingPercentEscapes(
        str: *foundation.String,
        escape: *foundation.String,
    ) Allocator.Error!*foundation.String {
        return CFURLCreateStringByReplacingPercentEscapes(
            null,
            str,
            escape,
        ) orelse return error.OutOfMemory;
    }

    pub fn release(self: *URL) void {
        foundation.CFRelease(self);
    }

    pub fn copyPath(self: *URL) ?*foundation.String {
        return CFURLCopyPath(self);
    }

    pub extern "c" fn CFURLCreateWithString(
        allocator: ?*anyopaque,
        url_string: *const anyopaque,
        base_url: ?*const anyopaque,
    ) ?*URL;
    pub extern "c" fn CFURLCopyPath(*URL) ?*foundation.String;
    pub extern "c" fn CFURLCreateStringByReplacingPercentEscapes(
        allocator: ?*anyopaque,
        original: *const anyopaque,
        escape: *const anyopaque,
    ) ?*foundation.String;
};

pub const URLPathStyle = enum(c_int) {
    posix = c.kCFURLPOSIXPathStyle,
    windows = c.kCFURLWindowsPathStyle,
};

test {
    const testing = std.testing;

    const str = try foundation.String.createWithBytes("http://www.example.com/foo", .utf8, false);
    defer str.release();

    const url = try URL.createWithString(str, null);
    defer url.release();

    {
        const path = url.copyPath().?;
        defer path.release();

        var buf: [128]u8 = undefined;
        const cstr = path.cstring(&buf, .utf8).?;
        try testing.expectEqualStrings("/foo", cstr);
    }
}

test "path" {
    const testing = std.testing;

    const str = try foundation.String.createWithBytes("foo/bar.ttf", .utf8, false);
    defer str.release();

    const url = try URL.createWithFileSystemPath(str, .posix, false);
    defer url.release();

    {
        const path = url.copyPath().?;
        defer path.release();

        var buf: [128]u8 = undefined;
        const cstr = path.cstring(&buf, .utf8).?;
        try testing.expectEqualStrings("foo/bar.ttf", cstr);
    }
}