]> diplodocus.org Git - nmh/blob - sbr/base64.c
Added test-anno, test-dist, test-msgchk, and test-rcvtty.
[nmh] / sbr / base64.c
1 /*
2 * base64.c -- routines for converting to base64
3 *
4 * This code is Copyright (c) 2012, by the authors of nmh. See the
5 * COPYRIGHT file in the root directory of the nmh distribution for
6 * complete copyright information.
7 */
8
9 #include <h/mh.h>
10 #include <h/mime.h>
11
12 static char nib2b64[0x40+1] =
13 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
14
15 int
16 writeBase64aux (FILE *in, FILE *out)
17 {
18 unsigned int cc, n;
19 char inbuf[3];
20
21 n = BPERLIN;
22 while ((cc = fread (inbuf, sizeof(*inbuf), sizeof(inbuf), in)) > 0) {
23 unsigned long bits;
24 char *bp;
25 char outbuf[4];
26
27 if (cc < sizeof(inbuf)) {
28 inbuf[2] = 0;
29 if (cc < sizeof(inbuf) - 1)
30 inbuf[1] = 0;
31 }
32 bits = (inbuf[0] & 0xff) << 16;
33 bits |= (inbuf[1] & 0xff) << 8;
34 bits |= inbuf[2] & 0xff;
35
36 for (bp = outbuf + sizeof(outbuf); bp > outbuf; bits >>= 6)
37 *--bp = nib2b64[bits & 0x3f];
38 if (cc < sizeof(inbuf)) {
39 outbuf[3] = '=';
40 if (cc < sizeof inbuf - 1)
41 outbuf[2] = '=';
42 }
43
44 fwrite (outbuf, sizeof(*outbuf), sizeof(outbuf), out);
45
46 if (cc < sizeof(inbuf)) {
47 putc ('\n', out);
48 return OK;
49 }
50
51 if (--n <= 0) {
52 n = BPERLIN;
53 putc ('\n', out);
54 }
55 }
56 if (n != BPERLIN)
57 putc ('\n', out);
58
59 return OK;
60 }
61
62
63 /* Caller is responsible for ensuring that the out array is long
64 enough. Given length is that of in, out should be have at
65 least this capacity:
66 4 * [length/3] + length/57 + 2
67 But double the length will certainly be sufficient. */
68 int
69 writeBase64 (unsigned char *in, size_t length, unsigned char *out)
70 {
71 unsigned int n = BPERLIN;
72
73 while (1) {
74 unsigned long bits;
75 unsigned char *bp;
76 unsigned int cc;
77 for (cc = 0, bp = in; length > 0 && cc < 3; ++cc, ++bp, --length)
78 /* empty */ ;
79
80 if (cc == 0) {
81 break;
82 } else {
83 bits = (in[0] & 0xff) << 16;
84 if (cc > 1) {
85 bits |= (in[1] & 0xff) << 8;
86 if (cc > 2) {
87 bits |= in[2] & 0xff;
88 }
89 }
90 }
91
92 for (bp = out + 4; bp > out; bits >>= 6)
93 *--bp = nib2b64[bits & 0x3f];
94 if (cc < 3) {
95 out[3] = '=';
96 if (cc < 2)
97 out[2] = '=';
98 out += 4;
99 n = 0;
100 break;
101 }
102
103 in += 3;
104 out += 4;
105 if (--n <= 0) {
106 n = BPERLIN;
107 *out++ = '\n';
108 }
109 }
110 if (n != BPERLIN)
111 *out++ = '\n';
112
113 *out = '\0';
114
115 return OK;
116 }