--- /dev/null
+/* $Id: encodeB.c,v 1.3 1998/03/21 18:30:27 lindberg Exp $*/
+/* $Name: ezmlm-idx-040 $*/
+
+#include "stralloc.h"
+#include "uint32.h"
+#include "mime.h"
+#include "strerr.h"
+#include "errtxt.h"
+
+static void die_nomem(fatal)
+ char *fatal;
+{
+ strerr_die2x(111,fatal,ERR_NOMEM);
+}
+
+static unsigned char base64char[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+static unsigned int pos = 0;
+static unsigned int i = 0;
+static uint32 hold32;
+static unsigned char *cpout;
+
+static void addone(ch)
+unsigned char ch;
+{
+ if (!(pos++))
+ hold32 = (uint32) ch;
+ else
+ hold32 = (hold32 << 8) | ch;
+ if (pos == 3) {
+ *cpout++ = base64char[(hold32 >> 18) & 0x3f];
+ *cpout++ = base64char[(hold32 >> 12) & 0x3f];
+ *cpout++ = base64char[(hold32 >> 6) & 0x3f];
+ *cpout++ = base64char[hold32 & 0x3f];
+ if (++i == 18) {
+ *cpout++ = '\n';
+ i = 0;
+ }
+ pos = 0;
+ }
+}
+
+static void dorest()
+{
+ switch (pos) {
+ case 2:
+ hold32 = hold32 << 2;
+ *cpout++ = base64char[(hold32 >> 12) & 0x3f];
+ *cpout++ = base64char[(hold32 >> 06) & 0x3f];
+ *cpout++ = base64char[hold32 & 0x3f];
+ *cpout++ = '=';
+ break;
+ case 1:
+ hold32 = hold32 << 4;
+ *cpout++ = base64char[(hold32 >> 06) & 0x3f];
+ *cpout++ = base64char[hold32 & 0x3f];
+ *cpout++ = '=';
+ *cpout++ = '=';
+ break;
+ default:
+ break;
+ }
+ *cpout++ = '\n';
+}
+
+void encodeB(indata,n,outdata,control,fatal)
+unsigned char *indata;
+unsigned int n;
+stralloc *outdata;
+int control; /* 1 = init, 2 = flush */
+char *fatal;
+ /* converts any character with the high order bit set to */
+ /* base64. In: n chars of indata, out: stralloc outdata */
+ /* as '=' is not allowed within the block, we cannot flush after */
+ /* each line, so we carry over data from call to call. The last */
+ /* call to encodeB should have control = 2 to do the flushing. */
+ /* control = 0 resets, and the routine starts out reset. */
+{
+ register unsigned char ch;
+
+ if (control == 1) {
+ pos = 0;
+ i = 0;
+ }
+ if (!stralloc_copys(outdata,"")) die_nomem(fatal);
+ if (!stralloc_ready(outdata,n*8/3 + n/72 + 5)) die_nomem(fatal);
+ cpout = (unsigned char *) outdata->s;
+ while (n--) {
+ ch = *indata++;
+ if (ch == '\n')
+ addone('\r');
+ addone(ch);
+ }
+ if (control == 2)
+ dorest();
+ outdata->len = (unsigned int) (cpout - (unsigned char *) outdata->s);
+}
+