-
Notifications
You must be signed in to change notification settings - Fork 1
/
protocol.go
137 lines (100 loc) · 4.06 KB
/
protocol.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
package objc
// #include <stdlib.h>
// #include <objc/runtime.h>
import "C"
import "unsafe"
type Protocol *C.Protocol
func Protocol_addMethodDescription(proto Protocol, name Sel, types string, isRequiredMethod bool, isInstanceMethod bool) {
ctypes := C.CString(types)
defer free(unsafe.Pointer(ctypes))
C.protocol_addMethodDescription(proto, name, ctypes, CBool(isRequiredMethod), CBool(isInstanceMethod))
}
func Protocol_addProtocol(proto Protocol, addition Protocol) {
C.protocol_addProtocol(proto, addition)
}
func Protocol_addProperty(proto Protocol, name string, attributes []PropertyAttribute, isRequiredProperty bool, isInstanceProperty bool) {
var cattributes *C.objc_property_attribute_t
cname := C.CString(name)
defer free(unsafe.Pointer(cname))
attrSize := unsafe.Sizeof(*cattributes)
attributeCount := len(attributes)
if len(attributes) != 0 {
cattributes = (*C.objc_property_attribute_t)(calloc(uint(attributeCount), attrSize))
defer func(cattributes *C.objc_property_attribute_t, attributeCount int) {
for i, elem := 0, cattributes; i < attributeCount; i++ {
free(unsafe.Pointer(elem.name))
free(unsafe.Pointer(elem.value))
elem = nextPropertyAttr(elem)
}
free(unsafe.Pointer(cattributes))
}(cattributes, attributeCount)
for i, elem := 0, cattributes; i < attributeCount; i++ {
attr := attributes[i]
elem.name = C.CString(attr.Name)
elem.value = C.CString(attr.Value)
elem = nextPropertyAttr(elem)
}
}
C.protocol_addProperty(proto, cname, cattributes, C.uint(attributeCount), CBool(isRequiredProperty), CBool(isInstanceProperty))
}
func Protocol_getName(p Protocol) string {
return C.GoString(C.protocol_getName(p))
}
func Protocol_isEqual(proto Protocol, other Protocol) bool {
return C.protocol_isEqual(proto, other) != 0
}
func Protocol_copyMethodDescriptionList(p Protocol, isRequiredMethod bool, isInstanceMethod bool) (descriptions []MethodDescription) {
var coutCount C.uint
descriptionList := C.protocol_copyMethodDescriptionList(p, CBool(isRequiredMethod), CBool(isInstanceMethod), &coutCount)
defer free(unsafe.Pointer(descriptionList))
if outCount := uint(coutCount); outCount > 0 {
descriptions = make([]MethodDescription, outCount)
for i, elem := uint(0), descriptionList; i < outCount; i++ {
descriptions[i] = makeMethodDescription(*elem)
elem = nextMethodDescription(elem)
}
}
return
}
func Protocol_getMethodDescription(p Protocol, aSel Sel, isRequiredMethod bool, isInstanceMethod bool) MethodDescription {
cmethodDescription := C.protocol_getMethodDescription(p, aSel, CBool(isRequiredMethod), CBool(isInstanceMethod))
return makeMethodDescription(cmethodDescription)
}
func Protocol_copyPropertyList(protocol Protocol) (properties []Property) {
var coutCount C.uint
propertyList := C.protocol_copyPropertyList(protocol, &coutCount)
defer free(unsafe.Pointer(propertyList))
if outCount := uint(coutCount); outCount > 0 {
properties = make([]Property, outCount)
for i, elem := uint(0), propertyList; i < outCount; i++ {
properties[i] = Property(*elem)
elem = nextProperty(elem)
}
}
return
}
func Protocol_getProperty(proto Protocol, name string, isRequiredProperty bool, isInstanceProperty bool) Property {
cname := C.CString(name)
defer free(unsafe.Pointer(cname))
return Property(C.protocol_getProperty(proto, cname, CBool(isRequiredProperty), CBool(isInstanceProperty)))
}
func Protocol_copyProtocolList(proto Protocol) (protocols []Protocol) {
var coutCount C.uint
protocolList := C.protocol_copyProtocolList(proto, &coutCount)
defer free(unsafe.Pointer(protocolList))
if outCount := uint(coutCount); outCount > 0 {
protocols = make([]Protocol, outCount)
for i, elem := uint(0), protocolList; i < outCount; i++ {
protocols[i] = Protocol(*elem)
elem = nextProtocol(elem)
}
}
return
}
func Protocol_conformsToProtocol(proto Protocol, other Protocol) bool {
return C.protocol_conformsToProtocol(proto, other) != 0
}
func nextProtocol(list **C.Protocol) **C.Protocol {
ptr := uintptr(unsafe.Pointer(list)) + unsafe.Sizeof(*list)
return (**C.Protocol)(unsafe.Pointer(ptr))
}