/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "plbase64.h"
#include "prlog.h" /* For PR_NOT_REACHED */
#include "prmem.h" /* for malloc / PR_MALLOC */

#include <string.h> /* for strlen */

static unsigned char *base = (unsigned char *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

static void
encode3to4
(
    const unsigned char    *src,
    unsigned char          *dest
)
{
    PRUint32 b32 = (PRUint32)0;
    PRIntn i, j = 18;

    for( i = 0; i < 3; i++ )
    {
        b32 <<= 8;
        b32 |= (PRUint32)src[i];
    }

    for( i = 0; i < 4; i++ )
    {
        dest[i] = base[ (PRUint32)((b32>>j) & 0x3F) ];
        j -= 6;
    }

    return;
}

static void
encode2to4
(
    const unsigned char    *src,
    unsigned char          *dest
)
{
    dest[0] = base[ (PRUint32)((src[0]>>2) & 0x3F) ];
    dest[1] = base[ (PRUint32)(((src[0] & 0x03) << 4) | ((src[1] >> 4) & 0x0F)) ];
    dest[2] = base[ (PRUint32)((src[1] & 0x0F) << 2) ];
    dest[3] = (unsigned char)'=';
    return;
}

static void
encode1to4
(
    const unsigned char    *src,
    unsigned char          *dest
)
{
    dest[0] = base[ (PRUint32)((src[0]>>2) & 0x3F) ];
    dest[1] = base[ (PRUint32)((src[0] & 0x03) << 4) ];
    dest[2] = (unsigned char)'=';
    dest[3] = (unsigned char)'=';
    return;
}

static void
encode
(
    const unsigned char    *src,
    PRUint32                srclen,
    unsigned char          *dest
)
{
    while( srclen >= 3 )
    {
        encode3to4(src, dest);
        src += 3;
        dest += 4;
        srclen -= 3;
    }

    switch( srclen )
    {
        case 2:
            encode2to4(src, dest);
            break;
        case 1:
            encode1to4(src, dest);
            break;
        case 0:
            break;
        default:
            PR_NOT_REACHED("coding error");
    }

    return;
}

/*
 * PL_Base64Encode
 *
 * If the destination argument is NULL, a return buffer is
 * allocated, and the data therein will be null-terminated.
 * If the destination argument is not NULL, it is assumed to
 * be of sufficient size, and the contents will not be null-
 * terminated by this routine.
 *
 * Returns null if the allocation fails.
 */

PR_IMPLEMENT(char *)
PL_Base64Encode
(
    const char *src,
    PRUint32    srclen,
    char       *dest
)
{
    if( 0 == srclen )
    {
        size_t len = strlen(src);
        srclen = len;
        /* Detect truncation. */
        if( srclen != len )
        {
            return (char *)0;
        }
    }

    if( (char *)0 == dest )
    {
        PRUint32 destlen;
        /* Ensure all PRUint32 values stay within range. */
        if( srclen > (PR_UINT32_MAX/4) * 3 )
        {
            return (char *)0;
        }
        destlen = ((srclen + 2)/3) * 4;
        dest = (char *)PR_MALLOC(destlen + 1);
        if( (char *)0 == dest )
        {
            return (char *)0;
        }
        dest[ destlen ] = (char)0; /* null terminate */
    }

    encode((const unsigned char *)src, srclen, (unsigned char *)dest);
    return dest;
}

static PRInt32
codetovalue
(
    unsigned char c
)
{
    if( (c >= (unsigned char)'A') && (c <= (unsigned char)'Z') )
    {
        return (PRInt32)(c - (unsigned char)'A');
    }
    else if( (c >= (unsigned char)'a') && (c <= (unsigned char)'z') )
    {
        return ((PRInt32)(c - (unsigned char)'a') +26);
    }
    else if( (c >= (unsigned char)'0') && (c <= (unsigned char)'9') )
    {
        return ((PRInt32)(c - (unsigned char)'0') +52);
    }
    else if( (unsigned char)'+' == c )
    {
        return (PRInt32)62;
    }
    else if( (unsigned char)'/' == c )
    {
        return (PRInt32)63;
    }
    else
    {
        return -1;
    }
}

static PRStatus
decode4to3
(
    const unsigned char    *src,
    unsigned char          *dest
)
{
    PRUint32 b32 = (PRUint32)0;
    PRInt32 bits;
    PRIntn i;

    for( i = 0; i < 4; i++ )
    {
        bits = codetovalue(src[i]);
        if( bits < 0 )
        {
            return PR_FAILURE;
        }

        b32 <<= 6;
        b32 |= bits;
    }

    dest[0] = (unsigned char)((b32 >> 16) & 0xFF);
    dest[1] = (unsigned char)((b32 >>  8) & 0xFF);
    dest[2] = (unsigned char)((b32      ) & 0xFF);

    return PR_SUCCESS;
}

static PRStatus
decode3to2
(
    const unsigned char    *src,
    unsigned char          *dest
)
{
    PRUint32 b32 = (PRUint32)0;
    PRInt32 bits;
    PRUint32 ubits;

    bits = codetovalue(src[0]);
    if( bits < 0 )
    {
        return PR_FAILURE;
    }

    b32 = (PRUint32)bits;
    b32 <<= 6;

    bits = codetovalue(src[1]);
    if( bits < 0 )
    {
        return PR_FAILURE;
    }

    b32 |= (PRUint32)bits;
    b32 <<= 4;

    bits = codetovalue(src[2]);
    if( bits < 0 )
    {
        return PR_FAILURE;
    }

    ubits = (PRUint32)bits;
    b32 |= (ubits >> 2);

    dest[0] = (unsigned char)((b32 >> 8) & 0xFF);
    dest[1] = (unsigned char)((b32     ) & 0xFF);

    return PR_SUCCESS;
}

static PRStatus
decode2to1
(
    const unsigned char    *src,
    unsigned char          *dest
)
{
    PRUint32 b32;
    PRUint32 ubits;
    PRInt32 bits;

    bits = codetovalue(src[0]);
    if( bits < 0 )
    {
        return PR_FAILURE;
    }

    ubits = (PRUint32)bits;
    b32 = (ubits << 2);

    bits = codetovalue(src[1]);
    if( bits < 0 )
    {
        return PR_FAILURE;
    }

    ubits = (PRUint32)bits;
    b32 |= (ubits >> 4);

    dest[0] = (unsigned char)b32;

    return PR_SUCCESS;
}

static PRStatus
decode
(
    const unsigned char    *src,
    PRUint32                srclen,
    unsigned char          *dest
)
{
    PRStatus rv;

    while( srclen >= 4 )
    {
        rv = decode4to3(src, dest);
        if( PR_SUCCESS != rv )
        {
            return PR_FAILURE;
        }

        src += 4;
        dest += 3;
        srclen -= 4;
    }

    switch( srclen )
    {
        case 3:
            rv = decode3to2(src, dest);
            break;
        case 2:
            rv = decode2to1(src, dest);
            break;
        case 1:
            rv = PR_FAILURE;
            break;
        case 0:
            rv = PR_SUCCESS;
            break;
        default:
            PR_NOT_REACHED("coding error");
    }

    return rv;
}

/*
 * PL_Base64Decode
 *
 * If the destination argument is NULL, a return buffer is
 * allocated and the data therein will be null-terminated.
 * If the destination argument is not null, it is assumed
 * to be of sufficient size, and the data will not be null-
 * terminated by this routine.
 *
 * Returns null if the allocation fails, or if the source string is
 * not well-formed.
 */

PR_IMPLEMENT(char *)
PL_Base64Decode
(
    const char *src,
    PRUint32    srclen,
    char       *dest
)
{
    PRStatus status;
    PRBool allocated = PR_FALSE;

    if( (char *)0 == src )
    {
        return (char *)0;
    }

    if( 0 == srclen )
    {
        size_t len = strlen(src);
        srclen = len;
        /* Detect truncation. */
        if( srclen != len )
        {
            return (char *)0;
        }
    }

    if( srclen && (0 == (srclen & 3)) )
    {
        if( (char)'=' == src[ srclen-1 ] )
        {
            if( (char)'=' == src[ srclen-2 ] )
            {
                srclen -= 2;
            }
            else
            {
                srclen -= 1;
            }
        }
    }

    if( (char *)0 == dest )
    {
        /* The following computes ((srclen * 3) / 4) without overflow. */
        PRUint32 destlen = (srclen / 4) * 3 + ((srclen % 4) * 3) / 4;
        dest = (char *)PR_MALLOC(destlen + 1);
        if( (char *)0 == dest )
        {
            return (char *)0;
        }
        dest[ destlen ] = (char)0; /* null terminate */
        allocated = PR_TRUE;
    }

    status = decode((const unsigned char *)src, srclen, (unsigned char *)dest);
    if( PR_SUCCESS != status )
    {
        if( PR_TRUE == allocated )
        {
            PR_DELETE(dest);
        }

        return (char *)0;
    }

    return dest;
}
