1d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */ 2d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott/* vi: set expandtab shiftwidth=4 tabstop=4: */ 3d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott/** 4d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * \file 5d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * <PRE> 6d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * MODP_B64 - High performance base64 encoder/decoder 7d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * Version 1.3 -- 17-Mar-2006 8d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * http://modp.com/release/base64 9d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * 10d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * Copyright © 2005, 2006 Nick Galbreath -- nickg [at] modp [dot] com 11d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * All rights reserved. 12d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * 13d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * Redistribution and use in source and binary forms, with or without 14d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * modification, are permitted provided that the following conditions are 15d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * met: 16d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * 17d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * Redistributions of source code must retain the above copyright 18d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * notice, this list of conditions and the following disclaimer. 19d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * 20d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * Redistributions in binary form must reproduce the above copyright 21d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * notice, this list of conditions and the following disclaimer in the 22d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * documentation and/or other materials provided with the distribution. 23d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * 24d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * Neither the name of the modp.com nor the names of its 25d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * contributors may be used to endorse or promote products derived from 26d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * this software without specific prior written permission. 27d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * 28d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * 40d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * This is the standard "new" BSD license: 41d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * http://www.opensource.org/licenses/bsd-license.php 42d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * </PRE> 43d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott */ 44d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 45d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott/* public header */ 46d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott#include "modp_b64.h" 47d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 48d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott/* 49d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * If you are ripping this out of the library, comment out the next 50d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * line and uncomment the next lines as approrpiate 51d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott */ 52d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott//#include "config.h" 53d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 54d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott/* if on motoral, sun, ibm; uncomment this */ 55d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott/* #define WORDS_BIGENDIAN 1 */ 56d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott/* else for Intel, Amd; uncomment this */ 57d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott/* #undef WORDS_BIGENDIAN */ 58d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 59d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott#include "modp_b64_data.h" 60d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 61d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott#define BADCHAR 0x01FFFFFF 62d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 63d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott/** 64d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * you can control if we use padding by commenting out this 65d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * next line. However, I highly recommend you use padding and not 66d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * using it should only be for compatability with a 3rd party. 67d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * Also, 'no padding' is not tested! 68d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott */ 69d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott#define DOPAD 1 70d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 71d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott/* 72d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * if we aren't doing padding 73d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * set the pad character to NULL 74d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott */ 75d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott#ifndef DOPAD 76d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott#undef CHARPAD 77d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott#define CHARPAD '\0' 78d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott#endif 79d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 80d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scottint modp_b64_encode(char* dest, const char* str, int len) 81d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott{ 82d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott int i; 83d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott uint8_t* p = (uint8_t*) dest; 84d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 85d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott /* unsigned here is important! */ 86d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott uint8_t t1, t2, t3; 87d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 88d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott for (i = 0; i < len - 2; i += 3) { 89d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott t1 = str[i]; t2 = str[i+1]; t3 = str[i+2]; 90d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott *p++ = e0[t1]; 91d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott *p++ = e1[((t1 & 0x03) << 4) | ((t2 >> 4) & 0x0F)]; 92d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott *p++ = e1[((t2 & 0x0F) << 2) | ((t3 >> 6) & 0x03)]; 93d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott *p++ = e2[t3]; 94d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott } 95d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 96d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott switch (len - i) { 97d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott case 0: 98d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott break; 99d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott case 1: 100d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott t1 = str[i]; 101d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott *p++ = e0[t1]; 102d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott *p++ = e1[(t1 & 0x03) << 4]; 103d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott *p++ = CHARPAD; 104d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott *p++ = CHARPAD; 105d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott break; 106d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott default: /* case 2 */ 107d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott t1 = str[i]; t2 = str[i+1]; 108d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott *p++ = e0[t1]; 109d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott *p++ = e1[((t1 & 0x03) << 4) | ((t2 >> 4) & 0x0F)]; 110d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott *p++ = e2[(t2 & 0x0F) << 2]; 111d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott *p++ = CHARPAD; 112d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott } 113d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 114d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott *p = '\0'; 115d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott return p - (uint8_t*)dest; 116d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott} 117d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 118d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott#ifdef WORDS_BIGENDIAN /* BIG ENDIAN -- SUN / IBM / MOTOROLA */ 119d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scottint modp_b64_decode(char* dest, const char* src, int len) 120d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott{ 121d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott if (len == 0) return 0; 122d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 123d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott#ifdef DOPAD 124d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott /* if padding is used, then the message must be at least 125d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 4 chars and be a multiple of 4. 126d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott there can be at most 2 pad chars at the end */ 127d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott if (len < 4 || (len % 4 != 0)) return -1; 128d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott if (src[len-1] == CHARPAD) { 129d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott len--; 130d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott if (src[len -1] == CHARPAD) { 131d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott len--; 132d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott } 133d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott } 134d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott#endif /* DOPAD */ 135d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 136d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott int i; 137d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott int leftover = len % 4; 138d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott int chunks = (leftover == 0) ? len / 4 - 1 : len /4; 139d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 140d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott uint8_t* p = (uint8_t*) dest; 141d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott uint32_t x = 0; 142d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott uint32_t* destInt = (uint32_t*) p; 143d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott uint32_t* srcInt = (uint32_t*) src; 144d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott uint32_t y = *srcInt++; 145d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott for (i = 0; i < chunks; ++i) { 146d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott x = d0[y >> 24 & 0xff] | d1[y >> 16 & 0xff] | 147d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott d2[y >> 8 & 0xff] | d3[y & 0xff]; 148d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 149d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott if (x >= BADCHAR) return -1; 150d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott *destInt = x << 8; 151d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott p += 3; 152d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott destInt = (uint32_t*)p; 153d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott y = *srcInt++; 154d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott } 155d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 156d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott switch (leftover) { 157d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott case 0: 158d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott x = d0[y >> 24 & 0xff] | d1[y >> 16 & 0xff] | 159d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott d2[y >> 8 & 0xff] | d3[y & 0xff]; 160d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott if (x >= BADCHAR) return -1; 161d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott *p++ = ((uint8_t*)&x)[1]; 162d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott *p++ = ((uint8_t*)&x)[2]; 163d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott *p = ((uint8_t*)&x)[3]; 164d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott return (chunks+1)*3; 165d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott case 1: 166d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott x = d3[y >> 24]; 167d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott *p = (uint8_t)x; 168d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott break; 169d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott case 2: 170d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott x = d3[y >> 24] *64 + d3[(y >> 16) & 0xff]; 171d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott *p = (uint8_t)(x >> 4); 172d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott break; 173d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott default: /* case 3 */ 174d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott x = (d3[y >> 24] *64 + d3[(y >> 16) & 0xff])*64 + 175d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott d3[(y >> 8) & 0xff]; 176d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott *p++ = (uint8_t) (x >> 10); 177d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott *p = (uint8_t) (x >> 2); 178d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott break; 179d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott } 180d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 181d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott if (x >= BADCHAR) return -1; 182d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott return 3*chunks + (6*leftover)/8; 183d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott} 184d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 185d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott#else /* LITTLE ENDIAN -- INTEL AND FRIENDS */ 186d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 187d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scottint modp_b64_decode(char* dest, const char* src, int len) 188d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott{ 189d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott if (len == 0) return 0; 190d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 191d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott#ifdef DOPAD 192d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott /* 193d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * if padding is used, then the message must be at least 194d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott * 4 chars and be a multiple of 4 195d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott */ 196d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott if (len < 4 || (len % 4 != 0)) return -1; /* error */ 197d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott /* there can be at most 2 pad chars at the end */ 198d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott if (src[len-1] == CHARPAD) { 199d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott len--; 200d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott if (src[len -1] == CHARPAD) { 201d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott len--; 202d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott } 203d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott } 204d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott#endif 205d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 206d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott int i; 207d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott int leftover = len % 4; 208d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott int chunks = (leftover == 0) ? len / 4 - 1 : len /4; 209d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 210d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott uint8_t* p = (uint8_t*)dest; 211d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott uint32_t x = 0; 212d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott uint32_t* destInt = (uint32_t*) p; 213d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott uint32_t* srcInt = (uint32_t*) src; 214d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott uint32_t y = *srcInt++; 215d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott for (i = 0; i < chunks; ++i) { 216d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott x = d0[y & 0xff] | 217d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott d1[(y >> 8) & 0xff] | 218d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott d2[(y >> 16) & 0xff] | 219d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott d3[(y >> 24) & 0xff]; 220d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 221d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott if (x >= BADCHAR) return -1; 222d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott *destInt = x ; 223d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott p += 3; 224d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott destInt = (uint32_t*)p; 225d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott y = *srcInt++;} 226d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 227d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 228d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott switch (leftover) { 229d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott case 0: 230d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott x = d0[y & 0xff] | 231d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott d1[(y >> 8) & 0xff] | 232d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott d2[(y >> 16) & 0xff] | 233d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott d3[(y >> 24) & 0xff]; 234d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 235d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott if (x >= BADCHAR) return -1; 236d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott *p++ = ((uint8_t*)(&x))[0]; 237d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott *p++ = ((uint8_t*)(&x))[1]; 238d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott *p = ((uint8_t*)(&x))[2]; 239d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott return (chunks+1)*3; 240d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott break; 241d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott case 1: /* with padding this is an impossible case */ 242d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott x = d0[y & 0xff]; 243d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott *p = *((uint8_t*)(&x)); // i.e. first char/byte in int 244d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott break; 245d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott case 2: // * case 2, 1 output byte */ 246d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott x = d0[y & 0xff] | d1[y >> 8 & 0xff]; 247d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott *p = *((uint8_t*)(&x)); // i.e. first char 248d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott break; 249d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott default: /* case 3, 2 output bytes */ 250d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott x = d0[y & 0xff] | 251d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott d1[y >> 8 & 0xff ] | 252d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott d2[y >> 16 & 0xff]; /* 0x3c */ 253d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott *p++ = ((uint8_t*)(&x))[0]; 254d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott *p = ((uint8_t*)(&x))[1]; 255d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott break; 256d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott } 257d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 258d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott if (x >= BADCHAR) return -1; 259d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 260d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott return 3*chunks + (6*leftover)/8; 261d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott} 262d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott 263d9f0c9bcce7092bf92cab485981630bd74307831Patrick Scott#endif /* if bigendian / else / endif */ 264