blob: b8f314607c19836c0370e1a91253490f5097f8b9 [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();
21 } else {
22 retval = PyUnicode_New(arglen*2, 127);
23 if (!retval)
24 return NULL;
25 retbuf = PyUnicode_1BYTE_DATA(retval);
26 }
27
28 /* make hex version of string, taken from shamodule.c */
29 for (i=j=0; i < arglen; i++) {
30 unsigned char c;
31 c = (argbuf[i] >> 4) & 0xf;
32 retbuf[j++] = Py_hexdigits[c];
33 c = argbuf[i] & 0xf;
34 retbuf[j++] = Py_hexdigits[c];
35 }
36
37 if (return_bytes) {
38 retval = PyBytes_FromStringAndSize((const char *)retbuf, arglen*2);
39 PyMem_Free(retbuf);
40 }
41#ifdef Py_DEBUG
42 else {
43 assert(_PyUnicode_CheckConsistency(retval, 1));
44 }
45#endif
46
47 return retval;
48}
49
50PyObject *_Py_strhex(const char* argbuf, const Py_ssize_t arglen)
51{
52 return _Py_strhex_impl(argbuf, arglen, 0);
53}
54
55/* Same as above but returns a bytes() instead of str() to avoid the
56 * need to decode the str() when bytes are needed. */
57PyObject *_Py_strhex_bytes(const char* argbuf, const Py_ssize_t arglen)
58{
59 return _Py_strhex_impl(argbuf, arglen, 1);
60}