diff options
Diffstat (limited to 'Python/pystrhex.c')
-rw-r--r-- | Python/pystrhex.c | 133 |
1 files changed, 0 insertions, 133 deletions
diff --git a/Python/pystrhex.c b/Python/pystrhex.c deleted file mode 100644 index 9d34f71..0000000 --- a/Python/pystrhex.c +++ /dev/null @@ -1,133 +0,0 @@ -/* bytes to hex implementation */ - -#include "Python.h" - -#include "pystrhex.h" - -static PyObject *_Py_strhex_impl(const char* argbuf, const Py_ssize_t arglen, - const PyObject* sep, int bytes_per_sep_group, - const int return_bytes) -{ - PyObject *retval; - Py_UCS1* retbuf; - Py_ssize_t i, j, resultlen = 0; - Py_UCS1 sep_char = 0; - unsigned int abs_bytes_per_sep; - - if (sep) { - Py_ssize_t seplen = PyObject_Length((PyObject*)sep); - if (seplen < 0) { - return NULL; - } - if (seplen != 1) { - PyErr_SetString(PyExc_ValueError, "sep must be length 1."); - return NULL; - } - if (PyUnicode_Check(sep)) { - if (PyUnicode_READY(sep)) - return NULL; - if (PyUnicode_KIND(sep) != PyUnicode_1BYTE_KIND) { - PyErr_SetString(PyExc_ValueError, "sep must be ASCII."); - return NULL; - } - sep_char = PyUnicode_READ_CHAR(sep, 0); - } else if (PyBytes_Check(sep)) { - sep_char = PyBytes_AS_STRING(sep)[0]; - } else { - PyErr_SetString(PyExc_TypeError, "sep must be str or bytes."); - return NULL; - } - if (sep_char > 127 && !return_bytes) { - PyErr_SetString(PyExc_ValueError, "sep must be ASCII."); - return NULL; - } - } else { - bytes_per_sep_group = 0; - } - - assert(arglen >= 0); - abs_bytes_per_sep = abs(bytes_per_sep_group); - if (bytes_per_sep_group && arglen > 0) { - /* How many sep characters we'll be inserting. */ - resultlen = (arglen - 1) / abs_bytes_per_sep; - } - /* Bounds checking for our Py_ssize_t indices. */ - if (arglen >= PY_SSIZE_T_MAX / 2 - resultlen) { - return PyErr_NoMemory(); - } - resultlen += arglen * 2; - - if ((size_t)abs_bytes_per_sep >= (size_t)arglen) { - bytes_per_sep_group = 0; - abs_bytes_per_sep = 0; - } - - if (return_bytes) { - /* If _PyBytes_FromSize() were public we could avoid malloc+copy. */ - retbuf = (Py_UCS1*) PyMem_Malloc(resultlen); - if (!retbuf) - return PyErr_NoMemory(); - retval = NULL; /* silence a compiler warning, assigned later. */ - } else { - retval = PyUnicode_New(resultlen, 127); - if (!retval) - return NULL; - retbuf = PyUnicode_1BYTE_DATA(retval); - } - - /* Hexlify */ - for (i=j=0; i < arglen; ++i) { - assert(j < resultlen); - unsigned char c; - c = (argbuf[i] >> 4) & 0xf; - retbuf[j++] = Py_hexdigits[c]; - c = argbuf[i] & 0xf; - retbuf[j++] = Py_hexdigits[c]; - if (bytes_per_sep_group && i < arglen - 1) { - Py_ssize_t anchor; - anchor = (bytes_per_sep_group > 0) ? (arglen - 1 - i) : (i + 1); - if (anchor % abs_bytes_per_sep == 0) { - retbuf[j++] = sep_char; - } - } - } - assert(j == resultlen); - - if (return_bytes) { - retval = PyBytes_FromStringAndSize((const char *)retbuf, resultlen); - PyMem_Free(retbuf); - } -#ifdef Py_DEBUG - else { - assert(_PyUnicode_CheckConsistency(retval, 1)); - } -#endif - - return retval; -} - -PyObject * _Py_strhex(const char* argbuf, const Py_ssize_t arglen) -{ - return _Py_strhex_impl(argbuf, arglen, NULL, 0, 0); -} - -/* Same as above but returns a bytes() instead of str() to avoid the - * need to decode the str() when bytes are needed. */ -PyObject * _Py_strhex_bytes(const char* argbuf, const Py_ssize_t arglen) -{ - return _Py_strhex_impl(argbuf, arglen, NULL, 0, 1); -} - -/* These variants include support for a separator between every N bytes: */ - -PyObject * _Py_strhex_with_sep(const char* argbuf, const Py_ssize_t arglen, const PyObject* sep, const int bytes_per_group) -{ - return _Py_strhex_impl(argbuf, arglen, sep, bytes_per_group, 0); -} - -/* Same as above but returns a bytes() instead of str() to avoid the - * need to decode the str() when bytes are needed. */ -PyObject * _Py_strhex_bytes_with_sep(const char* argbuf, const Py_ssize_t arglen, const PyObject* sep, const int bytes_per_group) -{ - return _Py_strhex_impl(argbuf, arglen, sep, bytes_per_group, 1); -} |