1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
/* copyright (c) 2022 - 2026 grunfink et al. / MIT license */
#ifndef _XS_HEX_H
#define _XS_HEX_H
int xs_is_hex_digit(char str);
void xs_hex_enc_1(char **dst, const char **src);
int xs_hex_dec_1(char **dst, const char **src);
char *_xs_hex_enc(char *dst, const char *src, int src_size);
char *_xs_hex_dec(char *dst, const char *src, int src_size);
#ifdef _XS_H
xs_str *xs_hex_enc(const xs_val *data, int size);
xs_val *xs_hex_dec(const xs_str *hex, int *size);
int xs_is_hex(const char *str);
#endif /* _XS_H */
#ifdef XS_IMPLEMENTATION
#include <string.h>
/** hex **/
static char rev_hex_digits[] = "fedcba9876543210FEDCBA";
int xs_is_hex_digit(char str)
/* checks if the char is an hex digit */
{
return strchr(rev_hex_digits, str) != NULL;
}
void xs_hex_enc_1(char **dst, const char **src)
/* decodes one character into two hex digits */
{
const char *i = *src;
char *o = *dst;
*o++ = rev_hex_digits[0xf - (*i >> 4 & 0xf)];
*o++ = rev_hex_digits[0xf - (*i & 0xf)];
*src = i + 1;
*dst = o;
}
int xs_hex_dec_1(char **dst, const char **src)
/* decodes two hex digits (returns 0 on error) */
{
const char *i = *src;
char *o = *dst;
char *d1 = strchr(rev_hex_digits, *i++);
char *d2 = strchr(rev_hex_digits, *i++);
if (!d1 || !d2) {
/* decoding error */
return 0;
}
*o++ = (0xf - ((d1 - rev_hex_digits) & 0xf)) << 4 |
(0xf - ((d2 - rev_hex_digits) & 0xf));
*src = i;
*dst = o;
return 1;
}
char *_xs_hex_enc(char *dst, const char *src, int src_size)
/* hex-encodes the src buffer into dst, which has enough size */
{
const char *e = src + src_size;
while (src < e)
xs_hex_enc_1(&dst, &src);
return dst;
}
char *_xs_hex_dec(char *dst, const char *src, int src_size)
/* hex-decodes the src string int dst, which has enough size.
return NULL on decoding errors or the final position of dst */
{
if (src_size % 2)
return NULL;
const char *e = src + src_size;
while (src < e) {
if (!xs_hex_dec_1(&dst, &src))
return NULL;
}
return dst;
}
#ifdef _XS_H
xs_str *xs_hex_enc(const xs_val *data, int size)
/* returns an hexdump of data */
{
xs_str *s = xs_realloc(NULL, _xs_blk_size(size * 2 + 1));
char *q = _xs_hex_enc(s, data, size);
*q = '\0';
return s;
}
xs_val *xs_hex_dec(const xs_str *hex, int *size)
/* decodes an hexdump into data */
{
int sz = strlen(hex);
xs_val *s = NULL;
*size = sz / 2;
s = xs_realloc(NULL, _xs_blk_size(*size + 1));
if (!_xs_hex_dec(s, hex, sz))
return xs_free(s);
s[*size] = '\0';
return s;
}
int xs_is_hex(const char *str)
/* returns 1 if str is an hex string */
{
if (strlen(str) % 2)
return 0;
while (*str) {
if (!xs_is_hex_digit(*str++))
return 0;
}
return 1;
}
#endif /* _XS_H */
#endif /* XS_IMPLEMENTATION */
#endif /* _XS_HEX_H */
|