diff options
author | Jack Jansen <jack.jansen@cwi.nl> | 2002-05-05 21:48:12 (GMT) |
---|---|---|
committer | Jack Jansen <jack.jansen@cwi.nl> | 2002-05-05 21:48:12 (GMT) |
commit | efaffae8f6f6f0d1482e6931f851b1c7264c554d (patch) | |
tree | ca7a7d0d134cde187cc446ed54194fa510109904 /Mac | |
parent | 46c04e140cf26d1b44935c28c6f15ea467400d22 (diff) | |
download | cpython-efaffae8f6f6f0d1482e6931f851b1c7264c554d.zip cpython-efaffae8f6f6f0d1482e6931f851b1c7264c554d.tar.gz cpython-efaffae8f6f6f0d1482e6931f851b1c7264c554d.tar.bz2 |
First steps towards a generalized converter of Python object
hierarchies to CoreFoundation object hierarchies and vice versa.
Diffstat (limited to 'Mac')
-rw-r--r-- | Mac/Modules/cf/pycfbridge.c | 206 | ||||
-rw-r--r-- | Mac/Modules/cf/pycfbridge.h | 11 |
2 files changed, 217 insertions, 0 deletions
diff --git a/Mac/Modules/cf/pycfbridge.c b/Mac/Modules/cf/pycfbridge.c new file mode 100644 index 0000000..76c5ad4 --- /dev/null +++ b/Mac/Modules/cf/pycfbridge.c @@ -0,0 +1,206 @@ +/* +** Convert objects from Python to CoreFoundation and vice-versa. +*/ + +#ifdef WITHOUT_FRAMEWORKS +#include <CFBase.h> +#include <CFArray.h> +#include <CFData.h> +#include <CFDictionary.h> +#include <CFString.h> +#include <CFURL.h> +#else +#include <CoreServices/CoreServices.h> +#endif + +#include "Python.h" +#include "macglue.h" +#include "pycfbridge.h" + + +/* ---------------------------------------- */ +/* CoreFoundation objects to Python objects */ +/* ---------------------------------------- */ + +PyObject * +PyCF_CF2Python(CFTypeRef src) { + CFTypeID typeid; + + typeid = CFGetTypeID(src); + if (typeid == CFArrayGetTypeID()) + return PyCF_CF2Python_sequence((CFArrayRef)src); + if (typeid == CFDictionaryGetTypeID()) + return PyCF_CF2Python_mapping((CFDictionaryRef)src); + return PyCF_CF2Python_simple(src); +} + +PyObject * +PyCF_CF2Python_sequence(CFArrayRef src) { + PyErr_SetString(PyExc_SystemError, "Not yet implemented"); + return NULL; +} + +PyObject * +PyCF_CF2Python_mapping(CFTypeRef src) { + PyErr_SetString(PyExc_SystemError, "Not yet implemented"); + return NULL; +} + +PyObject * +PyCF_CF2Python_simple(CFTypeRef src) { + CFTypeID typeid; + + typeid = CFGetTypeID(src); + if (typeid == CFStringGetTypeID()) + return PyCF_CF2Python_string((CFStringRef)src); + PyMac_Error(resNotFound); + return NULL; +} + +/* Unsure - Return unicode or 8 bit strings? */ +PyObject * +PyCF_CF2Python_string(CFStringRef src) { + int size = CFStringGetLength(src)+1; + Py_UNICODE *data = malloc(size*sizeof(Py_UNICODE)); + CFRange range; + PyObject *rv; + + range.location = 0; + range.length = size; + if( data == NULL ) return PyErr_NoMemory(); + CFStringGetCharacters(src, range, data); + rv = (PyObject *)PyUnicode_FromUnicode(data, size); + free(data); + return rv; +} + +/* ---------------------------------------- */ +/* Python objects to CoreFoundation objects */ +/* ---------------------------------------- */ + +int +PyCF_Python2CF(PyObject *src, CFTypeRef *dst) { + + if (PySequence_Check(src)) + return PyCF_Python2CF_sequence(src, (CFArrayRef *)dst); + if (PyMapping_Check(src)) + return PyCF_Python2CF_mapping(src, (CFDictionaryRef *)dst); + return PyCF_Python2CF_simple(src, dst); +} + +int +PyCF_Python2CF_sequence(PyObject *src, CFArrayRef *dst) { + CFArrayRef rv = NULL; + CFTypeRef item_cf = NULL; + PyObject *item_py = NULL; + int size, i; + + size = PySequence_Size(src); + rv = CFArrayCreateMutable((CFAllocatorRef)NULL, size, &kCFTypeArrayCallBacks); + if (rv == NULL) { + PyMac_Error(resNotFound); + goto err; + } + + for( i=0; i<size; i++) { + item_py = PySequence_GetItem(src, i); + if (item_py == NULL) goto err; + if ( !PyCF_Python2CF(item_py, &item_cf)) goto err; + Py_DECREF(item_py); + CFArraySetValueAtIndex(rv, i, item_cf); + CFRelease(item_cf); + item_cf = NULL; + } + *dst = rv; + return 1; +err: + Py_XDECREF(item_py); + if (rv) CFRelease(rv); + if (item_cf) CFRelease(item_cf); + return 0; +} + +int +PyCF_Python2CF_mapping(PyObject *src, CFDictionaryRef *dst) { + CFDictionaryRef rv = NULL; + PyObject *aslist = NULL; + CFTypeRef key_cf = NULL, value_cf = NULL; + PyObject *item_py = NULL, *key_py = NULL, *value_py = NULL; + int size, i; + + size = PyMapping_Size(src); + rv = CFDictionaryCreateMutable((CFAllocatorRef)NULL, size, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + if (rv == NULL) { + PyMac_Error(resNotFound); + goto err; + } + if ( (aslist = PyMapping_Items(src)) == NULL ) goto err; + + for( i=0; i<size; i++) { + item_py = PySequence_GetItem(aslist, i); + if (item_py == NULL) goto err; + if (!PyArg_ParseTuple(item_py, "OO", key_py, value_py)) goto err; + if ( !PyCF_Python2CF(key_py, &key_cf) ) goto err; + Py_DECREF(key_py); + if ( !PyCF_Python2CF(value_cf, &key_cf) ) goto err; + Py_DECREF(value_py); + CFDictionaryAddValue(rv, key_cf, value_cf); + CFRelease(key_cf); + key_cf = NULL; + CFRelease(value_cf); + value_cf = NULL; + } + *dst = rv; + return 1; +err: + Py_XDECREF(item_py); + Py_XDECREF(key_py); + Py_XDECREF(value_py); + Py_XDECREF(aslist); + if (rv) CFRelease(rv); + if (key_cf) CFRelease(key_cf); + if (value_cf) CFRelease(value_cf); + return 0; +} + +int +PyCF_Python2CF_simple(PyObject *src, CFTypeRef *dst) { + + if (PyObject_HasAttrString(src, "CFType")) { + *dst = PyObject_CallMethod(src, "CFType", ""); + return (*dst != NULL); + } + if (PyString_Check(src) || PyUnicode_Check(src)) + return PyCF_Python2CF_string(src, (CFStringRef *)dst); + PyErr_Format(PyExc_TypeError, + "Cannot convert %.500s objects to CF", + src->ob_type->tp_name); + return 0; +} + +int +PyCF_Python2CF_string(PyObject *src, CFStringRef *dst) { + char *chars; + CFIndex size; + UniChar *unichars; + + if (PyString_Check(src)) { + if ((chars = PyString_AsString(src)) == NULL ) goto err; + *dst = CFStringCreateWithCString((CFAllocatorRef)NULL, chars, 0); + return 1; + } + if (PyUnicode_Check(src)) { + /* We use the CF types here, if Python was configured differently that will give an error */ + size = PyUnicode_GetSize(src); + if ((unichars = PyUnicode_AsUnicode(src)) == NULL ) goto err; + *dst = CFStringCreateWithCharacters((CFAllocatorRef)NULL, unichars, size); + return 1; + } +err: + PyErr_Format(PyExc_TypeError, + "Cannot convert %.500s objects to CF", + src->ob_type->tp_name); + return 0; +} diff --git a/Mac/Modules/cf/pycfbridge.h b/Mac/Modules/cf/pycfbridge.h new file mode 100644 index 0000000..3377d5d --- /dev/null +++ b/Mac/Modules/cf/pycfbridge.h @@ -0,0 +1,11 @@ +extern PyObject *PyCF_CF2Python(CFTypeRef src); +extern PyObject *PyCF_CF2Python_sequence(CFArrayRef src); +extern PyObject *PyCF_CF2Python_mapping(CFTypeRef src); +extern PyObject *PyCF_CF2Python_simple(CFTypeRef src); +extern PyObject *PyCF_CF2Python_string(CFStringRef src); + +extern int PyCF_Python2CF(PyObject *src, CFTypeRef *dst); +extern int PyCF_Python2CF_sequence(PyObject *src, CFArrayRef *dst); +extern int PyCF_Python2CF_mapping(PyObject *src, CFDictionaryRef *dst); +extern int PyCF_Python2CF_simple(PyObject *src, CFTypeRef *dst); +extern int PyCF_Python2CF_string(PyObject *src, CFStringRef *dst);
\ No newline at end of file |