hex.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /* Copyright (C) 2014 OSCAR lab, Stony Brook University
  2. 2017 University of North Carolina at Chapel Hill
  3. This file is part of Graphene Library OS.
  4. Graphene Library OS is free software: you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation, either version 3 of the
  7. License, or (at your option) any later version.
  8. Graphene Library OS is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  14. #ifndef HEX_H
  15. #define HEX_H
  16. #include <api.h>
  17. #include <assert.h>
  18. #include <stddef.h>
  19. #include <stdint.h>
  20. /* This function is a helper for debug printing.
  21. * It accepts a pointer to a numerical value, and
  22. * formats it as a hex string, for printing.
  23. * size is the number of bytes pointed to by hex.
  24. * str is the caller-provided buffer, len is the length of the buffer.
  25. * The len must be at least (size * 2)+1.
  26. *
  27. * Note that it does not normalize for endianness, and pads to the
  28. * size the compiler things the string is.
  29. */
  30. static inline __attribute__((always_inline))
  31. char * __bytes2hexstr(void * hex, size_t size, char *str, size_t len)
  32. {
  33. static char * ch = "0123456789abcdef";
  34. __UNUSED(len);
  35. assert(len >= size * 2 + 1);
  36. for (size_t i = 0 ; i < size ; i++) {
  37. unsigned char h = ((unsigned char *) hex)[i];
  38. str[i * 2] = ch[h / 16];
  39. str[i * 2 + 1] = ch[h % 16];
  40. }
  41. str[size * 2] = 0;
  42. return str;
  43. }
  44. #define IS_INDEXABLE(arg) (sizeof((arg)[0]))
  45. #define IS_ARRAY(arg) (IS_INDEXABLE(arg) > 0 && (((void *) &(arg)) == ((void *) (arg))))
  46. static inline __attribute__((always_inline))
  47. int8_t hex2dec(char c) {
  48. if (c >= 'A' && c <= 'F')
  49. return c - 'A' + 10;
  50. else if (c >= 'a' && c <= 'f')
  51. return c - 'a' + 10;
  52. else if (c >= '0' && c <= '9')
  53. return c - '0';
  54. else
  55. return -1;
  56. }
  57. /*
  58. * BYTES2HEXSTR converts an array into a hexadecimal string and fills into a
  59. * given buffer. The buffer size is given as an extra argument.
  60. */
  61. #define BYTES2HEXSTR(array, str, len) ({ \
  62. static_assert(IS_ARRAY(array), "`array` must be an array"); \
  63. __bytes2hexstr((array), sizeof(array), str, len);})
  64. /*
  65. * ALLOCA_BYTES2HEXSTR uses __alloca to allocate a buffer on the current frame
  66. * and then fills the hexadecimal string into the buffer.
  67. * This buffer can only be used within the caller frame (function).
  68. */
  69. #define ALLOCA_BYTES2HEXSTR(array) \
  70. (BYTES2HEXSTR(array, __alloca(sizeof(array) * 2 + 1), sizeof(array) * 2 + 1))
  71. #endif // HEX_H