2 * convert from binary data (e.g. key) to text form
3 * Copyright (C) 2000 Henry Spencer.
5 * This library is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU Library General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
10 * This library is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 * License for more details.
15 * RCSID $Id: datatot.c,v 1.1 2000/08/18 15:09:07 henry Exp $
20 static void convert(const char *src, size_t nreal, int format, char *out);
23 - datatot - convert data bytes to text
25 size_t /* true length (with NUL) for success */
26 datatot(src, srclen, format, dst, dstlen)
29 int format; /* character indicating what format */
30 char *dst; /* need not be valid if dstlen is 0 */
33 size_t inblocksize; /* process this many bytes at a time */
34 size_t outblocksize; /* producing this many */
35 size_t breakevery; /* add a _ every this many (0 means don't) */
36 size_t sincebreak; /* output bytes since last _ */
37 char inblock[10]; /* enough for any format */
38 char outblock[10]; /* enough for any format */
39 char fake[1]; /* fake output area for dstlen == 0 */
40 size_t needed; /* return value */
41 char *stop; /* where the terminating NUL will go */
42 size_t ntodo; /* remaining input */
70 case 64: /* beware, equals ' ' */
80 assert(inblocksize < sizeof(inblock));
81 assert(outblocksize < sizeof(outblock));
82 assert(breakevery % outblocksize == 0);
88 if (dstlen == 0) { /* dispose of awkward special case */
92 stop = dst + dstlen - 1;
94 nreal = strlen(prefix);
95 needed = nreal; /* for starters */
96 if (dstlen <= nreal) { /* prefix won't fit */
97 strncpy(dst, prefix, dstlen - 1);
107 if (ntodo < inblocksize) { /* incomplete input */
108 memset(inblock, 0, sizeof(inblock));
109 memcpy(inblock, src, ntodo);
115 out = (outblocksize > stop - dst) ? outblock : dst;
117 convert(src, nreal, format, out);
118 needed += outblocksize;
119 sincebreak += outblocksize;
122 assert(outblocksize > stop - dst);
123 memcpy(dst, out, stop - dst);
130 ntodo -= inblocksize;
131 if (breakevery != 0 && sincebreak >= breakevery && ntodo > 0) {
147 - convert - convert one input block to one output block
150 convert(src, nreal, format, out)
152 size_t nreal; /* how much of the input block is real */
156 static char hex[] = "0123456789abcdef";
157 static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
158 "abcdefghijklmnopqrstuvwxyz"
161 unsigned char c1, c2, c3;
167 c = (unsigned char)*src;
168 *out++ = hex[c >> 4];
169 *out++ = hex[c & 0xf];
172 c1 = (unsigned char)*src++;
173 c2 = (unsigned char)*src++;
174 c3 = (unsigned char)*src++;
175 *out++ = base64[c1 >> 2]; /* top 6 bits of c1 */
176 c = (c1 & 0x3) << 4; /* bottom 2 of c1... */
177 c |= c2 >> 4; /* ...top 4 of c2 */
182 c = (c2 & 0xf) << 2; /* bottom 4 of c2... */
183 c |= c3 >> 6; /* ...top 2 of c3 */
189 *out++ = base64[c3 & 0x3f]; /* bottom 6 of c3 */
192 assert(nreal == 0); /* unknown format */
198 - datatoa - convert data to ASCII
199 * backward-compatibility synonym for datatot
201 size_t /* true length (with NUL) for success */
202 datatoa(src, srclen, format, dst, dstlen)
205 int format; /* character indicating what format */
206 char *dst; /* need not be valid if dstlen is 0 */
209 return datatot(src, srclen, format, dst, dstlen);
213 - bytestoa - convert data bytes to ASCII
214 * backward-compatibility synonym for datatot
216 size_t /* true length (with NUL) for success */
217 bytestoa(src, srclen, format, dst, dstlen)
220 int format; /* character indicating what format */
221 char *dst; /* need not be valid if dstlen is 0 */
224 return datatot(src, srclen, format, dst, dstlen);