-
-
Notifications
You must be signed in to change notification settings - Fork 50
/
cgoutil.go
139 lines (116 loc) · 3.01 KB
/
cgoutil.go
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
package vz
/*
#cgo darwin CFLAGS: -mmacosx-version-min=11 -x objective-c
#cgo darwin LDFLAGS: -lobjc -framework Foundation
#import <Foundation/Foundation.h>
const char *getNSErrorLocalizedDescription(void *err)
{
NSString *ld = (NSString *)[(NSError *)err localizedDescription];
return [ld UTF8String];
}
const char *getNSErrorDomain(void *err)
{
NSString *domain = (NSString *)[(NSError *)err domain];
return [domain UTF8String];
}
const char *getNSErrorUserInfo(void *err)
{
NSDictionary<NSErrorUserInfoKey, id> *ui = [(NSError *)err userInfo];
NSString *uis = [NSString stringWithFormat:@"%@", ui];
return [uis UTF8String];
}
NSInteger getNSErrorCode(void *err)
{
return (NSInteger)[(NSError *)err code];
}
typedef struct NSErrorFlat {
const char *domain;
const char *localizedDescription;
const char *userinfo;
int code;
} NSErrorFlat;
NSErrorFlat convertNSError2Flat(void *err)
{
NSErrorFlat ret;
ret.domain = getNSErrorDomain(err);
ret.localizedDescription = getNSErrorLocalizedDescription(err);
ret.userinfo = getNSErrorUserInfo(err);
ret.code = (int)getNSErrorCode(err);
return ret;
}
void *newNSError()
{
NSError *err = nil;
return err;
}
bool hasError(void *err)
{
return (NSError *)err != nil;
}
*/
import "C"
import (
"fmt"
"unsafe"
"github.com/Code-Hex/vz/v3/internal/objc"
)
// pointer is a type alias which is able to use as embedded type and
// makes as unexported it.
type pointer = objc.Pointer
// NSError indicates NSError.
type NSError struct {
Domain string
Code int
LocalizedDescription string
UserInfo string
}
// newNSErrorAsNil makes nil NSError in objective-c world.
func newNSErrorAsNil() unsafe.Pointer {
return unsafe.Pointer(C.newNSError())
}
// hasNSError checks passed pointer is NSError or not.
func hasNSError(nserrPtr unsafe.Pointer) bool {
return (bool)(C.hasError(nserrPtr))
}
func (n *NSError) Error() string {
if n == nil {
return "<nil>"
}
return fmt.Sprintf(
"Error Domain=%s Code=%d Description=%q UserInfo=%s",
n.Domain,
n.Code,
n.LocalizedDescription,
n.UserInfo,
)
}
func newNSError(p unsafe.Pointer) *NSError {
if !hasNSError(p) {
return nil
}
nsError := C.convertNSError2Flat(p)
return &NSError{
Domain: (*char)(nsError.domain).String(),
Code: int((nsError.code)),
LocalizedDescription: (*char)(nsError.localizedDescription).String(),
UserInfo: (*char)(nsError.userinfo).String(), // NOTE(codehex): maybe we can convert to map[string]interface{}
}
}
// CharWithGoString makes *Char which is *C.Char wrapper from Go string.
func charWithGoString(s string) *char {
return (*char)(unsafe.Pointer(C.CString(s)))
}
// Char is a wrapper of C.char
type char C.char
// CString converts *C.char from *Char
func (c *char) CString() *C.char {
return (*C.char)(c)
}
// String converts Go string from *Char
func (c *char) String() string {
return C.GoString((*C.char)(c))
}
// Free frees allocated *C.char in Go code
func (c *char) Free() {
C.free(unsafe.Pointer(c))
}