2006-03-24 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
[pspp] / lib / base64.c
index 98d933a70dd0b23d4e837390068185a15554126f..1fe719c95c010d286b8318f9628ccb2e34bd0611 100644 (file)
@@ -1,5 +1,6 @@
 /* base64.c -- Encode binary data using printable characters.
-   Copyright (C) 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2000, 2001, 2004, 2005, 2006 Free Software
+   Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -13,7 +14,7 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software Foundation,
-   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
 
 /* Written by Simon Josefsson.  Partially adapted from GNU MailUtils
  * (mailbox/filter_trans.c, as of 2004-11-28).  Improved by review
@@ -36,7 +37,7 @@
  *   FAIL: input too long
  * if (out == NULL)
  *   FAIL: memory allocation error
- * OK: data in OUT/LEN.
+ * OK: data in OUT/OUTLEN.
  *
  */
 
@@ -50,6 +51,9 @@
 /* Get malloc. */
 #include <stdlib.h>
 
+/* Get UCHAR_MAX. */
+#include <limits.h>
+
 /* C89 compliant way to cast 'char' to 'unsigned char'. */
 static inline unsigned char
 to_uchar (char ch)
@@ -65,30 +69,34 @@ void
 base64_encode (const char *restrict in, size_t inlen,
               char *restrict out, size_t outlen)
 {
-  const char b64[64] =
+  static const char b64str[64] =
     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
   while (inlen && outlen)
     {
-      *out++ = b64[to_uchar (in[0]) >> 2];
+      *out++ = b64str[(to_uchar (in[0]) >> 2) & 0x3f];
       if (!--outlen)
        break;
-      *out++ = b64[((to_uchar (in[0]) << 4)
-                   + (--inlen ? to_uchar (in[1]) >> 4 : 0)) & 0x3f];
+      *out++ = b64str[((to_uchar (in[0]) << 4)
+                      + (--inlen ? to_uchar (in[1]) >> 4 : 0))
+                     & 0x3f];
       if (!--outlen)
        break;
       *out++ =
        (inlen
-        ? b64[((to_uchar (in[1]) << 2)
-               + (--inlen ? to_uchar (in[2]) >> 6 : 0)) & 0x3f] : '=');
+        ? b64str[((to_uchar (in[1]) << 2)
+                  + (--inlen ? to_uchar (in[2]) >> 6 : 0))
+                 & 0x3f]
+        : '=');
       if (!--outlen)
        break;
-      *out++ = inlen ? b64[to_uchar (in[2]) & 0x3f] : '=';
+      *out++ = inlen ? b64str[to_uchar (in[2]) & 0x3f] : '=';
       if (!--outlen)
        break;
       if (inlen)
        inlen--;
-      in += 3;
+      if (inlen)
+       in += 3;
     }
 
   if (outlen)
@@ -274,10 +282,16 @@ static const signed char b64[0x100] = {
   B64 (252), B64 (253), B64 (254), B64 (255)
 };
 
+#if UCHAR_MAX == 255
+# define uchar_in_range(c) true
+#else
+# define uchar_in_range(c) ((c) <= 255)
+#endif
+
 bool
 isbase64 (char ch)
 {
-  return to_uchar (ch) <= 255 && 0 <= b64[to_uchar (ch)];
+  return uchar_in_range (to_uchar (ch)) && 0 <= b64[to_uchar (ch)];
 }
 
 /* Decode base64 encoded input array IN of length INLEN to output
@@ -289,7 +303,7 @@ isbase64 (char ch)
    encountered, decoding is stopped and false is returned. */
 bool
 base64_decode (const char *restrict in, size_t inlen,
-              char *restrict out, size_t * outlen)
+              char *restrict out, size_t *outlen)
 {
   size_t outleft = *outlen;
 
@@ -376,7 +390,7 @@ base64_decode (const char *restrict in, size_t inlen,
    undefined. */
 bool
 base64_decode_alloc (const char *in, size_t inlen, char **out,
-                    size_t * outlen)
+                    size_t *outlen)
 {
   /* This may allocate a few bytes too much, depending on input,
      but it's not worth the extra CPU time to compute the exact amount.