blob: 1259ed12dffe5c9bb690698f5398a7f8c32ba06b [file] [log] [blame]
Gregory P. Smithe3f63932015-04-26 00:41:00 +00001/* bytes to hex implementation */
2
3#include "Python.h"
4
5static 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();
Gregory P. Smithf7894652015-04-25 23:51:39 -070021 retval = NULL; /* silence a compiler warning, assigned later. */
Gregory P. Smithe3f63932015-04-26 00:41:00 +000022 } 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
Gregory P. Smith5d0ccd22015-04-26 04:59:52 +000051PyAPI_FUNC(PyObject *) _Py_strhex(const char* argbuf, const Py_ssize_t arglen)
Gregory P. Smithe3f63932015-04-26 00:41:00 +000052{
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. */
Gregory P. Smith5d0ccd22015-04-26 04:59:52 +000058PyAPI_FUNC(PyObject *) _Py_strhex_bytes(const char* argbuf, const Py_ssize_t arglen)
Gregory P. Smithe3f63932015-04-26 00:41:00 +000059{
60 return _Py_strhex_impl(argbuf, arglen, 1);
61}