-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathxs_hex.h
153 lines (105 loc) · 2.91 KB
/
xs_hex.h
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 - 2024 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 */