/* -*-c-*-
*
- * $Id: base64.c,v 1.3 1999/05/21 22:14:30 mdw Exp $
+ * $Id: base64.c,v 1.7 2004/04/08 01:36:11 mdw Exp $
*
* Base64 encoding and decoding.
*
* (c) 1997 Straylight/Edgeware
*/
-/*----- Licensing notice --------------------------------------------------*
+/*----- Licensing notice --------------------------------------------------*
*
* This file is part of the mLib utilities library.
*
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
- *
+ *
* mLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Library General Public
* License along with mLib; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
-/*----- Revision history --------------------------------------------------*
- *
- * $Log: base64.c,v $
- * Revision 1.3 1999/05/21 22:14:30 mdw
- * Take advantage of the new dynamic string macros.
- *
- * 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 */
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /* 5x */
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36 ,37, 38, 39, 40, /* 6x */
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 /* 7x */
-};
+};
/*----- Main code ---------------------------------------------------------*/
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);
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;
if (ch >= 128 || ch < 0)
ch = -1;
else
- ch = base64_decodeMap[ch];
+ ch = decodemap[ch];
sz--;
if (ch == -1)
continue;
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 --- */
unsigned char buf[BUFSIZ];
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;
base64_init(&ctx);