summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorMarc-André Lemburg <mal@egenix.com>2000-09-21 21:08:30 (GMT)
committerMarc-André Lemburg <mal@egenix.com>2000-09-21 21:08:30 (GMT)
commit0afff388ce38cc0a42ef6c8b9a3f815997ee0103 (patch)
tree40bde1198117bfbef75e6cf3f1ebba6a2da32163 /Python
parent3578b77312720061ef3e5a86e3db4f3c968edf56 (diff)
downloadcpython-0afff388ce38cc0a42ef6c8b9a3f815997ee0103.zip
cpython-0afff388ce38cc0a42ef6c8b9a3f815997ee0103.tar.gz
cpython-0afff388ce38cc0a42ef6c8b9a3f815997ee0103.tar.bz2
Special case the "s#" PyArg_Parse() token for Unicode objects:
"s#" will now return a pointer to the default encoded string data of the Unicode object instead of a pointer to the raw UTF-16 data. The latter is still available via PyObject_AsReadBuffer(). The patch also adds an optimization for string objects which is based on the fact that string objects return the raw character data for getreadbuffer access and are always single-segment.
Diffstat (limited to 'Python')
-rw-r--r--Python/getargs.c79
1 files changed, 53 insertions, 26 deletions
diff --git a/Python/getargs.c b/Python/getargs.c
index 1dddae4..797e9df 100644
--- a/Python/getargs.c
+++ b/Python/getargs.c
@@ -556,22 +556,36 @@ convertsimple1(PyObject *arg, char **p_format, va_list *p_va)
case 's': /* string */
{
- if (*format == '#') { /* any buffer-like object */
+ if (*format == '#') {
void **p = (void **)va_arg(*p_va, char **);
- PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
int *q = va_arg(*p_va, int *);
- int count;
- if ( pb == NULL ||
- pb->bf_getreadbuffer == NULL ||
- pb->bf_getsegcount == NULL )
- return "read-only buffer";
- if ( (*pb->bf_getsegcount)(arg, NULL) != 1 )
- return "single-segment read-only buffer";
- if ( (count =
- (*pb->bf_getreadbuffer)(arg, 0, p)) < 0 )
- return "(unspecified)";
- *q = count;
+ if (PyString_Check(arg)) {
+ *p = PyString_AS_STRING(arg);
+ *q = PyString_GET_SIZE(arg);
+ }
+ else if (PyUnicode_Check(arg)) {
+ arg = _PyUnicode_AsDefaultEncodedString(
+ arg, NULL);
+ if (arg == NULL)
+ return "unicode conversion error";
+ *p = PyString_AS_STRING(arg);
+ *q = PyString_GET_SIZE(arg);
+ }
+ else { /* any buffer-like object */
+ PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
+ int count;
+ if ( pb == NULL ||
+ pb->bf_getreadbuffer == NULL ||
+ pb->bf_getsegcount == NULL )
+ return "read-only buffer";
+ if ( (*pb->bf_getsegcount)(arg, NULL) != 1 )
+ return "single-segment read-only buffer";
+ if ( (count =
+ (*pb->bf_getreadbuffer)(arg, 0, p)) < 0 )
+ return "(unspecified)";
+ *q = count;
+ }
format++;
} else {
char **p = va_arg(*p_va, char **);
@@ -597,24 +611,37 @@ convertsimple1(PyObject *arg, char **p_format, va_list *p_va)
{
if (*format == '#') { /* any buffer-like object */
void **p = (void **)va_arg(*p_va, char **);
- PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
int *q = va_arg(*p_va, int *);
- int count;
if (arg == Py_None) {
*p = 0;
*q = 0;
- } else {
- if ( pb == NULL ||
- pb->bf_getreadbuffer == NULL ||
- pb->bf_getsegcount == NULL )
- return "read-only buffer";
- if ( (*pb->bf_getsegcount)(arg, NULL) != 1 )
- return "single-segment read-only buffer";
- if ( (count = (*pb->bf_getreadbuffer)
- (arg, 0, p)) < 0 )
- return "(unspecified)";
- *q = count;
+ }
+ else if (PyString_Check(arg)) {
+ *p = PyString_AS_STRING(arg);
+ *q = PyString_GET_SIZE(arg);
+ }
+ else if (PyUnicode_Check(arg)) {
+ arg = _PyUnicode_AsDefaultEncodedString(
+ arg, NULL);
+ if (arg == NULL)
+ return "unicode conversion error";
+ *p = PyString_AS_STRING(arg);
+ *q = PyString_GET_SIZE(arg);
+ }
+ else { /* any buffer-like object */
+ PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
+ int count;
+ if ( pb == NULL ||
+ pb->bf_getreadbuffer == NULL ||
+ pb->bf_getsegcount == NULL )
+ return "read-only buffer";
+ if ( (*pb->bf_getsegcount)(arg, NULL) != 1 )
+ return "single-segment read-only buffer";
+ if ( (count =
+ (*pb->bf_getreadbuffer)(arg, 0, p)) < 0 )
+ return "(unspecified)";
+ *q = count;
}
format++;
} else {