diff Objects/stringobject.c @ 14696:85038a024b19 legacy-trunk

This patch adds a new Python C API called PyString_AsStringAndSize() which implements the automatic conversion from Unicode to a string object using the default encoding. The new API is then put to use to have eval() and exec accept Unicode objects as code parameter. This closes bugs #110924 and #113890. As side-effect, the traditional C APIs PyString_Size() and PyString_AsString() will also accept Unicode objects as parameters.
author Marc-André Lemburg <mal@egenix.com>
date Tue, 19 Sep 2000 21:04:18 +0000
parents 7728b0ea9344
children 58b832b8745e
line wrap: on
line diff
--- a/Objects/stringobject.c	Tue Sep 19 20:51:17 2000 +0000
+++ b/Objects/stringobject.c	Tue Sep 19 21:04:18 2000 +0000
@@ -239,24 +239,80 @@
 	PyObject_DEL(op);
 }
 
+static int
+string_getsize(register PyObject *op)
+{
+    	char *s;
+    	int len;
+	if (PyString_AsStringAndSize(op, &s, &len))
+		return -1;
+	return len;
+}
+
+static /*const*/ char *
+string_getbuffer(register PyObject *op)
+{
+    	char *s;
+    	int len;
+	if (PyString_AsStringAndSize(op, &s, &len))
+		return NULL;
+	return s;
+}
+
 int
 PyString_Size(register PyObject *op)
 {
-	if (!PyString_Check(op)) {
-		PyErr_BadInternalCall();
-		return -1;
-	}
+	if (!PyString_Check(op))
+		return string_getsize(op);
 	return ((PyStringObject *)op) -> ob_size;
 }
 
 /*const*/ char *
 PyString_AsString(register PyObject *op)
 {
-	if (!PyString_Check(op)) {
+	if (!PyString_Check(op))
+		return string_getbuffer(op);
+	return ((PyStringObject *)op) -> ob_sval;
+}
+
+/* Internal API needed by PyString_AsStringAndSize(): */
+extern 
+PyObject *_PyUnicode_AsDefaultEncodedString(PyObject *unicode,
+					    const char *errors);
+
+int
+PyString_AsStringAndSize(register PyObject *obj,
+			 register char **s,
+			 register int *len)
+{
+	if (s == NULL) {
 		PyErr_BadInternalCall();
-		return NULL;
+		return -1;
 	}
-	return ((PyStringObject *)op) -> ob_sval;
+
+	if (!PyString_Check(obj)) {
+		if (PyUnicode_Check(obj)) {
+			obj = _PyUnicode_AsDefaultEncodedString(obj, NULL);
+			if (obj == NULL)
+				return -1;
+		}
+		else {
+			PyErr_Format(PyExc_TypeError,
+				     "expected string or Unicode object, "
+				     "%.200s found", obj->ob_type->tp_name);
+			return -1;
+		}
+	}
+
+	*s = PyString_AS_STRING(obj);
+	if (len != NULL)
+		*len = PyString_GET_SIZE(obj);
+	else if ((int)strlen(*s) != PyString_GET_SIZE(obj)) {
+		PyErr_SetString(PyExc_TypeError,
+				"expected string without null bytes");
+		return -1;
+	}
+	return 0;
 }
 
 /* Methods */