1/* 2 * Special wrappers for NSString methods with 'difficult' arguments. 3 * 4 * -getCString:maxLength:range:remainingRange: [call] 5 * -getCString:maxLength: [call] 6 * 7 */ 8 9static PyObject* 10call_NSString_getCString_maxLength_range_remainingRange_( 11 PyObject* method, PyObject* self, PyObject* arguments) 12{ 13 PyObject* rangeObj; 14 NSRange aRange; 15 NSRange leftoverRange; 16 NSRange* leftoverPtr; 17 char* buf; 18 NSUInteger maxLength; 19 struct objc_super super; 20 PyObject* res; 21 PyObject* buf1, *buf2; 22 23 if (!PyArg_ParseTuple(arguments, "O" Py_ARG_NSUInteger "OO", &buf1, &maxLength, &rangeObj, &buf2)) { 24 return NULL; 25 } 26 27 if (PyObjC_PythonToObjC(@encode(NSRange), rangeObj, &aRange) < 0) { 28 return NULL; 29 } 30 31 if (buf1 != Py_None) { 32 PyErr_SetString(PyExc_ValueError, "output buffer must be None"); 33 return NULL; 34 } 35 if (buf2 != Py_None && buf2 != PyObjC_NULL) { 36 PyErr_SetString(PyExc_ValueError, "range buffer must be None or NULL"); 37 return NULL; 38 } 39 if (buf2 == PyObjC_NULL) { 40 leftoverPtr = NULL; 41 } else { 42 leftoverPtr = &leftoverRange; 43 } 44 45 46 buf = malloc(maxLength+1); 47 if (buf == NULL) { 48 PyErr_NoMemory(); 49 return NULL; 50 } 51 52 PyObjC_DURING 53 PyObjC_InitSuper(&super, 54 PyObjCSelector_GetClass(method), 55 PyObjCObject_GetObject(self)); 56 57 ((void(*)(struct objc_super*, SEL, void*, NSInteger, NSRange, NSRange*))objc_msgSendSuper)(&super, 58 @selector(getCString:maxLength:range:remainingRange:), 59 buf, maxLength, aRange, leftoverPtr); 60 PyObjC_HANDLER 61 PyObjCErr_FromObjC(localException); 62 PyObjC_ENDHANDLER 63 64 if (PyErr_Occurred()) { 65 free(buf); 66 return NULL; 67 } 68 69 res = PyTuple_New(2); 70 if (res == NULL) { 71 free(buf); 72 return NULL; 73 } 74 75 PyTuple_SET_ITEM(res, 0, PyBytes_FromString(buf)); 76 free(buf); 77 if (PyErr_Occurred()) { 78 Py_DECREF(res); 79 free(buf); 80 return NULL; 81 } 82 83 if (leftoverPtr != NULL) { 84 rangeObj = PyObjC_ObjCToPython(@encode(NSRange), &leftoverRange); 85 if (rangeObj == NULL) { 86 Py_DECREF(res); 87 return NULL; 88 } 89 90 PyTuple_SET_ITEM(res, 1, rangeObj); 91 } else { 92 PyTuple_SET_ITEM(res, 1, PyObjC_NULL); 93 } 94 return res; 95} 96 97static PyObject* 98call_NSString_getCString_maxLength_( 99 PyObject* method, PyObject* self, PyObject* arguments) 100{ 101 char* buf; 102 NSUInteger maxLength; 103 struct objc_super super; 104 PyObject* res; 105 PyObject* py_buf; 106 107 if (!PyArg_ParseTuple(arguments, "O" Py_ARG_NSUInteger, &py_buf, &maxLength)) { 108 return NULL; 109 } 110 if (py_buf != Py_None) { 111 PyErr_SetString(PyExc_ValueError, "buffer must be None"); 112 return NULL; 113 } 114 115 buf = malloc(maxLength+1); 116 if (buf == NULL) { 117 PyErr_NoMemory(); 118 return NULL; 119 } 120 121 PyObjC_DURING 122 PyObjC_InitSuper(&super, 123 PyObjCSelector_GetClass(method), 124 PyObjCObject_GetObject(self)); 125 126 ((void(*)(struct objc_super*, SEL, void*, NSUInteger))objc_msgSendSuper)(&super, 127 @selector(getCString:maxLength:), 128 buf, maxLength); 129 PyObjC_HANDLER 130 PyObjCErr_FromObjC(localException); 131 PyObjC_ENDHANDLER 132 133 if (PyErr_Occurred()) { 134 free(buf); 135 return NULL; 136 } 137 138 res = PyBytes_FromString(buf); 139 free(buf); 140 if (res == NULL) { 141 return NULL; 142 } 143 144 return res; 145} 146 147static int setup_nssstring(PyObject* m __attribute__((__unused__))) 148{ 149 Class classNSString = objc_lookUpClass("NSString"); 150 if (classNSString == NULL) { 151 return 0; 152 } 153 154 if (PyObjC_RegisterMethodMapping( 155 classNSString, 156 @selector(getCString:maxLength:range:remainingRange:), 157 call_NSString_getCString_maxLength_range_remainingRange_, 158 PyObjCUnsupportedMethod_IMP) < 0) { 159 160 return -1; 161 } 162 163 if (PyObjC_RegisterMethodMapping( 164 classNSString, 165 @selector(getCString:maxLength:), 166 call_NSString_getCString_maxLength_, 167 PyObjCUnsupportedMethod_IMP) < 0) { 168 169 return -1; 170 } 171 172 return 0; 173} 174