1 /* source: xio-ascii.c */
2 /* Copyright Gerhard Rieger and contributors (see file CHANGES) */
3 /* Published under the GNU General Public License V.2, see file COPYING */
5 /* this file contains functions for text encoding, decoding, and conversions */
12 #include "xio-ascii.h"
14 /* for each 6 bit pattern we have an ASCII character in the arry */
15 const static int base64chars
[] = {
16 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
17 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
18 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
19 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
20 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
21 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
22 'w', 'x', 'y', 'z', '0', '1', '2', '3',
23 '4', '5', '6', '7', '8', '9', '+', '/',
26 #define CHAR64(c) (base64chars[c])
29 xiob64encodeline(const char *data
, /* input data */
30 size_t bytes
, /* length of input data, >=0 */
31 char *coded
/* output buffer, must be long enough */
37 *coded
++ = CHAR64(c1
>>2);
39 *coded
++ = CHAR64((c1
&0x03)<<4);
44 *coded
++ = CHAR64(((c1
&0x03)<<4)|(c2
>>4));
46 *coded
++ = CHAR64((c2
&0x0f)<<2);
49 c3
= *data
++; --bytes
;
50 *coded
++ = CHAR64(((c2
&0x0f)<<2)|(c3
>>6));
51 *coded
++ = CHAR64(c3
&0x3f);
60 /* sanitize "untrusted" text, replacing special control characters with the C
61 string version ("\x"), and replacing unprintable chars with ".".
62 text can grow to double size, so keep output buffer long enough!
63 returns a pointer to the first untouched byte of the output buffer.
65 char *xiosanitize(const char *data
, /* input data */
66 size_t bytes
, /* length of input data, >=0 */
67 char *coded
/* output buffer, must be long enough */
72 c
= *(unsigned char *)data
++;
74 case '\0' : *coded
++ = '\\'; *coded
++ = '0'; break;
75 case '\a' : *coded
++ = '\\'; *coded
++ = 'a'; break;
76 case '\b' : *coded
++ = '\\'; *coded
++ = 'b'; break;
77 case '\t' : *coded
++ = '\\'; *coded
++ = 't'; break;
78 case '\n' : *coded
++ = '\\'; *coded
++ = 'n'; break;
79 case '\v' : *coded
++ = '\\'; *coded
++ = 'v'; break;
80 case '\f' : *coded
++ = '\\'; *coded
++ = 'f'; break;
81 case '\r' : *coded
++ = '\\'; *coded
++ = 'r'; break;
82 case '\'' : *coded
++ = '\\'; *coded
++ = '\''; break;
83 case '\"' : *coded
++ = '\\'; *coded
++ = '"'; break;
84 case '\\' : *coded
++ = '\\'; *coded
++ = '\\'; break;
97 /* print the bytes in hex */
99 xiohexdump(const unsigned char *data
, size_t bytes
, char *coded
) {
101 while (bytes
-- > 0) {
102 if (space
) { *coded
++ = ' '; }
103 coded
+= sprintf(coded
, "%02x", *data
++);
109 /* write the binary data to output buffer codbuff in human readable form.
110 bytes gives the length of the data, codlen the available space in codbuff.
111 coding specifies how the data is to be presented. Not much to select now.
112 returns a pointer to the first char in codbuff that has not been overwritten;
113 it might also point to the first char after the buffer!
114 this function does not write a terminating \0
117 _xiodump(const unsigned char *data
, size_t bytes
, char *codbuff
, size_t codlen
,
120 int space
= coding
& 0xff;
122 if (bytes
<= 0) { return codbuff
; }
123 if (codlen
< 1) { return codbuff
; }
124 if (space
== 0) space
= -1;
126 ; /* for canonical reasons */
128 /* simple hexadecimal output */
129 if (3*bytes
+1 > codlen
) {
130 bytes
= (codlen
-1)/3; /* "truncate" data so generated text fits */
133 while (bytes
-- > 0) {
134 if (start
== 0 && space
== 0) {
136 space
= (coding
& 0xff);
138 codbuff
+= sprintf(codbuff
, "%02x", *data
++);
145 /* write the binary data to codbuff in human readable form.
146 bytes gives the length of the data, codlen the available space in codbuff.
147 coding specifies how the data is to be presented. Not much to select now.
148 null terminates the output. returns a pointer to the output string.
151 xiodump(const unsigned char *data
, size_t bytes
, char *codbuff
, size_t codlen
,
155 result
= _xiodump(data
, bytes
, codbuff
, codlen
-1, coding
);