summaryrefslogtreecommitdiff
path: root/xs_hex.h
diff options
context:
space:
mode:
authorGravatar default2023-12-27 12:54:38 +0100
committerGravatar default2023-12-27 12:54:38 +0100
commitbf435af788d387b3d97fd744e3b1f6a73795beb8 (patch)
tree6d193edd88ef3818bffd9278ddab0248e1108ef3 /xs_hex.h
parentAlso log the job_fifo len in status.txt. (diff)
downloadpenes-snac2-bf435af788d387b3d97fd744e3b1f6a73795beb8.tar.gz
penes-snac2-bf435af788d387b3d97fd744e3b1f6a73795beb8.tar.xz
penes-snac2-bf435af788d387b3d97fd744e3b1f6a73795beb8.zip
Backport from xs.
Diffstat (limited to '')
-rw-r--r--xs_hex.h138
1 files changed, 103 insertions, 35 deletions
diff --git a/xs_hex.h b/xs_hex.h
index 2d87a65..21183f4 100644
--- a/xs_hex.h
+++ b/xs_hex.h
@@ -4,65 +4,129 @@
4 4
5#define _XS_HEX_H 5#define _XS_HEX_H
6 6
7xs_str *xs_hex_enc(const xs_val *data, int size); 7 int xs_is_hex_digit(char str);
8xs_val *xs_hex_dec(const xs_str *hex, int *size); 8 void xs_hex_enc_1(char **dst, const char **src);
9int 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
15static char rev_hex_digits[] = "fedcba9876543210FEDCBA"; 26static char rev_hex_digits[] = "fedcba9876543210FEDCBA";
16 27
17xs_str *xs_hex_enc(const xs_val *data, int size) 28int 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++) { 35void 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
49int 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
38xs_val *xs_hex_dec(const xs_str *hex, int *size) 72char *_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) { 84char *_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
104xs_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
117xs_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)
71int xs_is_hex(const char *str) 135int 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