Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4225132

Browse files
committed
Fixed string and dict conversion, and implemented booleans and numbers (int and float). I think we now have enough CFType support to start on plists and CFpreferences!
Transparent handling of unknown CFType objects still TBD.
1 parent 1df628d commit 4225132

1 file changed

Lines changed: 49 additions & 14 deletions

File tree

Mac/Modules/cf/pycfbridge.c

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#ifdef WITHOUT_FRAMEWORKS
66
#include <CFBase.h>
7+
#include <CFNumber.h>
78
#include <CFArray.h>
89
#include <CFData.h>
910
#include <CFDictionary.h>
@@ -66,25 +67,30 @@ PyCF_CF2Python_sequence(CFArrayRef src) {
6667
PyObject *
6768
PyCF_CF2Python_mapping(CFTypeRef src) {
6869
int size = CFDictionaryGetCount(src);
69-
PyObject *rv;
70-
CFTypeRef *allkeys, *allvalues;
70+
PyObject *rv = NULL;
71+
CFTypeRef *allkeys = NULL, *allvalues = NULL;
7172
CFTypeRef key_cf, value_cf;
7273
PyObject *key_py = NULL, *value_py = NULL;
7374
int i;
7475

7576
allkeys = malloc(size*sizeof(CFTypeRef *));
76-
if (allkeys == NULL) return PyErr_NoMemory();
77+
if (allkeys == NULL) {
78+
PyErr_NoMemory();
79+
goto err;
80+
}
7781
allvalues = malloc(size*sizeof(CFTypeRef *));
78-
if (allvalues == NULL) return PyErr_NoMemory();
79-
if ( (rv=PyDict_New()) == NULL )
80-
return NULL;
82+
if (allvalues == NULL) {
83+
PyErr_NoMemory();
84+
goto err;
85+
}
86+
if ( (rv=PyDict_New()) == NULL ) goto err;
8187
CFDictionaryGetKeysAndValues(src, allkeys, allvalues);
8288
for(i=0; i<size; i++) {
8389
key_cf = allkeys[i];
8490
value_cf = allvalues[i];
8591
key_py = PyCF_CF2Python(key_cf);
8692
if (key_py == NULL ) goto err;
87-
value_py = PyCF_CF2Python(value_py);
93+
value_py = PyCF_CF2Python(value_cf);
8894
if (value_py == NULL ) goto err;
8995
if (PyDict_SetItem(rv, key_py, value_py) < 0) goto err;
9096
key_py = NULL;
@@ -94,7 +100,7 @@ PyCF_CF2Python_mapping(CFTypeRef src) {
94100
err:
95101
Py_XDECREF(key_py);
96102
Py_XDECREF(value_py);
97-
Py_DECREF(rv);
103+
Py_XDECREF(rv);
98104
free(allkeys);
99105
free(allvalues);
100106
return NULL;
@@ -107,6 +113,21 @@ PyCF_CF2Python_simple(CFTypeRef src) {
107113
typeid = CFGetTypeID(src);
108114
if (typeid == CFStringGetTypeID())
109115
return PyCF_CF2Python_string((CFStringRef)src);
116+
if (typeid == CFBooleanGetTypeID())
117+
return PyBool_FromLong((long)CFBooleanGetValue(src));
118+
if (typeid == CFNumberGetTypeID()) {
119+
if (CFNumberIsFloatType(src)) {
120+
double d;
121+
CFNumberGetValue(src, kCFNumberDoubleType, &d);
122+
return PyFloat_FromDouble(d);
123+
} else {
124+
long l;
125+
if (!CFNumberGetValue(src, kCFNumberLongType, &l))
126+
/* XXXX Out of range! */;
127+
return PyInt_FromLong(l);
128+
}
129+
}
130+
/* XXXX Should return as CFTypeRef, really... */
110131
PyMac_Error(resNotFound);
111132
return NULL;
112133
}
@@ -123,7 +144,7 @@ PyCF_CF2Python_string(CFStringRef src) {
123144
range.length = size;
124145
if( data == NULL ) return PyErr_NoMemory();
125146
CFStringGetCharacters(src, range, data);
126-
rv = (PyObject *)PyUnicode_FromUnicode(data, size);
147+
rv = (PyObject *)PyUnicode_FromUnicode(data, size-1);
127148
free(data);
128149
return rv;
129150
}
@@ -197,11 +218,9 @@ PyCF_Python2CF_mapping(PyObject *src, CFDictionaryRef *dst) {
197218
for( i=0; i<size; i++) {
198219
item_py = PySequence_GetItem(aslist, i);
199220
if (item_py == NULL) goto err;
200-
if (!PyArg_ParseTuple(item_py, "OO", key_py, value_py)) goto err;
221+
if (!PyArg_ParseTuple(item_py, "OO", &key_py, &value_py)) goto err;
201222
if ( !PyCF_Python2CF(key_py, &key_cf) ) goto err;
202-
Py_DECREF(key_py);
203223
if ( !PyCF_Python2CF(value_py, &value_cf) ) goto err;
204-
Py_DECREF(value_py);
205224
CFDictionaryAddValue(rv, key_cf, value_cf);
206225
CFRelease(key_cf);
207226
key_cf = NULL;
@@ -212,8 +231,6 @@ PyCF_Python2CF_mapping(PyObject *src, CFDictionaryRef *dst) {
212231
return 1;
213232
err:
214233
Py_XDECREF(item_py);
215-
Py_XDECREF(key_py);
216-
Py_XDECREF(value_py);
217234
Py_XDECREF(aslist);
218235
if (rv) CFRelease(rv);
219236
if (key_cf) CFRelease(key_cf);
@@ -230,6 +247,24 @@ PyCF_Python2CF_simple(PyObject *src, CFTypeRef *dst) {
230247
}
231248
if (PyString_Check(src) || PyUnicode_Check(src))
232249
return PyCF_Python2CF_string(src, (CFStringRef *)dst);
250+
if (PyBool_Check(src)) {
251+
if (src == Py_True)
252+
*dst = kCFBooleanTrue;
253+
else
254+
*dst = kCFBooleanFalse;
255+
return 1;
256+
}
257+
if (PyInt_Check(src)) {
258+
long v = PyInt_AsLong(src);
259+
*dst = CFNumberCreate(NULL, kCFNumberLongType, &v);
260+
return 1;
261+
}
262+
if (PyFloat_Check(src)) {
263+
double d = PyFloat_AsDouble(src);
264+
*dst = CFNumberCreate(NULL, kCFNumberDoubleType, &d);
265+
return 1;
266+
}
267+
233268
PyErr_Format(PyExc_TypeError,
234269
"Cannot convert %.500s objects to CF",
235270
src->ob_type->tp_name);

0 commit comments

Comments
 (0)