diff options
author | Marc-André Lemburg <mal@egenix.com> | 2000-09-21 21:08:30 (GMT) |
---|---|---|
committer | Marc-André Lemburg <mal@egenix.com> | 2000-09-21 21:08:30 (GMT) |
commit | 0afff388ce38cc0a42ef6c8b9a3f815997ee0103 (patch) | |
tree | 40bde1198117bfbef75e6cf3f1ebba6a2da32163 /Python | |
parent | 3578b77312720061ef3e5a86e3db4f3c968edf56 (diff) | |
download | cpython-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.c | 79 |
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 { |