1/*
2 * Helper methods opaque-pointer tests (objc.test.test_opaque)
3 */
4#include "Python.h"
5#include "pyobjc-api.h"
6#include <stdarg.h>
7
8#import <Foundation/Foundation.h>
9
10typedef struct _Foo* FooHandle;
11typedef struct _Bar* BarHandle;
12
13@interface OC_OpaqueTest : NSObject
14{
15}
16+(FooHandle)createFoo:(int)value;
17+(FooHandle)nullFoo;
18+(void)deleteFoo:(FooHandle)handle;
19+(int)getValueOf:(FooHandle)foo;
20+(void)setValue:(int)value forFoo:(FooHandle)handle;
21
22
23+(BarHandle)createBarWithFirst:(double)first andSecond:(double)second;
24+(BarHandle)nullBar;
25+(void)getFirst:(double*)first andSecond:(double*)second of:(BarHandle)bar;
26+(void)setFirst:(double)first andSecond:(double)second of:(BarHandle)bar;
27+(void)deleteBar:(BarHandle)handle;
28+(double)getFirst:(BarHandle)handle;
29+(double)getSecond:(BarHandle)handle;
30@end
31
32
33static PyMethodDef mod_methods[] = {
34	        { 0, 0, 0, 0 }
35};
36
37#if PY_VERSION_HEX >= 0x03000000
38
39static struct PyModuleDef mod_module = {
40	PyModuleDef_HEAD_INIT,
41	"opaque",
42	NULL,
43	0,
44	mod_methods,
45	NULL,
46	NULL,
47	NULL,
48	NULL
49};
50
51#define INITERROR() return NULL
52#define INITDONE() return m
53
54PyObject* PyInit_opaque(void);
55
56PyObject*
57PyInit_opaque(void)
58
59#else
60
61#define INITERROR() return
62#define INITDONE() return
63
64void initopaque(void);
65
66void
67initopaque(void)
68#endif
69{
70	PyObject* m;
71
72
73#if PY_VERSION_HEX >= 0x03000000
74	m = PyModule_Create(&mod_module);
75#else
76	m = Py_InitModule4("opaque", mod_methods,
77		NULL, NULL, PYTHON_API_VERSION);
78#endif
79	if (!m) {
80		INITERROR();
81	}
82
83	if (PyObjC_ImportAPI(m) < 0) {
84		INITERROR();
85	}
86
87	if (PyModule_AddObject(m, "OC_OpaqueTest",
88		PyObjCClass_New([OC_OpaqueTest class])) < 0) {
89		INITERROR();
90	}
91	if (PyModule_AddObject(m, "FooHandle",
92		PyObjCCreateOpaquePointerType("FooHandle",
93			                @encode(FooHandle), "FooHandle doc")) < 0) {
94		INITERROR();
95	}
96#if PY_VERSION_HEX >= 0x03000000
97	if (PyModule_AddObject(m, "BarEncoded",  PyBytes_FromString(@encode(BarHandle))) < 0) {
98#else
99	if (PyModule_AddObject(m, "BarEncoded",  PyString_FromString(@encode(BarHandle))) < 0) {
100#endif
101		INITERROR();
102	}
103
104	INITDONE();
105}
106
107/*
108 * Only define the full structs here to ensure that @encode won't include
109 * the field definition into the encoded value.
110 */
111
112struct _Foo {
113	int index;
114};
115
116struct _Bar {
117	double first;
118	double second;
119};
120
121@implementation OC_OpaqueTest
122+(FooHandle)createFoo:(int)value
123{
124	FooHandle result = malloc(sizeof(struct _Foo));
125	if (result == NULL) {
126		return NULL;
127	}
128	result->index = value;
129	return result;
130}
131
132+(FooHandle)nullFoo
133{
134	return NULL;
135}
136
137+(void)deleteFoo:(FooHandle)handle
138{
139	if (handle) {
140		free(handle);
141	}
142}
143
144+(int)getValueOf:(FooHandle)foo
145{
146	return foo->index;
147}
148
149+(void)setValue:(int)value forFoo:(FooHandle)handle
150{
151	handle->index = value;
152}
153
154+(BarHandle)createBarWithFirst:(double)first andSecond:(double)second
155{
156	BarHandle result = malloc(sizeof(struct _Bar));
157	if (result == NULL) return NULL;
158
159	result->first = first;
160	result->second = second;
161	return result;
162}
163
164+(BarHandle)nullBar
165{
166	return NULL;
167}
168
169
170+(void)getFirst:(double*)first andSecond:(double*)second of:(BarHandle)bar
171{
172	*first = bar->first;
173	*second = bar->second;
174}
175
176+(void)setFirst:(double)first andSecond:(double)second of:(BarHandle)bar
177{
178	bar->first = first;
179	bar->second = second;
180}
181
182+(void)deleteBar:(BarHandle)handle
183{
184	if (handle) {
185		free(handle);
186	}
187}
188
189+(double)getFirst:(BarHandle)handle
190{
191	return handle->first;
192}
193
194+(double)getSecond:(BarHandle)handle
195{
196	return handle->second;
197}
198
199@end
200