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.

63 lines
1.7 KiB

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