Import ezmlm-idx 0.40
[ezmlm] / encodeB.c
CommitLineData
f8beb284
MW
1/* $Id: encodeB.c,v 1.3 1998/03/21 18:30:27 lindberg Exp $*/
2/* $Name: ezmlm-idx-040 $*/
3
4#include "stralloc.h"
5#include "uint32.h"
6#include "mime.h"
7#include "strerr.h"
8#include "errtxt.h"
9
10static void die_nomem(fatal)
11 char *fatal;
12{
13 strerr_die2x(111,fatal,ERR_NOMEM);
14}
15
16static unsigned char base64char[] =
17 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
18
19static unsigned int pos = 0;
20static unsigned int i = 0;
21static uint32 hold32;
22static unsigned char *cpout;
23
24static void addone(ch)
25unsigned char ch;
26{
27 if (!(pos++))
28 hold32 = (uint32) ch;
29 else
30 hold32 = (hold32 << 8) | ch;
31 if (pos == 3) {
32 *cpout++ = base64char[(hold32 >> 18) & 0x3f];
33 *cpout++ = base64char[(hold32 >> 12) & 0x3f];
34 *cpout++ = base64char[(hold32 >> 6) & 0x3f];
35 *cpout++ = base64char[hold32 & 0x3f];
36 if (++i == 18) {
37 *cpout++ = '\n';
38 i = 0;
39 }
40 pos = 0;
41 }
42}
43
44static void dorest()
45{
46 switch (pos) {
47 case 2:
48 hold32 = hold32 << 2;
49 *cpout++ = base64char[(hold32 >> 12) & 0x3f];
50 *cpout++ = base64char[(hold32 >> 06) & 0x3f];
51 *cpout++ = base64char[hold32 & 0x3f];
52 *cpout++ = '=';
53 break;
54 case 1:
55 hold32 = hold32 << 4;
56 *cpout++ = base64char[(hold32 >> 06) & 0x3f];
57 *cpout++ = base64char[hold32 & 0x3f];
58 *cpout++ = '=';
59 *cpout++ = '=';
60 break;
61 default:
62 break;
63 }
64 *cpout++ = '\n';
65}
66
67void encodeB(indata,n,outdata,control,fatal)
68unsigned char *indata;
69unsigned int n;
70stralloc *outdata;
71int control; /* 1 = init, 2 = flush */
72char *fatal;
73 /* converts any character with the high order bit set to */
74 /* base64. In: n chars of indata, out: stralloc outdata */
75 /* as '=' is not allowed within the block, we cannot flush after */
76 /* each line, so we carry over data from call to call. The last */
77 /* call to encodeB should have control = 2 to do the flushing. */
78 /* control = 0 resets, and the routine starts out reset. */
79{
80 register unsigned char ch;
81
82 if (control == 1) {
83 pos = 0;
84 i = 0;
85 }
86 if (!stralloc_copys(outdata,"")) die_nomem(fatal);
87 if (!stralloc_ready(outdata,n*8/3 + n/72 + 5)) die_nomem(fatal);
88 cpout = (unsigned char *) outdata->s;
89 while (n--) {
90 ch = *indata++;
91 if (ch == '\n')
92 addone('\r');
93 addone(ch);
94 }
95 if (control == 2)
96 dorest();
97 outdata->len = (unsigned int) (cpout - (unsigned char *) outdata->s);
98}
99