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