chiark / gitweb /
@@@ more mess
[mLib] / codec / baseconv.c
index 1d507359ae75f1975b6f87d7d16c2740224a99b3..7ab32df420215174515a8166f33acd6f3faf5479 100644 (file)
@@ -35,6 +35,7 @@
 #include "alloc.h"
 #include "codec.h"
 #include "dstr.h"
 #include "alloc.h"
 #include "codec.h"
 #include "dstr.h"
+#include "macros.h"
 #include "sub.h"
 
 #include "base64.h"
 #include "sub.h"
 
 #include "base64.h"
@@ -48,6 +49,7 @@
 #define NV -1                          /* Not valid */
 #define PC -2                          /* Padding character */
 #define NL -3                          /* Newline character */
 #define NV -1                          /* Not valid */
 #define PC -2                          /* Padding character */
 #define NL -3                          /* Newline character */
+#define SP -4                          /* Space character */
 
 /* --- Base64 --- */
 
 
 /* --- Base64 --- */
 
@@ -63,27 +65,27 @@ static const char
                            "0123456789-_" };
 
 static const signed char decodemap_base64[] = {
                            "0123456789-_" };
 
 static const signed char decodemap_base64[] = {
-  NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NL, NV, NV, NL, NV, NV,  /* 0x */
+  NV, NV, NV, NV, NV, NV, NV, NV, NV, SP, NL, NV, SP, NL, NV, NV,  /* 0x */
   NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV,  /* 1x */
   NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV,  /* 1x */
-  NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, 62, NV, NV, NV, 63,  /* 2x */
+  SP, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, 62, NV, NV, NV, 63,  /* 2x */
   52, 53, 54, 55, 56, 57, 58, 59, 60, 61, NV, NV, NV, PC, NV, NV,  /* 3x */
   NV,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,  /* 4x */
   15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, NV, NV, NV, NV, NV,  /* 5x */
   NV, 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, NV, NV, NV, NV, NV   /* 7x */
 }, decodemap_file64[] = {
   52, 53, 54, 55, 56, 57, 58, 59, 60, 61, NV, NV, NV, PC, NV, NV,  /* 3x */
   NV,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,  /* 4x */
   15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, NV, NV, NV, NV, NV,  /* 5x */
   NV, 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, NV, NV, NV, NV, NV   /* 7x */
 }, decodemap_file64[] = {
-  NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NL, NV, NV, NL, NV, NV,  /* 0x */
+  NV, NV, NV, NV, NV, NV, NV, NV, NV, SP, NL, NV, SP, NL, NV, NV,  /* 0x */
   NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV,  /* 1x */
   NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV,  /* 1x */
-  NV, NV, NV, NV, NV, 63, NV, NV, NV, NV, NV, 62, NV, NV, NV, NV,  /* 2x */
+  SP, NV, NV, NV, NV, 63, NV, NV, NV, NV, NV, 62, NV, NV, NV, NV,  /* 2x */
   52, 53, 54, 55, 56, 57, 58, 59, 60, 61, NV, NV, NV, PC, NV, NV,  /* 3x */
   NV,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,  /* 4x */
   15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, NV, NV, NV, NV, NV,  /* 5x */
   NV, 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, NV, NV, NV, NV, NV   /* 7x */
 }, decodemap_base64url[] = {
   52, 53, 54, 55, 56, 57, 58, 59, 60, 61, NV, NV, NV, PC, NV, NV,  /* 3x */
   NV,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,  /* 4x */
   15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, NV, NV, NV, NV, NV,  /* 5x */
   NV, 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, NV, NV, NV, NV, NV   /* 7x */
 }, decodemap_base64url[] = {
-  NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NL, NV, NV, NL, NV, NV,  /* 0x */
+  NV, NV, NV, NV, NV, NV, NV, NV, NV, SP, NL, NV, SP, NL, NV, NV,  /* 0x */
   NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV,  /* 1x */
   NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV,  /* 1x */
-  NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, 62, NV, NV,  /* 2x */
+  SP, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, 62, NV, NV,  /* 2x */
   52, 53, 54, 55, 56, 57, 58, 59, 60, 61, NV, NV, NV, PC, NV, NV,  /* 3x */
   NV,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,  /* 4x */
   15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, NV, NV, NV, NV, 63,  /* 5x */
   52, 53, 54, 55, 56, 57, 58, 59, 60, 61, NV, NV, NV, PC, NV, NV,  /* 3x */
   NV,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,  /* 4x */
   15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, NV, NV, NV, NV, 63,  /* 5x */
@@ -98,18 +100,18 @@ static const char
   encodemap_base32hex[] =   { "0123456789ABCDEFGHIJKLMNOPQRSTUV" };
 
 static const signed char decodemap_base32[] = {
   encodemap_base32hex[] =   { "0123456789ABCDEFGHIJKLMNOPQRSTUV" };
 
 static const signed char decodemap_base32[] = {
-  NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NL, NV, NV, NL, NV, NV,  /* 0x */
+  NV, NV, NV, NV, NV, NV, NV, NV, NV, SP, NL, NV, SP, NL, NV, NV,  /* 0x */
   NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV,  /* 1x */
   NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV,  /* 1x */
-  NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV,  /* 2x */
+  SP, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV,  /* 2x */
   NV, NV, 26, 27, 28, 29, 30, 31, NV, NV, NV, NV, NV, PC, NV, NV,  /* 3x */
   NV,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,  /* 4x */
   15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, NV, NV, NV, NV, NV,  /* 5x */
   NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV,  /* 6x */
   NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV,  /* 7x */
 }, decodemap_base32hex[] = {
   NV, NV, 26, 27, 28, 29, 30, 31, NV, NV, NV, NV, NV, PC, NV, NV,  /* 3x */
   NV,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,  /* 4x */
   15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, NV, NV, NV, NV, NV,  /* 5x */
   NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV,  /* 6x */
   NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV,  /* 7x */
 }, decodemap_base32hex[] = {
-  NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NL, NV, NV, NL, NV, NV,  /* 0x */
+  NV, NV, NV, NV, NV, NV, NV, NV, NV, SP, NL, NV, SP, NL, NV, NV,  /* 0x */
   NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV,  /* 1x */
   NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV,  /* 1x */
-  NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV,  /* 2x */
+  SP, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV,  /* 2x */
    0,  1,  2,  3,  4,  5,  6,  7,  8,  9, NV, NV, NV, PC, NV, NV,  /* 3x */
   NV, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,  /* 4x */
   25, 26, 27, 28, 29, 30, 31, NV, NV, NV, NV, NV, NV, NV, NV, NV,  /* 5x */
    0,  1,  2,  3,  4,  5,  6,  7,  8,  9, NV, NV, NV, PC, NV, NV,  /* 3x */
   NV, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,  /* 4x */
   25, 26, 27, 28, 29, 30, 31, NV, NV, NV, NV, NV, NV, NV, NV, NV,  /* 5x */
@@ -123,9 +125,9 @@ static const char
   encodemap_hex[] =   { "0123456789ABCDEF" };
 
 static const signed char decodemap_hex[] = {
   encodemap_hex[] =   { "0123456789ABCDEF" };
 
 static const signed char decodemap_hex[] = {
-  NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NL, NV, NV, NL, NV, NV,  /* 0x */
+  NV, NV, NV, NV, NV, NV, NV, NV, NV, SP, NL, NV, SP, NL, NV, NV,  /* 0x */
   NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV,  /* 1x */
   NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV,  /* 1x */
-  NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV,  /* 2x */
+  SP, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV,  /* 2x */
    0,  1,  2,  3,  4,  5,  6,  7,  8,  9, NV, NV, NV, NV, NV, NV,  /* 3x */
   NV, 10, 11, 12, 13, 14, 15, NV, NV, NV, NV, NV, NV, NV, NV, NV,  /* 4x */
   NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV,  /* 5x */
    0,  1,  2,  3,  4,  5,  6,  7,  8,  9, NV, NV, NV, NV, NV, NV,  /* 3x */
   NV, 10, 11, 12, 13, 14, 15, NV, NV, NV, NV, NV, NV, NV, NV, NV,  /* 4x */
   NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV, NV,  /* 5x */
@@ -278,7 +280,7 @@ enum {
 
 #define PUTWRAP(x) WRAP({                                              \
   char ch = encodemap[x];                                              \
 
 #define PUTWRAP(x) WRAP({                                              \
   char ch = encodemap[x];                                              \
-  if (f & CDCF_LOWERC) ch = tolower((unsigned char)ch);                        \
+  if (f & CDCF_LOWERC) ch = TOLOWER(ch);                               \
   DPUTC(d, ch);                                                                \
 })
 
   DPUTC(d, ch);                                                                \
 })
 
@@ -349,9 +351,9 @@ static int ctxn##_dodecode(ctxn##_ctx *ctx,                         \
        case 0:                                                         \
          break;                                                        \
        case CDCF_LOWERC:                                               \
        case 0:                                                         \
          break;                                                        \
        case CDCF_LOWERC:                                               \
-         if (isupper(ch)) goto badch;                                  \
+         if (ISUPPER(ch)) goto badch;                                  \
        default:                                                        \
        default:                                                        \
-         ch = toupper(ch);                                             \
+         ch = TOUPPER(ch);                                             \
       }                                                                        \
       x = decodemap[ch];                                               \
       switch (x) {                                                     \
       }                                                                        \
       x = decodemap[ch];                                               \
       switch (x) {                                                     \
@@ -362,8 +364,8 @@ static int ctxn##_dodecode(ctxn##_ctx *ctx,                         \
        case PC:                                                        \
          if (f & CDCF_IGNEQMID) break;                                 \
          if (f & CDCF_NOEQPAD) goto badch;                             \
        case PC:                                                        \
          if (f & CDCF_IGNEQMID) break;                                 \
          if (f & CDCF_NOEQPAD) goto badch;                             \
-         if (st == ST_MAIN &&                                          \
-             !(f & CDCF_IGNZPAD) && (a & ((1 << nb) - 1)))             \
+         if (st == ST_MAIN && !(f & CDCF_IGNZPAD) &&                   \
+             ((nb && !(nb%wd)) || (a & ((1 << nb) - 1))))              \
            return (CDCERR_INVZPAD);                                    \
          st = ST_PAD;                                                  \
          if (!(f & CDCF_IGNEQPAD)) {                                   \
            return (CDCERR_INVZPAD);                                    \
          st = ST_PAD;                                                  \
          if (!(f & CDCF_IGNEQPAD)) {                                   \
@@ -375,16 +377,18 @@ static int ctxn##_dodecode(ctxn##_ctx *ctx,                               \
        case NL:                                                        \
          if (f & CDCF_IGNNEWL) break;                                  \
          return (CDCERR_INVCH);                                        \
        case NL:                                                        \
          if (f & CDCF_IGNNEWL) break;                                  \
          return (CDCERR_INVCH);                                        \
+       case SP:                                                        \
+         if (f & CDCF_IGNSPC) break;                                   \
+         return (CDCERR_INVCH);                                        \
        default:                                                        \
        default:                                                        \
-         if (st != ST_MAIN)                                            \
-           return (CDCERR_INVEQPAD);                                   \
+         if (st != ST_MAIN) return (CDCERR_INVEQPAD);                  \
          BASECONV(x, wd, 8, PUTRAW);                                   \
          break;                                                        \
       }                                                                        \
     }                                                                  \
   } else {                                                             \
          BASECONV(x, wd, 8, PUTRAW);                                   \
          break;                                                        \
       }                                                                        \
     }                                                                  \
   } else {                                                             \
-    if (st == ST_MAIN &&                                               \
-       !(f & CDCF_IGNZPAD) && (a & ((1 << nb) - 1)))                   \
+    if (st == ST_MAIN && !(f & CDCF_IGNZPAD) &&                                \
+       ((nb && !(nb%wd)) || (a & ((1 << nb) - 1))))                    \
       return (CDCERR_INVZPAD);                                         \
     if (!(f & (CDCF_IGNEQPAD | CDCF_IGNEQMID | CDCF_NOEQPAD)) && nb)   \
       return (CDCERR_INVEQPAD);                                                \
       return (CDCERR_INVZPAD);                                         \
     if (!(f & (CDCF_IGNEQPAD | CDCF_IGNEQMID | CDCF_NOEQPAD)) && nb)   \
       return (CDCERR_INVEQPAD);                                                \
@@ -415,7 +419,7 @@ static int ctxn##_dec(codec *c, const void *p, size_t sz, dstr *d)  \
 static void ctxn##_destroy(codec *c)                                   \
 {                                                                      \
   ctxn##_codec *bc = (ctxn##_codec *)c;                                        \
 static void ctxn##_destroy(codec *c)                                   \
 {                                                                      \
   ctxn##_codec *bc = (ctxn##_codec *)c;                                        \
-  if (bc->ctx.indent) xfree((/*unconst*/ char *)bc->ctx.indent);       \
+  if (bc->ctx.indent) xfree(UNCONST(char, bc->ctx.indent));            \
   DESTROY(bc);                                                         \
 }                                                                      \
                                                                        \
   DESTROY(bc);                                                         \
 }                                                                      \
                                                                        \