Import ezmlm-idx 0.40
[ezmlm] / encodeB.c
diff --git a/encodeB.c b/encodeB.c
new file mode 100644 (file)
index 0000000..1672de9
--- /dev/null
+++ b/encodeB.c
@@ -0,0 +1,99 @@
+/* $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);
+}
+