Commits

Bob Ippolito committed a7b221d

- New ``objc.RegisterCFSignature`` used to register ``CFTypeRef``-like
signatures with the runtime.

Comments (0)

Files changed (6)

Modules/objc/module.m

 	"The signature is the Objective-C type specifier for the function \n"
 	"signature.");
 
+PyDoc_STRVAR(objc_RegisterCFSignature_doc,
+	"RegisterCFSignature(signature) -> None\n"
+	"\n"
+	"Register a type signature as a CoreFoundation type"
+);
+static PyObject*
+objc_RegisterCFSignature(PyObject* self __attribute__((__unused__)), PyObject* args, PyObject* kwds)
+{
+static  char* keywords[] = { "signature", 0 };
+	char *signature;
+	int res;
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwds,
+			"s:RegisterCFSignature", keywords,
+			&signature)) {
+		return NULL;
+	}
+
+	signature = PyObjCUtil_Strdup(signature);
+	res = PyObjCPointerWrapper_RegisterCF((const char *)signature);
+	if (res == -1) {
+		return NULL;
+	}
+	
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+
 PyDoc_STRVAR(objc_CFToObject_doc,
 	"CFToObject(cfObject) -> objCObject\n"
 	"\n"
 	{ "protocolsForClass", (PyCFunction)protocolsForClass, METH_VARARGS|METH_KEYWORDS, protocolsForClass_doc },
 	{ "protocolsForProcess", (PyCFunction)protocolsForProcess, METH_NOARGS, protocolsForProcess_doc },
 #ifdef MACOSX
+	{ "RegisterCFSignature", (PyCFunction)objc_RegisterCFSignature, METH_VARARGS|METH_KEYWORDS, objc_RegisterCFSignature_doc },
 	{ "CFToObject", (PyCFunction)objc_CFToObject, METH_VARARGS|METH_KEYWORDS, objc_CFToObject_doc },
 	{ "ObjectToCF", (PyCFunction)objc_ObjectToCF, METH_VARARGS|METH_KEYWORDS, objc_ObjectToCF_doc },
 	{ "loadBundleVariables", (PyCFunction)PyObjC_loadBundleVariables,

Modules/objc/pointer-support.h

 	const char*, PyObjCPointerWrapper_ToPythonFunc pythonify,
 	PyObjCPointerWrapper_FromPythonFunc depythonify);
 
+int PyObjCPointerWrapper_RegisterCF(const char*);
 PyObject* PyObjCPointerWrapper_ToPython(const char*, void*);
 
 int PyObjCPointerWrapper_FromPython(const char*, PyObject*, void*);

Modules/objc/pointer-support.m

 static struct wrapper* items = 0;
 static int item_count = 0;
 
+static int find_offset(const char* signature) {
+	/* XXX:
+	 * I don't know what the heck this was supposed to do
+	 */
+#if 0
+	if (signature[1] == _C_STRUCT_B) {
+		int o1, o2;
+
+		o1 = strchr(signature, _C_STRUCT_E) - signature;
+		o2 = strchr(signature, '=') - signature;
+
+		return (o1 < o2) ? o1 : o2;
+	}
+#endif
+	return strlen(signature);
+}
+
 static struct wrapper*
 FindWrapper(const char* signature)
 {
 
 	for (i = 0; i < item_count; i++) {
 		if (strncmp(signature, items[i].signature, items[i].offset) == 0) {
+			return &items[i];
+			/* XXX: What was this supposed to do? */
+#if 0
 			if (signature[1] != _C_STRUCT_B || signature[items[i].offset] == '=' || signature[items[i].offset] == _C_STRUCT_E) {
-				return items + i;
+				return &items[i];
 			}
+#endif
 		}
 	}
 	return NULL;
 	 * This makes it possible to replace a default wrapper by something
 	 * better.
 	 */
+	if (signature == NULL) {
+		return -1;
+	}
 	value = FindWrapper(signature);
 	if (value != NULL) {
 		value->pythonify = pythonify;
 	value = items + (item_count-1);
 
 	value->signature = signature;
-	if (signature[1] == _C_STRUCT_B) {
-		int o1, o2;
-
-		o1 = strchr(signature, _C_STRUCT_E) - signature;
-		o2 = strchr(signature, '=') - signature;
-
-		if (o1 < o2) {
-			value->offset = o1;
-		} else {
-			value->offset = o2;
-		}
-	} else {
-		value->offset = strlen(signature);
-	}
+	value->offset = find_offset(signature);
 
 	value->pythonify = pythonify;
 	value->depythonify = depythonify;
 	return 0;
 }
 
+int PyObjCPointerWrapper_RegisterCF(const char *signature) {
+	return PyObjCPointerWrapper_Register(signature, 
+		(PyObjCPointerWrapper_ToPythonFunc)&CF_to_py, 
+		(PyObjCPointerWrapper_FromPythonFunc)&py_to_CF);
+}
+
 
 #endif
 
 	int r = 0;
 
 #ifdef MACOSX
-	r = PyObjCPointerWrapper_Register(@encode(CFURLRef), 
-		(PyObjCPointerWrapper_ToPythonFunc)CF_to_py, 
-		(PyObjCPointerWrapper_FromPythonFunc)py_to_CF);
+	r = PyObjCPointerWrapper_RegisterCF(@encode(CFURLRef)); 
 	if (r == -1) return -1;
 
-	r = PyObjCPointerWrapper_Register(@encode(CFSetRef), 
-		(PyObjCPointerWrapper_ToPythonFunc)CF_to_py, 
-		(PyObjCPointerWrapper_FromPythonFunc)py_to_CF);
+	r = PyObjCPointerWrapper_RegisterCF(@encode(CFSetRef)); 
 	if (r == -1) return -1;
 
 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_2
-	r = PyObjCPointerWrapper_Register(@encode(CFNetServiceRef), 
-		(PyObjCPointerWrapper_ToPythonFunc)CF_to_py, 
-		(PyObjCPointerWrapper_FromPythonFunc)py_to_CF);
+	r = PyObjCPointerWrapper_RegisterCF(@encode(CFNetServiceRef)); 
 	if (r == -1) return -1;
 #endif
 
-	r = PyObjCPointerWrapper_Register(@encode(CFReadStreamRef), 
-		(PyObjCPointerWrapper_ToPythonFunc)CF_to_py, 
-		(PyObjCPointerWrapper_FromPythonFunc)py_to_CF);
+	r = PyObjCPointerWrapper_RegisterCF(@encode(CFReadStreamRef)); 
 	if (r == -1) return -1;
 
-	r = PyObjCPointerWrapper_Register(@encode(CFRunLoopRef), 
-		(PyObjCPointerWrapper_ToPythonFunc)CF_to_py, 
-		(PyObjCPointerWrapper_FromPythonFunc)py_to_CF);
+	r = PyObjCPointerWrapper_RegisterCF(@encode(CFRunLoopRef)); 
 	if (r == -1) return -1;
 
 #endif

Modules/objc/toll-free-bridging.m

 {
 	/* Tollfree bridging of CF (some) objects 
 	 * This list of conversion functions is the complete list of such
-	 * functions in Python 2.3b1
+	 * functions in Python 2.4.1
 	 */
 	int r;
 	id  val;
 /* 
  * NOTE: CFObj_New creates a CF wrapper for any CF object, however we have
  * better information for at least some types: it is impossible to see the
- * difference between mutable and immutable collection types using only 
- * the CF API.
+ * difference between mutable and immutable types using the CF API.
+ *
  */
 PyObject* 
 PyObjC_IDToCFType(id argument)
 {
-	[argument retain];
+	CFTypeRef typeRef = (CFTypeRef)argument;
+	CFTypeID typeID = CFGetTypeID(argument);
 
-	if ([argument isKindOfClass:[NSMutableString class]]) {
+    /*
+     * This function has a net reference count of 0 as the CF wrapper
+     * does not retain, but will do a CFRelease when the Python proxy
+     * goes away.
+     */
+	CFRetain(typeRef);
+
+	/* This could be more efficient, could cache... */
+	if (typeID == CFStringGetTypeID()) {
 		return CFMutableStringRefObj_New((CFMutableStringRef)argument);
+	} else if (typeID == CFArrayGetTypeID()) {
+		return CFMutableArrayRefObj_New((CFMutableArrayRef)argument);
+	} else if (typeID == CFDictionaryGetTypeID()) {
+		return CFMutableDictionaryRefObj_New((CFMutableDictionaryRef)argument);
+	} else if (typeID == CFURLGetTypeID()) {
+		return CFURLRefObj_New((CFURLRef)argument);
+/*
+ * TODO: This is in Python 2.5, Fix the #if at some point
+ */
+#if 0
+	} else if (typeID == CFDataGetTypeID()) {
+		return CFMutableDataRefObj_New((CFMutableDataRef)argument);
+#endif
 	}
-
-	if ([argument isKindOfClass:[NSString class]]) {
-		return CFStringRefObj_New((CFStringRef)argument);
-	}
-	
-	if ([argument isKindOfClass:[NSMutableArray class]]) {
-		return CFMutableArrayRefObj_New((CFMutableArrayRef)argument);
-	}
-
-	if ([argument isKindOfClass:[NSArray class]]) {
-		return CFArrayRefObj_New((CFArrayRef)argument);
-	}
-
-	if ([argument isKindOfClass:[NSDictionary class]]) {
-		return CFDictionaryRefObj_New((CFDictionaryRef)argument);
-	}
-
-	if ([argument isKindOfClass:[NSMutableDictionary class]]) {
-		return CFMutableDictionaryRefObj_New(
-				(CFMutableDictionaryRef)argument);
-	}
-
-	if ([argument isKindOfClass:[NSURL class]]) {
-		return CFURLRefObj_New((CFURLRef)argument);
-	}
-
-	/* Apple doesn't say as much, but as NSArray and CFArray are toll-free
-	 * bridged NSObject must also be toll-free bridged to a CoreFoundation
-	 * type.  As is is not document which type this is, we use the most
-	 * generic one.
-	 */
 	return CFObj_New((CFTypeRef)argument);
 }
 
 <p>An overview of the relevant changes in new, and older, releases.</p>
 <h2><a name="version-1-3-5-2005-05">Version 1.3.5 (2005-05-??)</a></h2>
 <ul>
+<li>New <code><span>objc.RegisterCFSignature</span></code> used to register <code><span>CFTypeRef</span></code>-like
+signatures with the runtime.</li>
 <li><code><span>PyObjCTools.Conversion</span></code> functions now support all property list
 types with the following conversions:<ul>
 <li>NSData &lt;-&gt; buffer</li>
 Version 1.3.5 (2005-05-??)
 --------------------------
 
+- New ``objc.RegisterCFSignature`` used to register ``CFTypeRef``-like
+  signatures with the runtime.
+
 - ``PyObjCTools.Conversion`` functions now support all property list
   types with the following conversions:
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.