From dd9db1046e4da149e246938895258e8b6025958e Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Mon, 21 Oct 2019 01:43:54 +0100 Subject: [PATCH] *.c: Introduce a new input conversion for binary strings. One of the major differences in Python 3 is that it firmly distinguishes between binary and text strings: the former consist of small integers, while the latter consist of Unicode scalars. The Python 3 `s#' conversion's main purpose is to accept text strings, and though it will also accept binary strings it's not really ideal for the purpose. Python 3 introduces a new conversion `y#' specifically for binary strings, though this isn't quite what we want because, for some reason, it /doesn't/ work with bufferish objects which require explicit release. The best answer seems to be to introduce our own custom conversion for binary strings, so we do this here, replacing all of the binary-input argument conversions. While we're at it, replace all of the by-steam argument conversions using `PyObject_AsReadBuffer' too. --- pyke.c | 19 +++++++++++++++++++ pyke.h | 2 ++ 2 files changed, 21 insertions(+) diff --git a/pyke.c b/pyke.c index 29dd8c5..d874763 100644 --- a/pyke.c +++ b/pyke.c @@ -101,6 +101,25 @@ end: return (0); } +int convbin(PyObject *o, void *pp) +{ + struct bin *r = pp; + + if (PyString_Check(o)) { + r->p = PyString_AS_STRING(o); + r->sz = PyString_GET_SIZE(o); + return (1); + } + if (PyUnicode_Check(o)) { + o = _PyUnicode_AsDefaultEncodedString(o, 0); + if (!o) return (0); + r->p = PyString_AS_STRING(o); + r->sz = PyString_GET_SIZE(o); + return (1); + } + return (PyObject_AsReadBuffer(o, &r->p, &r->sz) ? 0 : 1); +} + /*----- Miscellaneous utilities -------------------------------------------*/ PyObject *abstract_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw) diff --git a/pyke.h b/pyke.h index e3b2083..893dd6d 100644 --- a/pyke.h +++ b/pyke.h @@ -169,10 +169,12 @@ extern void restore_exception(struct excinfo *, const char *, ...); /* Input conversion functions for standard kinds of objects, with overflow * checking where applicable. */ +struct bin { const void *p; Py_ssize_t sz; }; extern int convulong(PyObject *, void *); /* unsigned long */ extern int convuint(PyObject *, void *); /* unsigned int */ extern int convszt(PyObject *, void *); /* size_t */ extern int convbool(PyObject *, void *); /* bool */ +extern int convbin(PyObject *, void *); /* read buffer holding bytes */ /* Output conversions. */ extern PyObject *getbool(int); /* bool */ -- 2.11.0