From 0afff388ce38cc0a42ef6c8b9a3f815997ee0103 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marc-Andr=C3=A9=20Lemburg?= Date: Thu, 21 Sep 2000 21:08:30 +0000 Subject: [PATCH] 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. --- Python/getargs.c | 79 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 53 insertions(+), 26 deletions(-) diff --git a/Python/getargs.c b/Python/getargs.c index 1dddae4991..797e9df77d 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 { -- 2.40.0