You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

61 lines
1.6 KiB

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