xs_hex.h 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /* copyright (c) 2022 - 2023 grunfink et al. / MIT license */
  2. #ifndef _XS_HEX_H
  3. #define _XS_HEX_H
  4. xs_str *xs_hex_enc(const xs_val *data, int size);
  5. xs_val *xs_hex_dec(const xs_str *hex, int *size);
  6. int xs_is_hex(const char *str);
  7. #ifdef XS_IMPLEMENTATION
  8. /** hex **/
  9. static char rev_hex_digits[] = "fedcba9876543210FEDCBA";
  10. xs_str *xs_hex_enc(const xs_val *data, int size)
  11. /* returns an hexdump of data */
  12. {
  13. xs_str *s;
  14. char *p;
  15. int n;
  16. p = s = xs_realloc(NULL, _xs_blk_size(size * 2 + 1));
  17. for (n = 0; n < size; n++) {
  18. *p++ = rev_hex_digits[0xf - (*data >> 4 & 0xf)];
  19. *p++ = rev_hex_digits[0xf - (*data & 0xf)];
  20. data++;
  21. }
  22. *p = '\0';
  23. return s;
  24. }
  25. xs_val *xs_hex_dec(const xs_str *hex, int *size)
  26. /* decodes an hexdump into data */
  27. {
  28. int sz = strlen(hex);
  29. xs_val *s = NULL;
  30. char *p;
  31. int n;
  32. if (sz % 2)
  33. return NULL;
  34. p = s = xs_realloc(NULL, _xs_blk_size(sz / 2 + 1));
  35. for (n = 0; n < sz; n += 2) {
  36. char *d1 = strchr(rev_hex_digits, *hex++);
  37. char *d2 = strchr(rev_hex_digits, *hex++);
  38. if (!d1 || !d2) {
  39. /* decoding error */
  40. return xs_free(s);
  41. }
  42. *p++ = (0xf - ((d1 - rev_hex_digits) & 0xf)) << 4 |
  43. (0xf - ((d2 - rev_hex_digits) & 0xf));
  44. }
  45. *p = '\0';
  46. *size = sz / 2;
  47. return s;
  48. }
  49. int xs_is_hex(const char *str)
  50. /* returns 1 if str is an hex string */
  51. {
  52. while (*str) {
  53. if (strchr(rev_hex_digits, *str++) == NULL)
  54. return 0;
  55. }
  56. return 1;
  57. }
  58. #endif /* XS_IMPLEMENTATION */
  59. #endif /* _XS_HEX_H */