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