X-Git-Url: https://git.distorted.org.uk/~mdw/ezmlm/blobdiff_plain/5b62e993b0af39700031c2875d7f6654e6a02850..f8beb284087c279acfb30506f5bb32baa4949b44:/encodeB.c diff --git a/encodeB.c b/encodeB.c new file mode 100644 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); +} +