comparison python/pydc/pydcext.c @ 34:2682a627168c

- breaking changes: * restrict 'Z' conversions to immutable types * restrict 'p' to mutable types (and handles)
author Tassilo Philipp
date Sun, 12 Apr 2020 19:37:37 +0200
parents ba47a3d709d7
children 75fe1dec0eb4
comparison
equal deleted inserted replaced
33:ba47a3d709d7 34:2682a627168c
323 if (!PyFloat_Check(po)) 323 if (!PyFloat_Check(po))
324 return PyErr_Format( PyExc_RuntimeError, "arg %d - expeecting a float", pos ); 324 return PyErr_Format( PyExc_RuntimeError, "arg %d - expeecting a float", pos );
325 dcArgDouble(gpCall, PyFloat_AsDouble(po)); 325 dcArgDouble(gpCall, PyFloat_AsDouble(po));
326 break; 326 break;
327 327
328 case DC_SIGCHAR_POINTER: 328 case DC_SIGCHAR_POINTER: // this will only accept integers or mutable array types (meaning only bytearray)
329 {
330 DCpointer p;
331 if ( PyByteArray_Check(po) )
332 p = (DCpointer) PyByteArray_AsString(po); // adds an extra '\0', but that's ok
333 #if PY_MAJOR_VERSION < 3
334 else if ( PyInt_Check(po) )
335 p = (DCpointer) PyInt_AS_LONG(po);
336 #endif
337 else if ( PyLong_Check(po) )
338 p = (DCpointer) PyLong_AsVoidPtr(po);
339 else
340 return PyErr_Format( PyExc_RuntimeError, "arg %d - expecting a promoting pointer-type (int, bytearray)", pos );
341 dcArgPointer(gpCall, p);
342 }
343 break;
344
345 case DC_SIGCHAR_STRING: // strings are considered to be immutable objects
329 { 346 {
330 PyObject* bo = NULL; 347 PyObject* bo = NULL;
331 DCpointer p; 348 const char* p;
349 char* p_;
350 size_t s;
332 if ( PyUnicode_Check(po) ) { 351 if ( PyUnicode_Check(po) ) {
333 if((bo = PyUnicode_AsEncodedString(po, "utf-8", "strict"))) // !new ref! 352 if((bo = PyUnicode_AsEncodedString(po, "utf-8", "strict"))) // !new ref!
334 p = PyBytes_AS_STRING(bo); // Borrowed pointer 353 p = PyBytes_AS_STRING(bo); // Borrowed pointer
335 } else if ( DcPyString_Check(po) ) 354 } else if ( DcPyString_Check(po) )
336 p = (DCpointer) DcPyString_AsString(po); 355 p = DcPyString_AsString(po); //@@@ must not be modified in any way
337 #if PY_MAJOR_VERSION < 3 356 else if ( PyByteArray_Check(po) )
338 else if ( PyInt_Check(po) ) 357 p = (DCpointer) PyByteArray_AsString(po); // adds an extra '\0', but that's ok //@@@ not sure if allowed to modify
339 p = (DCpointer) PyInt_AS_LONG(po);
340 #endif
341 else if ( PyLong_Check(po) )
342 p = (DCpointer) PyLong_AsVoidPtr(po);
343 else 358 else
344 return PyErr_Format( PyExc_RuntimeError, "arg %d - expecting a promoting pointer-type (int,str)", pos ); 359 return PyErr_Format( PyExc_RuntimeError, "arg %d - expecting a str", pos );
345 dcArgPointer(gpCall, p); 360
361 // pointer points in any case to a buffer that shouldn't be modified, so pass a copy of the string to dyncall
362 s = strlen(p)+1;
363 p_ = malloc(s);
364 strncpy(p_, p, s);
346 Py_XDECREF(bo); 365 Py_XDECREF(bo);
347 } 366 dcArgPointer(gpCall, (DCpointer)p_);
348 break; 367 free(p_);
349
350 case DC_SIGCHAR_STRING:
351 {
352 PyObject* bo = NULL;
353 const char* p;
354 if ( PyUnicode_Check(po) ) {
355 if((bo = PyUnicode_AsEncodedString(po, "utf-8", "strict"))) // !new ref!
356 p = PyBytes_AS_STRING(bo); // Borrowed pointer
357 } else if ( DcPyString_Check(po) ) {
358 p = DcPyString_AsString(po);
359 } else
360 return PyErr_Format( PyExc_RuntimeError, "arg %d - expecting a str", pos );
361 dcArgPointer(gpCall, (DCpointer) p);
362 Py_XDECREF(bo);
363 } 368 }
364 break; 369 break;
365 370
366 default: 371 default:
367 return PyErr_Format( PyExc_RuntimeError, "unknown signature character '%c'", ch); 372 return PyErr_Format( PyExc_RuntimeError, "unknown signature character '%c'", ch);