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

Skip to content

Commit 7906634

Browse files
committed
- Better exception when a NULL CF object is encountered.
- Manually generate a routine with funny error semantics.
1 parent 69c9266 commit 7906634

3 files changed

Lines changed: 168 additions & 16 deletions

File tree

Mac/Modules/cf/_CFmodule.c

Lines changed: 133 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <CFDictionary.h>
2828
#include <CFString.h>
2929
#include <CFURL.h>
30+
#include <CFPropertyList.h>
3031
#else
3132
#include <CoreServices/CoreServices.h>
3233
#endif
@@ -137,7 +138,11 @@ typedef struct CFTypeRefObject {
137138
PyObject *CFTypeRefObj_New(CFTypeRef itself)
138139
{
139140
CFTypeRefObject *it;
140-
if (itself == NULL) return PyMac_Error(resNotFound);
141+
if (itself == NULL)
142+
{
143+
PyErr_SetString(PyExc_RuntimeError, "cannot wrap NULL");
144+
return NULL;
145+
}
141146
it = PyObject_NEW(CFTypeRefObject, &CFTypeRef_Type);
142147
if (it == NULL) return NULL;
143148
it->ob_itself = itself;
@@ -275,6 +280,35 @@ static PyObject *CFTypeRefObj_CFCopyDescription(CFTypeRefObject *_self, PyObject
275280
return _res;
276281
}
277282

283+
static PyObject *CFTypeRefObj_CFPropertyListCreateXMLData(CFTypeRefObject *_self, PyObject *_args)
284+
{
285+
PyObject *_res = NULL;
286+
CFDataRef _rv;
287+
if (!PyArg_ParseTuple(_args, ""))
288+
return NULL;
289+
_rv = CFPropertyListCreateXMLData((CFAllocatorRef)NULL,
290+
_self->ob_itself);
291+
_res = Py_BuildValue("O&",
292+
CFDataRefObj_New, _rv);
293+
return _res;
294+
}
295+
296+
static PyObject *CFTypeRefObj_CFPropertyListCreateDeepCopy(CFTypeRefObject *_self, PyObject *_args)
297+
{
298+
PyObject *_res = NULL;
299+
CFTypeRef _rv;
300+
CFOptionFlags mutabilityOption;
301+
if (!PyArg_ParseTuple(_args, "l",
302+
&mutabilityOption))
303+
return NULL;
304+
_rv = CFPropertyListCreateDeepCopy((CFAllocatorRef)NULL,
305+
_self->ob_itself,
306+
mutabilityOption);
307+
_res = Py_BuildValue("O&",
308+
CFTypeRefObj_New, _rv);
309+
return _res;
310+
}
311+
278312
static PyObject *CFTypeRefObj_CFShow(CFTypeRefObject *_self, PyObject *_args)
279313
{
280314
PyObject *_res = NULL;
@@ -289,6 +323,32 @@ static PyObject *CFTypeRefObj_CFShow(CFTypeRefObject *_self, PyObject *_args)
289323
return _res;
290324
}
291325

326+
static PyObject *CFTypeRefObj_CFPropertyListCreateFromXMLData(CFTypeRefObject *_self, PyObject *_args)
327+
{
328+
PyObject *_res = NULL;
329+
330+
CFTypeRef _rv;
331+
CFOptionFlags mutabilityOption;
332+
CFStringRef errorString;
333+
if (!PyArg_ParseTuple(_args, "l",
334+
&mutabilityOption))
335+
return NULL;
336+
_rv = CFPropertyListCreateFromXMLData((CFAllocatorRef)NULL,
337+
_self->ob_itself,
338+
mutabilityOption,
339+
&errorString);
340+
if (errorString)
341+
CFRelease(errorString);
342+
if (_rv == NULL) {
343+
PyErr_SetString(PyExc_RuntimeError, "Parse error in XML data");
344+
return NULL;
345+
}
346+
_res = Py_BuildValue("O&",
347+
CFTypeRefObj_New, _rv);
348+
return _res;
349+
350+
}
351+
292352
static PyObject *CFTypeRefObj_toPython(CFTypeRefObject *_self, PyObject *_args)
293353
{
294354
PyObject *_res = NULL;
@@ -312,8 +372,14 @@ static PyMethodDef CFTypeRefObj_methods[] = {
312372
"() -> (CFHashCode _rv)"},
313373
{"CFCopyDescription", (PyCFunction)CFTypeRefObj_CFCopyDescription, 1,
314374
"() -> (CFStringRef _rv)"},
375+
{"CFPropertyListCreateXMLData", (PyCFunction)CFTypeRefObj_CFPropertyListCreateXMLData, 1,
376+
"() -> (CFDataRef _rv)"},
377+
{"CFPropertyListCreateDeepCopy", (PyCFunction)CFTypeRefObj_CFPropertyListCreateDeepCopy, 1,
378+
"(CFOptionFlags mutabilityOption) -> (CFTypeRef _rv)"},
315379
{"CFShow", (PyCFunction)CFTypeRefObj_CFShow, 1,
316380
"() -> None"},
381+
{"CFPropertyListCreateFromXMLData", (PyCFunction)CFTypeRefObj_CFPropertyListCreateFromXMLData, 1,
382+
"(CFOptionFlags mutabilityOption) -> (CFTypeRefObj)"},
317383
{"toPython", (PyCFunction)CFTypeRefObj_toPython, 1,
318384
"() -> (python_object)"},
319385
{NULL, NULL, 0}
@@ -386,7 +452,11 @@ typedef struct CFArrayRefObject {
386452
PyObject *CFArrayRefObj_New(CFArrayRef itself)
387453
{
388454
CFArrayRefObject *it;
389-
if (itself == NULL) return PyMac_Error(resNotFound);
455+
if (itself == NULL)
456+
{
457+
PyErr_SetString(PyExc_RuntimeError, "cannot wrap NULL");
458+
return NULL;
459+
}
390460
it = PyObject_NEW(CFArrayRefObject, &CFArrayRef_Type);
391461
if (it == NULL) return NULL;
392462
it->ob_itself = itself;
@@ -538,7 +608,11 @@ typedef struct CFMutableArrayRefObject {
538608
PyObject *CFMutableArrayRefObj_New(CFMutableArrayRef itself)
539609
{
540610
CFMutableArrayRefObject *it;
541-
if (itself == NULL) return PyMac_Error(resNotFound);
611+
if (itself == NULL)
612+
{
613+
PyErr_SetString(PyExc_RuntimeError, "cannot wrap NULL");
614+
return NULL;
615+
}
542616
it = PyObject_NEW(CFMutableArrayRefObject, &CFMutableArrayRef_Type);
543617
if (it == NULL) return NULL;
544618
it->ob_itself = itself;
@@ -719,7 +793,11 @@ typedef struct CFDictionaryRefObject {
719793
PyObject *CFDictionaryRefObj_New(CFDictionaryRef itself)
720794
{
721795
CFDictionaryRefObject *it;
722-
if (itself == NULL) return PyMac_Error(resNotFound);
796+
if (itself == NULL)
797+
{
798+
PyErr_SetString(PyExc_RuntimeError, "cannot wrap NULL");
799+
return NULL;
800+
}
723801
it = PyObject_NEW(CFDictionaryRefObject, &CFDictionaryRef_Type);
724802
if (it == NULL) return NULL;
725803
it->ob_itself = itself;
@@ -853,7 +931,11 @@ typedef struct CFMutableDictionaryRefObject {
853931
PyObject *CFMutableDictionaryRefObj_New(CFMutableDictionaryRef itself)
854932
{
855933
CFMutableDictionaryRefObject *it;
856-
if (itself == NULL) return PyMac_Error(resNotFound);
934+
if (itself == NULL)
935+
{
936+
PyErr_SetString(PyExc_RuntimeError, "cannot wrap NULL");
937+
return NULL;
938+
}
857939
it = PyObject_NEW(CFMutableDictionaryRefObject, &CFMutableDictionaryRef_Type);
858940
if (it == NULL) return NULL;
859941
it->ob_itself = itself;
@@ -971,7 +1053,11 @@ typedef struct CFDataRefObject {
9711053
PyObject *CFDataRefObj_New(CFDataRef itself)
9721054
{
9731055
CFDataRefObject *it;
974-
if (itself == NULL) return PyMac_Error(resNotFound);
1056+
if (itself == NULL)
1057+
{
1058+
PyErr_SetString(PyExc_RuntimeError, "cannot wrap NULL");
1059+
return NULL;
1060+
}
9751061
it = PyObject_NEW(CFDataRefObject, &CFDataRef_Type);
9761062
if (it == NULL) return NULL;
9771063
it->ob_itself = itself;
@@ -982,7 +1068,13 @@ int CFDataRefObj_Convert(PyObject *v, CFDataRef *p_itself)
9821068
{
9831069

9841070
if (v == Py_None) { *p_itself = NULL; return 1; }
985-
/* Check for other CF objects here */
1071+
if (PyString_Check(v)) {
1072+
char *cStr;
1073+
int cLen;
1074+
if( PyString_AsStringAndSize(v, &cStr, &cLen) < 0 ) return 0;
1075+
*p_itself = CFDataCreate((CFAllocatorRef)NULL, (unsigned char *)cStr, cLen);
1076+
return 1;
1077+
}
9861078

9871079
if (!CFDataRefObj_Check(v))
9881080
{
@@ -1046,13 +1138,27 @@ static PyObject *CFDataRefObj_CFStringCreateFromExternalRepresentation(CFDataRef
10461138
return _res;
10471139
}
10481140

1141+
static PyObject *CFDataRefObj_CFDataGetData(CFDataRefObject *_self, PyObject *_args)
1142+
{
1143+
PyObject *_res = NULL;
1144+
1145+
int size = CFDataGetLength(_self->ob_itself);
1146+
char *data = (char *)CFDataGetBytePtr(_self->ob_itself);
1147+
1148+
_res = (PyObject *)PyString_FromStringAndSize(data, size);
1149+
return _res;
1150+
1151+
}
1152+
10491153
static PyMethodDef CFDataRefObj_methods[] = {
10501154
{"CFDataCreateCopy", (PyCFunction)CFDataRefObj_CFDataCreateCopy, 1,
10511155
"() -> (CFDataRef _rv)"},
10521156
{"CFDataGetLength", (PyCFunction)CFDataRefObj_CFDataGetLength, 1,
10531157
"() -> (CFIndex _rv)"},
10541158
{"CFStringCreateFromExternalRepresentation", (PyCFunction)CFDataRefObj_CFStringCreateFromExternalRepresentation, 1,
10551159
"(CFStringEncoding encoding) -> (CFStringRef _rv)"},
1160+
{"CFDataGetData", (PyCFunction)CFDataRefObj_CFDataGetData, 1,
1161+
"() -> (string _rv)"},
10561162
{NULL, NULL, 0}
10571163
};
10581164

@@ -1123,7 +1229,11 @@ typedef struct CFMutableDataRefObject {
11231229
PyObject *CFMutableDataRefObj_New(CFMutableDataRef itself)
11241230
{
11251231
CFMutableDataRefObject *it;
1126-
if (itself == NULL) return PyMac_Error(resNotFound);
1232+
if (itself == NULL)
1233+
{
1234+
PyErr_SetString(PyExc_RuntimeError, "cannot wrap NULL");
1235+
return NULL;
1236+
}
11271237
it = PyObject_NEW(CFMutableDataRefObject, &CFMutableDataRef_Type);
11281238
if (it == NULL) return NULL;
11291239
it->ob_itself = itself;
@@ -1329,7 +1439,11 @@ typedef struct CFStringRefObject {
13291439
PyObject *CFStringRefObj_New(CFStringRef itself)
13301440
{
13311441
CFStringRefObject *it;
1332-
if (itself == NULL) return PyMac_Error(resNotFound);
1442+
if (itself == NULL)
1443+
{
1444+
PyErr_SetString(PyExc_RuntimeError, "cannot wrap NULL");
1445+
return NULL;
1446+
}
13331447
it = PyObject_NEW(CFStringRefObject, &CFStringRef_Type);
13341448
if (it == NULL) return NULL;
13351449
it->ob_itself = itself;
@@ -2010,7 +2124,11 @@ typedef struct CFMutableStringRefObject {
20102124
PyObject *CFMutableStringRefObj_New(CFMutableStringRef itself)
20112125
{
20122126
CFMutableStringRefObject *it;
2013-
if (itself == NULL) return PyMac_Error(resNotFound);
2127+
if (itself == NULL)
2128+
{
2129+
PyErr_SetString(PyExc_RuntimeError, "cannot wrap NULL");
2130+
return NULL;
2131+
}
20142132
it = PyObject_NEW(CFMutableStringRefObject, &CFMutableStringRef_Type);
20152133
if (it == NULL) return NULL;
20162134
it->ob_itself = itself;
@@ -2339,7 +2457,11 @@ typedef struct CFURLRefObject {
23392457
PyObject *CFURLRefObj_New(CFURLRef itself)
23402458
{
23412459
CFURLRefObject *it;
2342-
if (itself == NULL) return PyMac_Error(resNotFound);
2460+
if (itself == NULL)
2461+
{
2462+
PyErr_SetString(PyExc_RuntimeError, "cannot wrap NULL");
2463+
return NULL;
2464+
}
23432465
it = PyObject_NEW(CFURLRefObject, &CFURLRef_Type);
23442466
if (it == NULL) return NULL;
23452467
it->ob_itself = itself;

Mac/Modules/cf/cfscan.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ def makeblacklistnames(self):
9797
"CFStringSetExternalCharactersNoCopy",
9898
"CFStringGetCharacterAtIndex", # No format for single unichars yet.
9999
"kCFStringEncodingInvalidId", # incompatible constant declaration
100+
"CFPropertyListCreateFromXMLData", # Manually generated
100101
]
101102

102103
def makegreylist(self):

Mac/Modules/cf/cfsupport.py

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,11 @@ def parseArgumentList(self, args):
203203

204204
class MyGlobalObjectDefinition(GlobalObjectDefinition):
205205
def outputCheckNewArg(self):
206-
Output("if (itself == NULL) return PyMac_Error(resNotFound);")
206+
Output('if (itself == NULL)')
207+
OutLbrace()
208+
Output('PyErr_SetString(PyExc_RuntimeError, "cannot wrap NULL");')
209+
Output('return NULL;')
210+
OutRbrace()
207211
def outputStructMembers(self):
208212
GlobalObjectDefinition.outputStructMembers(self)
209213
Output("void (*ob_freeit)(CFTypeRef ptr);")
@@ -501,10 +505,6 @@ def outputRepr(self):
501505
f.docstring = lambda: "() -> (unicode _rv)"
502506
CFStringRef_object.add(f)
503507

504-
toPython_body = """
505-
return PyCF_CF2Python(_self->ob_itself);
506-
"""
507-
508508
# Get data from CFDataRef
509509
getasdata_body = """
510510
int size = CFDataGetLength(_self->ob_itself);
@@ -518,7 +518,36 @@ def outputRepr(self):
518518
f.docstring = lambda: "() -> (string _rv)"
519519
CFDataRef_object.add(f)
520520

521+
# Manual generator for CFPropertyListCreateFromXMLData because of funny error return
522+
fromxml_body = """
523+
CFTypeRef _rv;
524+
CFOptionFlags mutabilityOption;
525+
CFStringRef errorString;
526+
if (!PyArg_ParseTuple(_args, "l",
527+
&mutabilityOption))
528+
return NULL;
529+
_rv = CFPropertyListCreateFromXMLData((CFAllocatorRef)NULL,
530+
_self->ob_itself,
531+
mutabilityOption,
532+
&errorString);
533+
if (errorString)
534+
CFRelease(errorString);
535+
if (_rv == NULL) {
536+
PyErr_SetString(PyExc_RuntimeError, "Parse error in XML data");
537+
return NULL;
538+
}
539+
_res = Py_BuildValue("O&",
540+
CFTypeRefObj_New, _rv);
541+
return _res;
542+
"""
543+
f = ManualGenerator("CFPropertyListCreateFromXMLData", fromxml_body)
544+
f.docstring = lambda: "(CFOptionFlags mutabilityOption) -> (CFTypeRefObj)"
545+
CFTypeRef_object.add(f)
521546

547+
# Convert CF objects to Python objects
548+
toPython_body = """
549+
return PyCF_CF2Python(_self->ob_itself);
550+
"""
522551

523552
f = ManualGenerator("toPython", toPython_body);
524553
f.docstring = lambda: "() -> (python_object)"

0 commit comments

Comments
 (0)