chiark / gitweb /
Expunge revision histories in files.
[mLib] / base64.c
index 5f5009a9a86854eb71b5040f86fcd0e6269763a1..60bb040ae3a74383c38df2ea1d7469a075e62560 100644 (file)
--- a/base64.c
+++ b/base64.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: base64.c,v 1.2 1999/05/18 21:45:27 mdw Exp $
+ * $Id: base64.c,v 1.7 2004/04/08 01:36:11 mdw Exp $
  *
  * Base64 encoding and decoding.
  *
  * MA 02111-1307, USA.
  */
 
-/*----- Revision history --------------------------------------------------*
- *
- * $Log: base64.c,v $
- * Revision 1.2  1999/05/18 21:45:27  mdw
- * Allow Base64 encode and decode of arbitrary rubbish.
- *
- * Revision 1.1  1999/05/17 20:35:00  mdw
- * Base64 encoding and decoding support.
- *
- */
-
 /*----- Header files ------------------------------------------------------*/
 
 #include <stdio.h>
 
 /*----- Important tables --------------------------------------------------*/
 
-static const char base64_encodeMap[] = { "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-                                        "abcdefghijklmnopqrstuvwxyz" 
-                                        "0123456789+/" };
+static const char encodemap[] = { "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+                                 "abcdefghijklmnopqrstuvwxyz" 
+                                 "0123456789+/" };
 
-static const signed char base64_decodeMap[] = {
+static const signed char decodemap[] = {
   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 0x */
   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  /* 1x */
   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,  /* 2x */
@@ -93,10 +82,10 @@ void base64_encode(base64_ctx *ctx,
       qsz++;
       sz--;
       if (qsz == 3) {
-       DPUTC(d, base64_encodeMap[(acc >> 18) & 0x3f]);
-       DPUTC(d, base64_encodeMap[(acc >> 12) & 0x3f]);
-       DPUTC(d, base64_encodeMap[(acc >>  6) & 0x3f]);
-       DPUTC(d, base64_encodeMap[(acc >>  0) & 0x3f]);
+       DPUTC(d, encodemap[(acc >> 18) & 0x3f]);
+       DPUTC(d, encodemap[(acc >> 12) & 0x3f]);
+       DPUTC(d, encodemap[(acc >>  6) & 0x3f]);
+       DPUTC(d, encodemap[(acc >>  0) & 0x3f]);
        ctx->lnlen += 4;
        if (ctx->maxline && ctx->lnlen >= ctx->maxline) {
          dstr_puts(d, ctx->indent);
@@ -118,17 +107,17 @@ void base64_encode(base64_ctx *ctx,
        break;
       case 1:
        acc <<= 16;
-       DPUTC(d, base64_encodeMap[(acc >> 18) & 0x3f]);
-       DPUTC(d, base64_encodeMap[(acc >> 12) & 0x3f]);
+       DPUTC(d, encodemap[(acc >> 18) & 0x3f]);
+       DPUTC(d, encodemap[(acc >> 12) & 0x3f]);
        DPUTC(d, '=');
        DPUTC(d, '=');
        ctx->lnlen += 4;
        break;
       case 2:
        acc <<= 8;
-       DPUTC(d, base64_encodeMap[(acc >> 18) & 0x3f]);
-       DPUTC(d, base64_encodeMap[(acc >> 12) & 0x3f]);
-       DPUTC(d, base64_encodeMap[(acc >>  6) & 0x3f]);
+       DPUTC(d, encodemap[(acc >> 18) & 0x3f]);
+       DPUTC(d, encodemap[(acc >> 12) & 0x3f]);
+       DPUTC(d, encodemap[(acc >>  6) & 0x3f]);
        DPUTC(d, '=');
        ctx->lnlen += 4;
        break;
@@ -169,7 +158,7 @@ void base64_decode(base64_ctx *ctx,
       if (ch >= 128 || ch < 0)
        ch = -1;
       else
-       ch = base64_decodeMap[ch];
+       ch = decodemap[ch];
       sz--;
       if (ch == -1)
        continue;
@@ -209,14 +198,24 @@ void base64_decode(base64_ctx *ctx,
     unsigned long acc = ctx->acc;
     unsigned qsz = ctx->qsz;
 
-    /* --- Now fiddle with everything else --- */
+    /* --- Now fiddle with everything else --- *
+     *
+     * There's a bodge here for invalid encodings which have only one hextet
+     * in the final group.  I'm not sure this is really worth having, but it
+     * might save some unexpected behaviour.  (Not that you won't still get
+     * unexpected behaviour if the stream is completely empty, of course.)
+     */
 
-    acc <<= 6 * (4 - qsz);
-    qsz *= 6;
-    while (qsz > 8) {
-      DPUTC(d, (acc >> 16) & 0xff);
-      acc <<= 8;
-      qsz -= 8;
+    if (qsz) {
+      acc <<= 6 * (4 - qsz);
+      qsz *= 6;
+      if (qsz < 8)
+       qsz = 8;
+      while (qsz >= 8) {
+       DPUTC(d, (acc >> 16) & 0xff);
+       acc <<= 8;
+       qsz -= 8;
+      }
     }
 
     /* --- That seems to be good enough --- */
@@ -251,12 +250,11 @@ void base64_init(base64_ctx *ctx)
 int main(int argc, char *argv[])
 {
   unsigned char buf[BUFSIZ];
-  dstr d;
+  dstr d = DSTR_INIT;
   base64_ctx ctx;
-  void (*proc)(base64_ctx *, const unsigned char *, size_t, dstr *);
+  void (*proc)(base64_ctx *, const void *, size_t, dstr *);
   size_t sz;
 
-  dstr_create(&d);
   base64_init(&ctx);
 
   if (argc > 1 && strcmp(argv[1], "-d") == 0)