Home | History | Annotate | Download | only in Python
      1 /* bytes to hex implementation */
      2 
      3 #include "Python.h"
      4 
      5 static PyObject *_Py_strhex_impl(const char* argbuf, const Py_ssize_t arglen,
      6                                  int return_bytes)
      7 {
      8     PyObject *retval;
      9     Py_UCS1* retbuf;
     10     Py_ssize_t i, j;
     11 
     12     assert(arglen >= 0);
     13     if (arglen > PY_SSIZE_T_MAX / 2)
     14         return PyErr_NoMemory();
     15 
     16     if (return_bytes) {
     17         /* If _PyBytes_FromSize() were public we could avoid malloc+copy. */
     18         retbuf = (Py_UCS1*) PyMem_Malloc(arglen*2);
     19 	if (!retbuf)
     20 	    return PyErr_NoMemory();
     21         retval = NULL;  /* silence a compiler warning, assigned later. */
     22     } else {
     23 	retval = PyUnicode_New(arglen*2, 127);
     24 	if (!retval)
     25 	    return NULL;
     26 	retbuf = PyUnicode_1BYTE_DATA(retval);
     27     }
     28 
     29     /* make hex version of string, taken from shamodule.c */
     30     for (i=j=0; i < arglen; i++) {
     31         unsigned char c;
     32         c = (argbuf[i] >> 4) & 0xf;
     33         retbuf[j++] = Py_hexdigits[c];
     34         c = argbuf[i] & 0xf;
     35         retbuf[j++] = Py_hexdigits[c];
     36     }
     37 
     38     if (return_bytes) {
     39         retval = PyBytes_FromStringAndSize((const char *)retbuf, arglen*2);
     40         PyMem_Free(retbuf);
     41     }
     42 #ifdef Py_DEBUG
     43     else {
     44         assert(_PyUnicode_CheckConsistency(retval, 1));
     45     }
     46 #endif
     47 
     48     return retval;
     49 }
     50 
     51 PyAPI_FUNC(PyObject *) _Py_strhex(const char* argbuf, const Py_ssize_t arglen)
     52 {
     53     return _Py_strhex_impl(argbuf, arglen, 0);
     54 }
     55 
     56 /* Same as above but returns a bytes() instead of str() to avoid the
     57  * need to decode the str() when bytes are needed. */
     58 PyAPI_FUNC(PyObject *) _Py_strhex_bytes(const char* argbuf, const Py_ssize_t arglen)
     59 {
     60     return _Py_strhex_impl(argbuf, arglen, 1);
     61 }
     62