1 /* bytes to hex implementation */
2
3 #include "Python.h"
4
_Py_strhex_impl(const char * argbuf,const Py_ssize_t arglen,int return_bytes)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
_Py_strhex(const char * argbuf,const Py_ssize_t arglen)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. */
_Py_strhex_bytes(const char * argbuf,const Py_ssize_t arglen)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