1/* 2 * Wrappers for methods with callback functions. 3 */ 4#include "Python.h" 5#include "pyobjc-api.h" 6 7#import <Foundation/Foundation.h> 8 9static int 10SortHelperFunc(id arg1, id arg2, void* opaque) 11{ 12 PyObjC_BEGIN_WITH_GIL 13 14 PyObject* func = PyTuple_GetItem((PyObject*)opaque, 0); 15 PyObject* context = PyTuple_GetItem((PyObject*)opaque, 1); 16 PyObject* a1; 17 PyObject* a2; 18 PyObject* r; 19 int res; 20 21 if (func == NULL || context == NULL) { 22 PyObjC_GIL_FORWARD_EXC(); 23 } 24 25 a1 = PyObjC_IdToPython(arg1); 26 if (a1 == NULL) { 27 PyObjC_GIL_FORWARD_EXC(); 28 } 29 30 a2 = PyObjC_IdToPython(arg2); 31 if (a2 == NULL) { 32 Py_DECREF(a1); 33 PyObjC_GIL_FORWARD_EXC(); 34 } 35 36 r = PyObject_CallFunction(func, "OOO", a1, a2, context); 37 Py_DECREF(a1); 38 Py_DECREF(a2); 39 if (r == NULL) { 40 PyObjC_GIL_FORWARD_EXC(); 41 } 42 43 if (PyObjC_PythonToObjC(@encode(int), r, &res) < 0) { 44 Py_DECREF(r); 45 PyObjC_GIL_FORWARD_EXC(); 46 } 47 Py_DECREF(r); 48 49 PyObjC_GIL_RETURN(res); 50 PyObjC_END_WITH_GIL 51 52} 53 54static PyObject* 55call_NSArray_sortedArrayUsingFunction_context_( 56 PyObject* method, PyObject* self, PyObject* arguments) 57{ 58 PyObject* result; 59 struct objc_super super; 60 PyObject* sortFunc; 61 PyObject* context; 62 PyObject* realContext; 63 id res; 64 65 if (!PyArg_ParseTuple(arguments, "OO", &sortFunc, &context)) { 66 return NULL; 67 } 68 69 realContext = PyTuple_New(2); 70 if (realContext == NULL) { 71 return NULL; 72 } 73 PyTuple_SET_ITEM(realContext, 0, sortFunc); 74 Py_INCREF(sortFunc); 75 PyTuple_SET_ITEM(realContext, 1, context); 76 Py_INCREF(context); 77 78 PyObjC_DURING 79 if (PyObjCIMP_Check(method)) { 80 res = ((id(*)(id,SEL, int(*)(id, id, void*), void*)) 81 (PyObjCIMP_GetIMP(method)))( 82 PyObjCObject_GetObject(self), 83 PyObjCIMP_GetSelector(method), 84 SortHelperFunc, realContext); 85 } else { 86 PyObjC_InitSuper(&super, 87 PyObjCSelector_GetClass(method), 88 PyObjCObject_GetObject(self)); 89 90 91 res = objc_msgSendSuper(&super, 92 PyObjCSelector_GetSelector(method), 93 SortHelperFunc, realContext); 94 } 95 PyObjC_HANDLER 96 PyObjCErr_FromObjC(localException); 97 res = nil; 98 PyObjC_ENDHANDLER 99 100 Py_DECREF(realContext); 101 102 if (res == nil && PyErr_Occurred()) { 103 return NULL; 104 } 105 106 result = PyObjC_IdToPython(res); 107 108 return result; 109} 110 111static PyObject* 112call_NSArray_sortedArrayUsingFunction_context_hint_( 113 PyObject* method, PyObject* self, PyObject* arguments) 114{ 115 PyObject* result; 116 struct objc_super super; 117 PyObject* sortFunc; 118 PyObject* context; 119 id hint = nil; 120 PyObject* realContext; 121 id res; 122 123 if (!PyArg_ParseTuple(arguments, "OOO&", &sortFunc, &context, 124 PyObjCObject_Convert, &hint)) { 125 return NULL; 126 } 127 128 realContext = PyTuple_New(2); 129 if (realContext == NULL) { 130 return NULL; 131 } 132 PyTuple_SET_ITEM(realContext, 0, sortFunc); 133 Py_INCREF(sortFunc); 134 PyTuple_SET_ITEM(realContext, 1, context); 135 Py_INCREF(context); 136 137 PyObjC_DURING 138 if (PyObjCIMP_Check(method)) { 139 res = ((id(*)(id,SEL, int(*)(id, id, void*), void*, id)) 140 (PyObjCIMP_GetIMP(method)))( 141 PyObjCObject_GetObject(self), 142 PyObjCIMP_GetSelector(method), 143 SortHelperFunc, realContext, hint); 144 } else { 145 PyObjC_InitSuper(&super, 146 PyObjCSelector_GetClass(method), 147 PyObjCObject_GetObject(self)); 148 149 res = objc_msgSendSuper(&super, 150 PyObjCSelector_GetSelector(method), 151 SortHelperFunc, realContext, hint); 152 } 153 PyObjC_HANDLER 154 PyObjCErr_FromObjC(localException); 155 res = nil; 156 PyObjC_ENDHANDLER 157 158 Py_DECREF(realContext); 159 160 if (res == nil && PyErr_Occurred()) { 161 return NULL; 162 } 163 164 result = PyObjC_IdToPython(res); 165 166 return result; 167} 168 169 170static PyObject* 171call_NSMutableArray_sortUsingFunction_context_( 172 PyObject* method, PyObject* self, PyObject* arguments) 173{ 174 PyObject* result; 175 struct objc_super super; 176 PyObject* sortFunc; 177 PyObject* context; 178 PyObject* realContext; 179 id res; 180 181 if (!PyArg_ParseTuple(arguments, "OO", &sortFunc, &context)) { 182 return NULL; 183 } 184 185 realContext = PyTuple_New(2); 186 if (realContext == NULL) { 187 return NULL; 188 } 189 PyTuple_SET_ITEM(realContext, 0, sortFunc); 190 Py_INCREF(sortFunc); 191 PyTuple_SET_ITEM(realContext, 1, context); 192 Py_INCREF(context); 193 194 PyObjC_DURING 195 PyObjC_InitSuper(&super, 196 PyObjCSelector_GetClass(method), 197 PyObjCObject_GetObject(self)); 198 199 200 (void)objc_msgSendSuper(&super, 201 @selector(sortUsingFunction:context:), 202 SortHelperFunc, realContext); 203 res = nil; 204 PyObjC_HANDLER 205 PyObjCErr_FromObjC(localException); 206 res = nil; 207 PyObjC_ENDHANDLER 208 209 Py_DECREF(realContext); 210 211 if (res == nil && PyErr_Occurred()) { 212 return NULL; 213 } 214 215 result = PyObjC_IdToPython(res); 216 217 return result; 218} 219 220static PyObject* 221call_NSMutableArray_sortUsingFunction_context_range_( 222 PyObject* method, PyObject* self, PyObject* arguments) 223{ 224 PyObject* result; 225 struct objc_super super; 226 PyObject* sortFunc; 227 PyObject* context; 228 PyObject* rangeObj; 229 NSRange range; 230 PyObject* realContext; 231 id res; 232 233 if (!PyArg_ParseTuple(arguments, "OOO", &sortFunc, &context, 234 &rangeObj)) { 235 return NULL; 236 } 237 238 if (PyObjC_PythonToObjC(@encode(NSRange), rangeObj, &range) < 0) { 239 return NULL; 240 } 241 242 realContext = PyTuple_New(2); 243 if (realContext == NULL) { 244 return NULL; 245 } 246 PyTuple_SET_ITEM(realContext, 0, sortFunc); 247 Py_INCREF(sortFunc); 248 PyTuple_SET_ITEM(realContext, 1, context); 249 Py_INCREF(context); 250 251 PyObjC_DURING 252 PyObjC_InitSuper(&super, 253 PyObjCSelector_GetClass(method), 254 PyObjCObject_GetObject(self)); 255 256 257 (void)objc_msgSendSuper(&super, 258 @selector(sortUsingFunction:context:range:), 259 SortHelperFunc, realContext, range); 260 res = nil; 261 PyObjC_HANDLER 262 PyObjCErr_FromObjC(localException); 263 res = nil; 264 PyObjC_ENDHANDLER 265 266 Py_DECREF(realContext); 267 268 if (res == nil && PyErr_Occurred()) { 269 return NULL; 270 } 271 272 result = PyObjC_IdToPython(res); 273 274 return result; 275} 276 277PyDoc_STRVAR(mod_doc, ""); 278 279static PyMethodDef mod_methods[] = { 280 { 0, 0, 0, 0 } /* sentinel */ 281}; 282 283 284 285void init_functioncallbacks(void); 286 287void 288init_functioncallbacks(void) 289{ 290 PyObject* m = Py_InitModule4("_functioncallbacks", mod_methods, 291 mod_doc, NULL, PYTHON_API_VERSION); 292 293 if (PyObjC_ImportAPI(m) < 0) { return; } 294 295 Class classNSArray = objc_lookUpClass("NSArray"); 296 297 /* XXX: this one is mostly here because I'd like to add support someday 298 */ 299 if (PyObjC_RegisterMethodMapping( 300 classNSArray, 301 @selector(apply:context:), 302 PyObjCUnsupportedMethod_Caller, 303 PyObjCUnsupportedMethod_IMP) < 0) { 304 305 return; 306 } 307 308 if (PyObjC_RegisterMethodMapping( 309 classNSArray, 310 @selector(sortedArrayUsingFunction:context:), 311 call_NSArray_sortedArrayUsingFunction_context_, 312 PyObjCUnsupportedMethod_IMP) < 0) { 313 314 return; 315 } 316 317 if (PyObjC_RegisterMethodMapping( 318 classNSArray, 319 @selector(sortedArrayUsingFunction:context:hint:), 320 call_NSArray_sortedArrayUsingFunction_context_hint_, 321 PyObjCUnsupportedMethod_IMP) < 0) { 322 323 return; 324 } 325 326 327 328 Class classNSMutableArray = objc_lookUpClass("NSMutableArray"); 329 330 if (PyObjC_RegisterMethodMapping( 331 classNSMutableArray, 332 @selector(sortUsingFunction:context:), 333 call_NSMutableArray_sortUsingFunction_context_, 334 PyObjCUnsupportedMethod_IMP) < 0) { 335 336 return; 337 } 338 339 if (PyObjC_RegisterMethodMapping( 340 classNSMutableArray, 341 @selector(sortUsingFunction:context:range:), 342 call_NSMutableArray_sortUsingFunction_context_range_, 343 PyObjCUnsupportedMethod_IMP) < 0) { 344 345 return; 346 } 347} 348