Home | History | Annotate | Line # | Download | only in generic
      1 /*
      2  * base64.h -- Fast Base64 stream decoder
      3  *
      4  * Copyright (c) 2005-2007, Nick Galbreath.
      5  * Copyright (c) 2015-2018, Wojciech Mua.
      6  * Copyright (c) 2016-2017, Matthieu Darbois.
      7  * Copyright (c) 2013-2022, Alfred Klomp.
      8  * Copyright (c) 2022, NLnet Labs. All rights reserved.
      9  *
     10  * SPDX-License-Identifier: BSD-2-Clause
     11  *
     12  */
     13 #ifndef BASE64_H
     14 #define BASE64_H
     15 
     16 // Modified version of https://github.com/aklomp/base64
     17 
     18 struct base64_state {
     19 	int eof;
     20 	int bytes;
     21 	unsigned char carry;
     22 };
     23 
     24 #include <stdint.h>
     25 #define CHAR62 '+'
     26 #define CHAR63 '/'
     27 #define CHARPAD '='
     28 
     29 // End-of-file definitions.
     30 // Almost end-of-file when waiting for the last '=' character:
     31 #define BASE64_AEOF 1
     32 // End-of-file when stream end has been reached or invalid input provided:
     33 #define BASE64_EOF 2
     34 
     35 // In the lookup table below, note that the value for '=' (character 61) is
     36 // 254, not 255. This character is used for in-band signaling of the end of
     37 // the datastream, and we will use that later. The characters A-Z, a-z, 0-9
     38 // and + / are mapped to their "decoded" values. The other bytes all map to
     39 // the value 255, which flags them as "invalid input".
     40 
     41 static const uint8_t
     42 base64_table_dec_8bit[] =
     43 {
     44   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,		//   0..15
     45   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,		//  16..31
     46   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,  62, 255, 255, 255,  63,		//  32..47
     47    52,  53,  54,  55,  56,  57,  58,  59,  60,  61, 255, 255, 255, 254, 255, 255,		//  48..63
     48   255,   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,		//  64..79
     49    15,  16,  17,  18,  19,  20,  21,  22,  23,  24,  25, 255, 255, 255, 255, 255,		//  80..95
     50   255,  26,  27,  28,  29,  30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,		//  96..111
     51    41,  42,  43,  44,  45,  46,  47,  48,  49,  50,  51, 255, 255, 255, 255, 255,		// 112..127
     52   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,		// 128..143
     53   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     54   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     55   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     56   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     57   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     58   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     59   255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
     60 };
     61 
     62 
     63 #if BYTE_ORDER == LITTLE_ENDIAN
     64 
     65 /* SPECIAL DECODE TABLES FOR LITTLE ENDIAN (INTEL) CPUS */
     66 
     67 static const uint32_t base64_table_dec_32bit_d0[256] = {
     68 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
     69 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
     70 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
     71 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
     72 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
     73 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
     74 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
     75 0xffffffff, 0x000000f8, 0xffffffff, 0xffffffff, 0xffffffff, 0x000000fc,
     76 0x000000d0, 0x000000d4, 0x000000d8, 0x000000dc, 0x000000e0, 0x000000e4,
     77 0x000000e8, 0x000000ec, 0x000000f0, 0x000000f4, 0xffffffff, 0xffffffff,
     78 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000,
     79 0x00000004, 0x00000008, 0x0000000c, 0x00000010, 0x00000014, 0x00000018,
     80 0x0000001c, 0x00000020, 0x00000024, 0x00000028, 0x0000002c, 0x00000030,
     81 0x00000034, 0x00000038, 0x0000003c, 0x00000040, 0x00000044, 0x00000048,
     82 0x0000004c, 0x00000050, 0x00000054, 0x00000058, 0x0000005c, 0x00000060,
     83 0x00000064, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
     84 0xffffffff, 0x00000068, 0x0000006c, 0x00000070, 0x00000074, 0x00000078,
     85 0x0000007c, 0x00000080, 0x00000084, 0x00000088, 0x0000008c, 0x00000090,
     86 0x00000094, 0x00000098, 0x0000009c, 0x000000a0, 0x000000a4, 0x000000a8,
     87 0x000000ac, 0x000000b0, 0x000000b4, 0x000000b8, 0x000000bc, 0x000000c0,
     88 0x000000c4, 0x000000c8, 0x000000cc, 0xffffffff, 0xffffffff, 0xffffffff,
     89 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
     90 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
     91 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
     92 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
     93 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
     94 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
     95 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
     96 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
     97 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
     98 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
     99 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    100 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    101 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    102 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    103 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    104 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    105 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    106 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    107 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    108 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    109 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    110 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
    111 };
    112 
    113 
    114 static const uint32_t base64_table_dec_32bit_d1[256] = {
    115 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    116 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    117 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    118 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    119 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    120 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    121 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    122 0xffffffff, 0x0000e003, 0xffffffff, 0xffffffff, 0xffffffff, 0x0000f003,
    123 0x00004003, 0x00005003, 0x00006003, 0x00007003, 0x00008003, 0x00009003,
    124 0x0000a003, 0x0000b003, 0x0000c003, 0x0000d003, 0xffffffff, 0xffffffff,
    125 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000,
    126 0x00001000, 0x00002000, 0x00003000, 0x00004000, 0x00005000, 0x00006000,
    127 0x00007000, 0x00008000, 0x00009000, 0x0000a000, 0x0000b000, 0x0000c000,
    128 0x0000d000, 0x0000e000, 0x0000f000, 0x00000001, 0x00001001, 0x00002001,
    129 0x00003001, 0x00004001, 0x00005001, 0x00006001, 0x00007001, 0x00008001,
    130 0x00009001, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    131 0xffffffff, 0x0000a001, 0x0000b001, 0x0000c001, 0x0000d001, 0x0000e001,
    132 0x0000f001, 0x00000002, 0x00001002, 0x00002002, 0x00003002, 0x00004002,
    133 0x00005002, 0x00006002, 0x00007002, 0x00008002, 0x00009002, 0x0000a002,
    134 0x0000b002, 0x0000c002, 0x0000d002, 0x0000e002, 0x0000f002, 0x00000003,
    135 0x00001003, 0x00002003, 0x00003003, 0xffffffff, 0xffffffff, 0xffffffff,
    136 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    137 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    138 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    139 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    140 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    141 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    142 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    143 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    144 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    145 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    146 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    147 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    148 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    149 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    150 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    151 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    152 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    153 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    154 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    155 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    156 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    157 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
    158 };
    159 
    160 
    161 static const uint32_t base64_table_dec_32bit_d2[256] = {
    162 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    163 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    164 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    165 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    166 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    167 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    168 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    169 0xffffffff, 0x00800f00, 0xffffffff, 0xffffffff, 0xffffffff, 0x00c00f00,
    170 0x00000d00, 0x00400d00, 0x00800d00, 0x00c00d00, 0x00000e00, 0x00400e00,
    171 0x00800e00, 0x00c00e00, 0x00000f00, 0x00400f00, 0xffffffff, 0xffffffff,
    172 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000,
    173 0x00400000, 0x00800000, 0x00c00000, 0x00000100, 0x00400100, 0x00800100,
    174 0x00c00100, 0x00000200, 0x00400200, 0x00800200, 0x00c00200, 0x00000300,
    175 0x00400300, 0x00800300, 0x00c00300, 0x00000400, 0x00400400, 0x00800400,
    176 0x00c00400, 0x00000500, 0x00400500, 0x00800500, 0x00c00500, 0x00000600,
    177 0x00400600, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    178 0xffffffff, 0x00800600, 0x00c00600, 0x00000700, 0x00400700, 0x00800700,
    179 0x00c00700, 0x00000800, 0x00400800, 0x00800800, 0x00c00800, 0x00000900,
    180 0x00400900, 0x00800900, 0x00c00900, 0x00000a00, 0x00400a00, 0x00800a00,
    181 0x00c00a00, 0x00000b00, 0x00400b00, 0x00800b00, 0x00c00b00, 0x00000c00,
    182 0x00400c00, 0x00800c00, 0x00c00c00, 0xffffffff, 0xffffffff, 0xffffffff,
    183 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    184 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    185 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    186 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    187 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    188 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    189 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    190 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    191 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    192 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    193 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    194 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    195 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    196 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    197 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    198 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    199 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    200 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    201 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    202 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    203 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    204 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
    205 };
    206 
    207 
    208 static const uint32_t base64_table_dec_32bit_d3[256] = {
    209 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    210 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    211 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    212 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    213 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    214 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    215 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    216 0xffffffff, 0x003e0000, 0xffffffff, 0xffffffff, 0xffffffff, 0x003f0000,
    217 0x00340000, 0x00350000, 0x00360000, 0x00370000, 0x00380000, 0x00390000,
    218 0x003a0000, 0x003b0000, 0x003c0000, 0x003d0000, 0xffffffff, 0xffffffff,
    219 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000,
    220 0x00010000, 0x00020000, 0x00030000, 0x00040000, 0x00050000, 0x00060000,
    221 0x00070000, 0x00080000, 0x00090000, 0x000a0000, 0x000b0000, 0x000c0000,
    222 0x000d0000, 0x000e0000, 0x000f0000, 0x00100000, 0x00110000, 0x00120000,
    223 0x00130000, 0x00140000, 0x00150000, 0x00160000, 0x00170000, 0x00180000,
    224 0x00190000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    225 0xffffffff, 0x001a0000, 0x001b0000, 0x001c0000, 0x001d0000, 0x001e0000,
    226 0x001f0000, 0x00200000, 0x00210000, 0x00220000, 0x00230000, 0x00240000,
    227 0x00250000, 0x00260000, 0x00270000, 0x00280000, 0x00290000, 0x002a0000,
    228 0x002b0000, 0x002c0000, 0x002d0000, 0x002e0000, 0x002f0000, 0x00300000,
    229 0x00310000, 0x00320000, 0x00330000, 0xffffffff, 0xffffffff, 0xffffffff,
    230 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    231 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    232 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    233 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    234 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    235 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    236 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    237 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    238 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    239 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    240 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    241 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    242 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    243 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    244 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    245 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    246 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    247 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    248 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    249 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    250 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    251 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
    252 };
    253 
    254 #elif BYTE_ORDER == BIG_ENDIAN
    255 
    256 /* SPECIAL DECODE TABLES FOR BIG ENDIAN (IBM/MOTOROLA/SUN) CPUS */
    257 
    258 const uint32_t base64_table_dec_32bit_d0[256] = {
    259 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    260 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    261 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    262 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    263 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    264 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    265 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    266 0xffffffff, 0xf8000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xfc000000,
    267 0xd0000000, 0xd4000000, 0xd8000000, 0xdc000000, 0xe0000000, 0xe4000000,
    268 0xe8000000, 0xec000000, 0xf0000000, 0xf4000000, 0xffffffff, 0xffffffff,
    269 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000,
    270 0x04000000, 0x08000000, 0x0c000000, 0x10000000, 0x14000000, 0x18000000,
    271 0x1c000000, 0x20000000, 0x24000000, 0x28000000, 0x2c000000, 0x30000000,
    272 0x34000000, 0x38000000, 0x3c000000, 0x40000000, 0x44000000, 0x48000000,
    273 0x4c000000, 0x50000000, 0x54000000, 0x58000000, 0x5c000000, 0x60000000,
    274 0x64000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    275 0xffffffff, 0x68000000, 0x6c000000, 0x70000000, 0x74000000, 0x78000000,
    276 0x7c000000, 0x80000000, 0x84000000, 0x88000000, 0x8c000000, 0x90000000,
    277 0x94000000, 0x98000000, 0x9c000000, 0xa0000000, 0xa4000000, 0xa8000000,
    278 0xac000000, 0xb0000000, 0xb4000000, 0xb8000000, 0xbc000000, 0xc0000000,
    279 0xc4000000, 0xc8000000, 0xcc000000, 0xffffffff, 0xffffffff, 0xffffffff,
    280 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    281 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    282 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    283 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    284 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    285 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    286 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    287 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    288 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    289 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    290 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    291 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    292 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    293 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    294 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    295 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    296 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    297 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    298 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    299 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    300 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    301 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
    302 };
    303 
    304 const uint32_t base64_table_dec_32bit_d1[256] = {
    305 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    306 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    307 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    308 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    309 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    310 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    311 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    312 0xffffffff, 0x03e00000, 0xffffffff, 0xffffffff, 0xffffffff, 0x03f00000,
    313 0x03400000, 0x03500000, 0x03600000, 0x03700000, 0x03800000, 0x03900000,
    314 0x03a00000, 0x03b00000, 0x03c00000, 0x03d00000, 0xffffffff, 0xffffffff,
    315 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000,
    316 0x00100000, 0x00200000, 0x00300000, 0x00400000, 0x00500000, 0x00600000,
    317 0x00700000, 0x00800000, 0x00900000, 0x00a00000, 0x00b00000, 0x00c00000,
    318 0x00d00000, 0x00e00000, 0x00f00000, 0x01000000, 0x01100000, 0x01200000,
    319 0x01300000, 0x01400000, 0x01500000, 0x01600000, 0x01700000, 0x01800000,
    320 0x01900000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    321 0xffffffff, 0x01a00000, 0x01b00000, 0x01c00000, 0x01d00000, 0x01e00000,
    322 0x01f00000, 0x02000000, 0x02100000, 0x02200000, 0x02300000, 0x02400000,
    323 0x02500000, 0x02600000, 0x02700000, 0x02800000, 0x02900000, 0x02a00000,
    324 0x02b00000, 0x02c00000, 0x02d00000, 0x02e00000, 0x02f00000, 0x03000000,
    325 0x03100000, 0x03200000, 0x03300000, 0xffffffff, 0xffffffff, 0xffffffff,
    326 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    327 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    328 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    329 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    330 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    331 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    332 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    333 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    334 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    335 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    336 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    337 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    338 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    339 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    340 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    341 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    342 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    343 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    344 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    345 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    346 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    347 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
    348 };
    349 
    350 const uint32_t base64_table_dec_32bit_d2[256] = {
    351 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    352 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    353 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    354 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    355 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    356 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    357 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    358 0xffffffff, 0x000f8000, 0xffffffff, 0xffffffff, 0xffffffff, 0x000fc000,
    359 0x000d0000, 0x000d4000, 0x000d8000, 0x000dc000, 0x000e0000, 0x000e4000,
    360 0x000e8000, 0x000ec000, 0x000f0000, 0x000f4000, 0xffffffff, 0xffffffff,
    361 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000,
    362 0x00004000, 0x00008000, 0x0000c000, 0x00010000, 0x00014000, 0x00018000,
    363 0x0001c000, 0x00020000, 0x00024000, 0x00028000, 0x0002c000, 0x00030000,
    364 0x00034000, 0x00038000, 0x0003c000, 0x00040000, 0x00044000, 0x00048000,
    365 0x0004c000, 0x00050000, 0x00054000, 0x00058000, 0x0005c000, 0x00060000,
    366 0x00064000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    367 0xffffffff, 0x00068000, 0x0006c000, 0x00070000, 0x00074000, 0x00078000,
    368 0x0007c000, 0x00080000, 0x00084000, 0x00088000, 0x0008c000, 0x00090000,
    369 0x00094000, 0x00098000, 0x0009c000, 0x000a0000, 0x000a4000, 0x000a8000,
    370 0x000ac000, 0x000b0000, 0x000b4000, 0x000b8000, 0x000bc000, 0x000c0000,
    371 0x000c4000, 0x000c8000, 0x000cc000, 0xffffffff, 0xffffffff, 0xffffffff,
    372 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    373 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    374 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    375 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    376 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    377 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    378 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    379 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    380 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    381 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    382 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    383 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    384 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    385 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    386 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    387 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    388 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    389 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    390 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    391 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    392 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    393 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
    394 };
    395 
    396 
    397 const uint32_t base64_table_dec_32bit_d3[256] = {
    398 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    399 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    400 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    401 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    402 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    403 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    404 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    405 0xffffffff, 0x00003e00, 0xffffffff, 0xffffffff, 0xffffffff, 0x00003f00,
    406 0x00003400, 0x00003500, 0x00003600, 0x00003700, 0x00003800, 0x00003900,
    407 0x00003a00, 0x00003b00, 0x00003c00, 0x00003d00, 0xffffffff, 0xffffffff,
    408 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000,
    409 0x00000100, 0x00000200, 0x00000300, 0x00000400, 0x00000500, 0x00000600,
    410 0x00000700, 0x00000800, 0x00000900, 0x00000a00, 0x00000b00, 0x00000c00,
    411 0x00000d00, 0x00000e00, 0x00000f00, 0x00001000, 0x00001100, 0x00001200,
    412 0x00001300, 0x00001400, 0x00001500, 0x00001600, 0x00001700, 0x00001800,
    413 0x00001900, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    414 0xffffffff, 0x00001a00, 0x00001b00, 0x00001c00, 0x00001d00, 0x00001e00,
    415 0x00001f00, 0x00002000, 0x00002100, 0x00002200, 0x00002300, 0x00002400,
    416 0x00002500, 0x00002600, 0x00002700, 0x00002800, 0x00002900, 0x00002a00,
    417 0x00002b00, 0x00002c00, 0x00002d00, 0x00002e00, 0x00002f00, 0x00003000,
    418 0x00003100, 0x00003200, 0x00003300, 0xffffffff, 0xffffffff, 0xffffffff,
    419 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    420 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    421 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    422 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    423 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    424 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    425 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    426 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    427 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    428 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    429 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    430 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    431 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    432 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    433 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    434 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    435 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    436 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    437 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    438 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    439 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
    440 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff
    441 };
    442 
    443 #else
    444 
    445 # error "byte order unknown"
    446 
    447 #endif // LITTLE_ENDIAN
    448 
    449 static really_inline int
    450 dec_loop_generic_32_inner (const uint8_t **s, uint8_t **o, size_t *rounds)
    451 {
    452 	const uint32_t str
    453 		= base64_table_dec_32bit_d0[(*s)[0]]
    454 		| base64_table_dec_32bit_d1[(*s)[1]]
    455 		| base64_table_dec_32bit_d2[(*s)[2]]
    456 		| base64_table_dec_32bit_d3[(*s)[3]];
    457 
    458 #if BYTE_ORDER == LITTLE_ENDIAN
    459 
    460 	// LUTs for little-endian set MSB in case of invalid character:
    461 	if (str & UINT32_C(0x80000000)) {
    462 		return 0;
    463 	}
    464 #else
    465 	// LUTs for big-endian set LSB in case of invalid character:
    466 	if (str & UINT32_C(1)) {
    467 		return 0;
    468 	}
    469 #endif
    470 	// Store the output:
    471 	memcpy(*o, &str, sizeof (str));
    472 
    473 	*s += 4;
    474 	*o += 3;
    475 	*rounds -= 1;
    476 
    477 	return 1;
    478 }
    479 
    480 static really_inline void
    481 dec_loop_generic_32 (const uint8_t **s, size_t *slen, uint8_t **o, size_t *olen)
    482 {
    483 	if (*slen < 8) {
    484 		return;
    485 	}
    486 
    487 	// Process blocks of 4 bytes per round. Because one extra zero byte is
    488 	// written after the output, ensure that there will be at least 4 bytes
    489 	// of input data left to cover the gap. (Two data bytes and up to two
    490 	// end-of-string markers.)
    491 	size_t rounds = (*slen - 4) / 4;
    492 
    493 	*slen -= rounds * 4;	// 4 bytes consumed per round
    494 	*olen += rounds * 3;	// 3 bytes produced per round
    495 
    496 	do {
    497 		if (rounds >= 8) {
    498 			if (dec_loop_generic_32_inner(s, o, &rounds) &&
    499 			    dec_loop_generic_32_inner(s, o, &rounds) &&
    500 			    dec_loop_generic_32_inner(s, o, &rounds) &&
    501 			    dec_loop_generic_32_inner(s, o, &rounds) &&
    502 			    dec_loop_generic_32_inner(s, o, &rounds) &&
    503 			    dec_loop_generic_32_inner(s, o, &rounds) &&
    504 			    dec_loop_generic_32_inner(s, o, &rounds) &&
    505 			    dec_loop_generic_32_inner(s, o, &rounds)) {
    506 				continue;
    507 			}
    508 			break;
    509 		}
    510 		if (rounds >= 4) {
    511 			if (dec_loop_generic_32_inner(s, o, &rounds) &&
    512 			    dec_loop_generic_32_inner(s, o, &rounds) &&
    513 			    dec_loop_generic_32_inner(s, o, &rounds) &&
    514 			    dec_loop_generic_32_inner(s, o, &rounds)) {
    515 				continue;
    516 			}
    517 			break;
    518 		}
    519 		if (rounds >= 2) {
    520 			if (dec_loop_generic_32_inner(s, o, &rounds) &&
    521 			    dec_loop_generic_32_inner(s, o, &rounds)) {
    522 				continue;
    523 			}
    524 			break;
    525 		}
    526 		dec_loop_generic_32_inner(s, o, &rounds);
    527 		break;
    528 
    529 	} while (rounds > 0);
    530 
    531 	// Adjust for any rounds that were skipped:
    532 	*slen += rounds * 4;
    533 	*olen -= rounds * 3;
    534 }
    535 
    536 nonnull((1,2,4,5))
    537 static really_inline int base64_stream_decode(
    538   struct base64_state *state,
    539   const char *src,
    540   size_t srclen,
    541   uint8_t *out,
    542   size_t *outlen)
    543 {
    544   int ret = 0;
    545   const uint8_t *s = (const uint8_t *) src;
    546   uint8_t *o = (uint8_t *) out;
    547   uint8_t q;
    548 
    549   // Use local temporaries to avoid cache thrashing:
    550   size_t olen = 0;
    551   size_t slen = srclen;
    552   struct base64_state st;
    553   st.eof = state->eof;
    554   st.bytes = state->bytes;
    555   st.carry = state->carry;
    556 
    557   // If we previously saw an EOF or an invalid character, bail out:
    558   if (st.eof) {
    559     *outlen = 0;
    560     ret = 0;
    561     // If there was a trailing '=' to check, check it:
    562     if (slen && (st.eof == BASE64_AEOF)) {
    563       state->bytes = 0;
    564       state->eof = BASE64_EOF;
    565       ret = ((base64_table_dec_8bit[*s++] == 254) && (slen == 1)) ? 1 : 0;
    566     }
    567     return ret;
    568   }
    569 
    570   // Turn four 6-bit numbers into three bytes:
    571   // out[0] = 11111122
    572   // out[1] = 22223333
    573   // out[2] = 33444444
    574 
    575   // Duff's device again:
    576   switch (st.bytes)
    577   {
    578 #if defined(__SUNPRO_C)
    579 #pragma error_messages(off, E_STATEMENT_NOT_REACHED)
    580 #endif
    581     for (;;)
    582 #if defined(__SUNPRO_C)
    583 #pragma error_messages(default, E_STATEMENT_NOT_REACHED)
    584 #endif
    585     {
    586     case 0:
    587       dec_loop_generic_32(&s, &slen, &o, &olen);
    588       if (slen-- == 0) {
    589         ret = 1;
    590         break;
    591       }
    592       if ((q = base64_table_dec_8bit[*s++]) >= 254) {
    593         st.eof = BASE64_EOF;
    594         // Treat character '=' as invalid for byte 0:
    595         break;
    596       }
    597       st.carry = (uint8_t)(q << 2);
    598       st.bytes++;
    599 
    600       // fallthrough
    601 
    602     case 1:
    603       if (slen-- == 0) {
    604         ret = 1;
    605         break;
    606       }
    607       if ((q = base64_table_dec_8bit[*s++]) >= 254) {
    608         st.eof = BASE64_EOF;
    609         // Treat character '=' as invalid for byte 1:
    610         break;
    611       }
    612       *o++ = st.carry | (q >> 4);
    613       st.carry = (uint8_t)(q << 4);
    614       st.bytes++;
    615       olen++;
    616 
    617   		// fallthrough
    618 
    619     case 2:
    620       if (slen-- == 0) {
    621         ret = 1;
    622         break;
    623       }
    624       if ((q = base64_table_dec_8bit[*s++]) >= 254) {
    625         st.bytes++;
    626         // When q == 254, the input char is '='.
    627         // Check if next byte is also '=':
    628         if (q == 254) {
    629           if (slen-- != 0) {
    630             st.bytes = 0;
    631             // EOF:
    632             st.eof = BASE64_EOF;
    633             q = base64_table_dec_8bit[*s++];
    634             ret = ((q == 254) && (slen == 0)) ? 1 : 0;
    635             break;
    636           }
    637           else {
    638             // Almost EOF
    639             st.eof = BASE64_AEOF;
    640             ret = 1;
    641             break;
    642           }
    643         }
    644         // If we get here, there was an error:
    645         break;
    646       }
    647       *o++ = st.carry | (q >> 2);
    648       st.carry = (uint8_t)(q << 6);
    649       st.bytes++;
    650       olen++;
    651 
    652       // fallthrough
    653 
    654     case 3:
    655       if (slen-- == 0) {
    656         ret = 1;
    657         break;
    658       }
    659       if ((q = base64_table_dec_8bit[*s++]) >= 254) {
    660         st.bytes = 0;
    661         st.eof = BASE64_EOF;
    662         // When q == 254, the input char is '='. Return 1 and EOF.
    663         // When q == 255, the input char is invalid. Return 0 and EOF.
    664         ret = ((q == 254) && (slen == 0)) ? 1 : 0;
    665         break;
    666       }
    667       *o++ = st.carry | q;
    668       st.carry = 0;
    669       st.bytes = 0;
    670       olen++;
    671     }
    672   }
    673 
    674   state->eof = st.eof;
    675   state->bytes = st.bytes;
    676   state->carry = st.carry;
    677   *outlen = olen;
    678   return ret;
    679 }
    680 
    681 nonnull((1,3,4))
    682 static really_inline int base64_decode(
    683   const char *src,
    684   size_t srclen,
    685   uint8_t *out,
    686   size_t *outlen)
    687 {
    688   struct base64_state state = { .eof = 0, .bytes = 0, .carry = 0 };
    689   return base64_stream_decode(&state, src, srclen, out, outlen) & !state.bytes;
    690 }
    691 
    692 nonnull_all
    693 static really_inline int32_t parse_base64_sequence(
    694   parser_t *parser,
    695   const type_info_t *type,
    696   const rdata_info_t *item,
    697   rdata_t *rdata,
    698   token_t *token)
    699 {
    700   if (is_contiguous(token)) {
    701     struct base64_state state = { .eof = 0, .bytes = 0, .carry = 0 };
    702 
    703     do {
    704       size_t length = token->length / 4;
    705       if (((uintptr_t)rdata->limit - (uintptr_t)rdata->octets) / 3 < length)
    706         SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(item), NAME(type));
    707       if (!base64_stream_decode(&state, token->data, token->length, rdata->octets, &length))
    708         SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(item), NAME(type));
    709       rdata->octets += length;
    710       take(parser, token);
    711     } while (is_contiguous(token));
    712 
    713     // incomplete base64 sequence
    714     if (state.bytes)
    715       SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(item), NAME(type));
    716   }
    717 
    718   return have_delimiter(parser, type, token);
    719 }
    720 
    721 nonnull_all
    722 static really_inline int32_t parse_base64(
    723   parser_t *parser,
    724   const type_info_t *type,
    725   const rdata_info_t *item,
    726   rdata_t *rdata,
    727   const token_t *token)
    728 {
    729   size_t length = token->length / 4;
    730   if (((uintptr_t)rdata->limit - (uintptr_t)rdata->octets) / 3 < length)
    731     SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(item), NAME(type));
    732   if (!base64_decode(token->data, token->length, rdata->octets, &length))
    733     SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(item), NAME(type));
    734   rdata->octets += length;
    735   return 0;
    736 }
    737 
    738 #endif // BASE64_H
    739