/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.xml.security.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;

import org.apache.xml.security.exceptions.Base64DecodingException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;

/**
 * Implementation of MIME's Base64 encoding and decoding conversions.
 * Optimized code. (raw version taken from oreilly.jonathan.util,
 * and currently org.apache.xerces.ds.util.Base64)
 *
 * @see <A HREF="ftp://ftp.isi.edu/in-notes/rfc2045.txt">RFC 2045</A>
 * @see org.apache.xml.security.transforms.implementations.TransformBase64Decode
 */
@Deprecated
public class Base64 {

    /** Field BASE64DEFAULTLENGTH */
    public static final int BASE64DEFAULTLENGTH = 76;

    private static final int BASELENGTH = 255;
    private static final int LOOKUPLENGTH = 64;
    private static final int TWENTYFOURBITGROUP = 24;
    private static final int EIGHTBIT = 8;
    private static final int SIXTEENBIT = 16;
    private static final int FOURBYTE = 4;
    private static final int SIGN = -128;
    private static final char PAD = '=';
    private static final byte [] base64Alphabet = new byte[BASELENGTH];
    private static final char [] lookUpBase64Alphabet = new char[LOOKUPLENGTH];

    static {
        for (int i = 0; i < BASELENGTH; i++) {
            base64Alphabet[i] = -1;
        }
        for (int i = 'Z'; i >= 'A'; i--) {
            base64Alphabet[i] = (byte) (i - 'A');
        }
        for (int i = 'z'; i>= 'a'; i--) {
            base64Alphabet[i] = (byte) (i - 'a' + 26);
        }

        for (int i = '9'; i >= '0'; i--) {
            base64Alphabet[i] = (byte) (i - '0' + 52);
        }

        base64Alphabet['+'] = 62;
        base64Alphabet['/'] = 63;

        for (int i = 0; i <= 25; i++) {
            lookUpBase64Alphabet[i] = (char)('A' + i);
        }

        for (int i = 26,  j = 0; i <= 51; i++, j++) {
            lookUpBase64Alphabet[i] = (char)('a' + j);
        }

        for (int i = 52,  j = 0; i <= 61; i++, j++) {
            lookUpBase64Alphabet[i] = (char)('0' + j);
        }
        lookUpBase64Alphabet[62] = '+';
        lookUpBase64Alphabet[63] = '/';
    }

    private Base64() {
        // we don't allow instantiation
    }

    /**
     * Returns a byte-array representation of a <code>{@link BigInteger}<code>.
     * No sign-bit is output.
     *
     * <b>N.B.:</B> <code>{@link BigInteger}<code>'s toByteArray
     * returns eventually longer arrays because of the leading sign-bit.
     *
     * @param big <code>BigInteger</code> to be converted
     * @param bitlen <code>int</code> the desired length in bits of the representation
     * @return a byte array with <code>bitlen</code> bits of <code>big</code>
     */
    static final byte[] getBytes(BigInteger big, int bitlen) {

        //round bitlen
        bitlen = ((bitlen + 7) >> 3) << 3;

        if (bitlen < big.bitLength()) {
            throw new IllegalArgumentException(I18n.translate("utils.Base64.IllegalBitlength"));
        }

        byte[] bigBytes = big.toByteArray();

        if (big.bitLength() % 8 != 0
            && big.bitLength() / 8 + 1 == bitlen / 8) {
            return bigBytes;
        }

        // some copying needed
        int startSrc = 0;    // no need to skip anything
        int bigLen = bigBytes.length;    //valid length of the string

        if (big.bitLength() % 8 == 0) {    // correct values
            startSrc = 1;    // skip sign bit

            bigLen--;    // valid length of the string
        }

        int startDst = bitlen / 8 - bigLen;    //pad with leading nulls
        byte[] resizedBytes = new byte[bitlen / 8];

        System.arraycopy(bigBytes, startSrc, resizedBytes, startDst, bigLen);

        return resizedBytes;
    }

    /**
     * Encode in Base64 the given <code>{@link BigInteger}</code>.
     *
     * @param big
     * @return String with Base64 encoding
     */
    public static final String encode(BigInteger big) {
        byte[] bytes = XMLUtils.getBytes(big, big.bitLength());
        return XMLUtils.encodeToString(bytes);
    }

    /**
     * Returns a byte-array representation of a <code>{@link BigInteger}</code>.
     * No sign-bit is output.
     *
     * <b>N.B.:</B> <code>{@link BigInteger}</code>'s toByteArray
     * returns eventually longer arrays because of the leading sign-bit.
     *
     * @param big <code>BigInteger</code> to be converted
     * @param bitlen <code>int</code> the desired length in bits of the representation
     * @return a byte array with <code>bitlen</code> bits of <code>big</code>
     */
    public static final byte[] encode(BigInteger big, int bitlen) {

        //round bitlen
        bitlen = ((bitlen + 7) >> 3) << 3;

        if (bitlen < big.bitLength()) {
            throw new IllegalArgumentException(I18n.translate("utils.Base64.IllegalBitlength"));
        }

        byte[] bigBytes = big.toByteArray();

        if (big.bitLength() % 8 != 0
            && big.bitLength() / 8 + 1 == bitlen / 8) {
            return bigBytes;
        }

        // some copying needed
        int startSrc = 0;    // no need to skip anything
        int bigLen = bigBytes.length;    //valid length of the string

        if (big.bitLength() % 8 == 0) {    // correct values
            startSrc = 1;    // skip sign bit

            bigLen--;    // valid length of the string
        }

        int startDst = bitlen / 8 - bigLen;    //pad with leading nulls
        byte[] resizedBytes = new byte[bitlen / 8];

        System.arraycopy(bigBytes, startSrc, resizedBytes, startDst, bigLen);

        return resizedBytes;
    }

    /**
     * Method decodeBigIntegerFromElement
     *
     * @param element
     * @return the biginteger obtained from the node
     * @throws Base64DecodingException
     */
    public static final BigInteger decodeBigIntegerFromElement(Element element)
        throws Base64DecodingException {
        return new BigInteger(1, Base64.decode(element));
    }

    /**
     * Decode a base 64 string into a {@link BigInteger}
     * @param base64str Base 64 encoded string.
     * @return a decoded BigInteger
     * @throws Base64DecodingException
     */
    public static final BigInteger decodeBigIntegerFromText(Text text)
        throws Base64DecodingException {
        return new BigInteger(1, Base64.decode(text.getData()));
    }

    /**
     * This method takes an (empty) Element and a BigInteger and adds the
     * base64 encoded BigInteger to the Element.
     *
     * @param element
     * @param biginteger
     */
    public static final void fillElementWithBigInteger(Element element, BigInteger biginteger) {

        String encodedInt = encode(biginteger);

        if (!XMLUtils.ignoreLineBreaks() && encodedInt.length() > BASE64DEFAULTLENGTH) {
            encodedInt = "\n" + encodedInt + "\n";
        }

        Document doc = element.getOwnerDocument();
        Text text = doc.createTextNode(encodedInt);

        element.appendChild(text);
    }

    /**
     * Method decode
     *
     * Takes the <CODE>Text</CODE> children of the Element and interprets
     * them as input for the <CODE>Base64.decode()</CODE> function.
     *
     * @param element
     * @return the byte obtained of the decoding the element
     * $todo$ not tested yet
     * @throws Base64DecodingException
     */
    public static final byte[] decode(Element element) throws Base64DecodingException {

        Node sibling = element.getFirstChild();
        StringBuilder sb = new StringBuilder();

        while (sibling != null) {
            if (sibling.getNodeType() == Node.TEXT_NODE) {
                Text t = (Text) sibling;

                sb.append(t.getData());
            }
            sibling = sibling.getNextSibling();
        }

        return decode(sb.toString());
    }

    /**
     * Method encodeToElement
     *
     * @param doc
     * @param localName
     * @param bytes
     * @return an Element with the base64 encoded in the text.
     *
     */
    public static final Element encodeToElement(Document doc, String localName, byte[] bytes) {
        Element el = XMLUtils.createElementInSignatureSpace(doc, localName);
        Text text = doc.createTextNode(encode(bytes));

        el.appendChild(text);

        return el;
    }

    /**
     * Method decode
     *
     * @param base64
     * @return the UTF bytes of the base64
     * @throws Base64DecodingException
     *
     */
    public static final byte[] decode(byte[] base64) throws Base64DecodingException  {
        return decodeInternal(base64, -1);
    }

    /**
     * Encode a byte array and fold lines at the standard 76th character unless
     * ignore line breaks property is set.
     *
     * @param binaryData <code>byte[]</code> to be base64 encoded
     * @return the <code>String</code> with encoded data
     */
    public static final String encode(byte[] binaryData) {
        return XMLUtils.ignoreLineBreaks()
            ? encode(binaryData, Integer.MAX_VALUE)
            : encode(binaryData, BASE64DEFAULTLENGTH);
    }

    /**
     * Base64 decode the lines from the reader and return an InputStream
     * with the bytes.
     *
     * @param reader
     * @return InputStream with the decoded bytes
     * @exception IOException passes what the reader throws
     * @throws IOException
     * @throws Base64DecodingException
     */
    public static final byte[] decode(BufferedReader reader)
        throws IOException, Base64DecodingException {

        byte[] retBytes = null;
        UnsyncByteArrayOutputStream baos = new UnsyncByteArrayOutputStream();
        try {
            String line;
            while (null != (line = reader.readLine())) {
                byte[] bytes = decode(line);
                baos.write(bytes);
            }
            retBytes = baos.toByteArray();
        } finally {
            baos.close();
        }

        return retBytes;
    }

    protected static final boolean isWhiteSpace(byte octet) {
        return octet == 0x20 || octet == 0xd || octet == 0xa || octet == 0x9;
    }

    protected static final boolean isPad(byte octet) {
        return octet == PAD;
    }

    /**
     * Encodes hex octets into Base64
     *
     * @param binaryData Array containing binaryData
     * @return Encoded Base64 array
     */
    /**
     * Encode a byte array in Base64 format and return an optionally
     * wrapped line.
     *
     * @param binaryData <code>byte[]</code> data to be encoded
     * @param length <code>int</code> length of wrapped lines; No wrapping if less than 4.
     * @return a <code>String</code> with encoded data
     */
    public static final String  encode(byte[] binaryData, int length) {
        if (length < 4) {
            length = Integer.MAX_VALUE;
        }

        if (binaryData == null) {
            return null;
        }

        long lengthDataBits = ((long) binaryData.length) * ((long) EIGHTBIT);
        if (lengthDataBits == 0L) {
            return "";
        }

        long fewerThan24bits = lengthDataBits % ((long) TWENTYFOURBITGROUP);
        int numberTriplets = (int) (lengthDataBits / TWENTYFOURBITGROUP);
        int numberQuartet = fewerThan24bits != 0L ? numberTriplets + 1 : numberTriplets;
        int quartesPerLine = length / 4;
        int numberLines = (numberQuartet - 1) / quartesPerLine;
        char encodedData[] = null;

        encodedData = new char[numberQuartet * 4 + numberLines * 2];

        byte k = 0, l = 0, b1 = 0, b2 = 0, b3 = 0;
        int encodedIndex = 0;
        int dataIndex = 0;
        int i = 0;

        for (int line = 0; line < numberLines; line++) {
            for (int quartet = 0; quartet < 19; quartet++) {
                b1 = binaryData[dataIndex++];
                b2 = binaryData[dataIndex++];
                b3 = binaryData[dataIndex++];

                l = (byte)(b2 & 0x0f);
                k = (byte)(b1 & 0x03);

                byte val1 = ((b1 & SIGN) == 0) ? (byte)(b1 >> 2): (byte)((b1) >> 2 ^ 0xc0);

                byte val2 = ((b2 & SIGN) == 0) ? (byte)(b2 >> 4) : (byte)((b2) >> 4 ^ 0xf0);
                byte val3 = ((b3 & SIGN) == 0) ? (byte)(b3 >> 6) : (byte)((b3) >> 6 ^ 0xfc);


                encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
                encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
                encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3];
                encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f];

                i++;
            }
            encodedData[encodedIndex++] = 0xd;
            encodedData[encodedIndex++] = 0xa;
        }

        for (; i < numberTriplets; i++) {
            b1 = binaryData[dataIndex++];
            b2 = binaryData[dataIndex++];
            b3 = binaryData[dataIndex++];

            l = (byte)(b2 & 0x0f);
            k = (byte)(b1 & 0x03);

            byte val1 = ((b1 & SIGN) == 0) ? (byte)(b1 >> 2) : (byte)((b1) >> 2 ^ 0xc0);

            byte val2 = ((b2 & SIGN) == 0) ? (byte)(b2 >> 4) : (byte)((b2) >> 4 ^ 0xf0);
            byte val3 = ((b3 & SIGN) == 0) ? (byte)(b3 >> 6) : (byte)((b3) >> 6 ^ 0xfc);


            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
            encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
            encodedData[encodedIndex++] = lookUpBase64Alphabet[(l << 2) | val3];
            encodedData[encodedIndex++] = lookUpBase64Alphabet[b3 & 0x3f];
        }

        // form integral number of 6-bit groups
        if (fewerThan24bits == EIGHTBIT) {
            b1 = binaryData[dataIndex];
            k = (byte) (b1 &0x03);
            byte val1 = ((b1 & SIGN) == 0) ? (byte)(b1 >> 2):(byte)((b1) >> 2 ^ 0xc0);
            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
            encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4];
            encodedData[encodedIndex++] = PAD;
            encodedData[encodedIndex++] = PAD;
        } else if (fewerThan24bits == SIXTEENBIT) {
            b1 = binaryData[dataIndex];
            b2 = binaryData[dataIndex +1 ];
            l = ( byte ) (b2 & 0x0f);
            k = ( byte ) (b1 & 0x03);

            byte val1 = ((b1 & SIGN) == 0) ? (byte)(b1 >> 2) : (byte)((b1) >> 2 ^ 0xc0);
            byte val2 = ((b2 & SIGN) == 0) ? (byte)(b2 >> 4) : (byte)((b2) >> 4 ^ 0xf0);

            encodedData[encodedIndex++] = lookUpBase64Alphabet[val1];
            encodedData[encodedIndex++] = lookUpBase64Alphabet[val2 | (k << 4)];
            encodedData[encodedIndex++] = lookUpBase64Alphabet[l << 2];
            encodedData[encodedIndex++] = PAD;
        }

        //encodedData[encodedIndex] = 0xa;

        return new String(encodedData);
    }

    /**
     * Decodes Base64 data into octets
     *
     * @param encoded String containing base64 encoded data
     * @return byte array containing the decoded data
     * @throws Base64DecodingException if there is a problem decoding the data
     */
    public static final byte[] decode(String encoded) throws Base64DecodingException {
        if (encoded == null) {
            return null;
        }
        byte[] bytes = new byte[encoded.length()];
        int len = getBytesInternal(encoded, bytes);
        return decodeInternal(bytes, len);
    }

    protected static final int getBytesInternal(String s, byte[] result) {
        int length = s.length();

        int newSize = 0;
        for (int i = 0; i < length; i++) {
            byte dataS = (byte)s.charAt(i);
            if (!isWhiteSpace(dataS)) {
                result[newSize++] = dataS;
            }
        }
        return newSize;
    }

    protected static final byte[] decodeInternal(byte[] base64Data, int len)
        throws Base64DecodingException {
        // remove white spaces
        if (len == -1) {
            len = removeWhiteSpace(base64Data);
        }

        if (len % FOURBYTE != 0) {
            throw new Base64DecodingException("decoding.divisible.four");
            //should be divisible by four
        }

        int numberQuadruple = len / FOURBYTE;

        if (numberQuadruple == 0) {
            return new byte[0];
        }

        byte decodedData[] = null;
        byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;

        int i = 0;
        int encodedIndex = 0;
        int dataIndex = 0;

        //decodedData = new byte[ (numberQuadruple)*3];
        dataIndex = (numberQuadruple - 1) * 4;
        encodedIndex = (numberQuadruple - 1) * 3;
        //first last bits.
        b1 = base64Alphabet[base64Data[dataIndex++]];
        b2 = base64Alphabet[base64Data[dataIndex++]];
        if (b1 == -1 || b2 == -1) {
             //if found "no data" just return null
            throw new Base64DecodingException("decoding.general");
        }


        byte d3, d4;
        b3 = base64Alphabet[d3 = base64Data[dataIndex++]];
        b4 = base64Alphabet[d4 = base64Data[dataIndex++]];
        if (b3 == -1 || b4 == -1) {
            //Check if they are PAD characters
            if (isPad(d3) && isPad(d4)) {               //Two PAD e.g. 3c[Pad][Pad]
                if ((b2 & 0xf) != 0) { //last 4 bits should be zero
                    throw new Base64DecodingException("decoding.general");
                }
                decodedData = new byte[encodedIndex + 1];
                decodedData[encodedIndex]   = (byte)(b1 << 2 | b2 >> 4) ;
            } else if (!isPad(d3) && isPad(d4)) {               //One PAD  e.g. 3cQ[Pad]
                if ((b3 & 0x3) != 0) { //last 2 bits should be zero
                    throw new Base64DecodingException("decoding.general");
                }
                decodedData = new byte[encodedIndex + 2];
                decodedData[encodedIndex++] = (byte)(b1 << 2 | b2 >> 4);
                decodedData[encodedIndex] = (byte)(((b2 & 0xf) << 4) |((b3 >> 2) & 0xf));
            } else {
                //an error  like "3c[Pad]r", "3cdX", "3cXd", "3cXX" where X is non data
                throw new Base64DecodingException("decoding.general");
            }
        } else {
            //No PAD e.g 3cQl
            decodedData = new byte[encodedIndex+3];
            decodedData[encodedIndex++] = (byte)(b1 << 2 | b2 >> 4) ;
            decodedData[encodedIndex++] = (byte)(((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
            decodedData[encodedIndex++] = (byte)(b3 << 6 | b4);
        }
        encodedIndex = 0;
        dataIndex = 0;
        //the begin
        for (i = numberQuadruple - 1; i > 0; i--) {
            b1 = base64Alphabet[base64Data[dataIndex++]];
            b2 = base64Alphabet[base64Data[dataIndex++]];
            b3 = base64Alphabet[base64Data[dataIndex++]];
            b4 = base64Alphabet[base64Data[dataIndex++]];

            if (b1 == -1 || b2 == -1 || b3 == -1 || b4 == -1) {
                //if found "no data" just return null
                throw new Base64DecodingException("decoding.general");
            }

            decodedData[encodedIndex++] = (byte)(b1 << 2 | b2 >> 4) ;
            decodedData[encodedIndex++] = (byte)(((b2 & 0xf) << 4) |((b3 >> 2) & 0xf));
            decodedData[encodedIndex++] = (byte)(b3 << 6 | b4 );
        }
        return decodedData;
    }

    /**
     * Decodes Base64 data into outputstream
     *
     * @param base64Data String containing Base64 data
     * @param os the outputstream
     * @throws IOException
     * @throws Base64DecodingException
     */
    public static final void decode(String base64Data, OutputStream os)
        throws Base64DecodingException, IOException {
        byte[] bytes = new byte[base64Data.length()];
        int len = getBytesInternal(base64Data, bytes);
        decode(bytes, os, len);
    }

    /**
     * Decodes Base64 data into outputstream
     *
     * @param base64Data Byte array containing Base64 data
     * @param os the outputstream
     * @throws IOException
     * @throws Base64DecodingException
     */
    public static final void decode(byte[] base64Data, OutputStream os)
        throws Base64DecodingException, IOException {
        decode(base64Data, os, -1);
    }

    protected static final void decode(byte[] base64Data, OutputStream os, int len)
        throws Base64DecodingException, IOException {
        // remove white spaces
        if (len == -1) {
            len = removeWhiteSpace(base64Data);
        }

        if (len % FOURBYTE != 0) {
            throw new Base64DecodingException("decoding.divisible.four");
            //should be divisible by four
        }

        int numberQuadruple = len / FOURBYTE;

        if (numberQuadruple == 0) {
            return;
        }

        //byte decodedData[] = null;
        byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;

        int i = 0;
        int dataIndex = 0;

        //the begin
        for (i = numberQuadruple - 1; i > 0; i--) {
            b1 = base64Alphabet[base64Data[dataIndex++]];
            b2 = base64Alphabet[base64Data[dataIndex++]];
            b3 = base64Alphabet[base64Data[dataIndex++]];
            b4 = base64Alphabet[base64Data[dataIndex++]];
            if (b1 == -1 || b2 == -1 || b3 == -1 || b4 == -1) {
                //if found "no data" just return null
                throw new Base64DecodingException("decoding.general");
            }

            os.write((byte)(b1 << 2 | b2 >> 4));
            os.write((byte)(((b2 & 0xf) << 4 ) | ((b3 >> 2) & 0xf)));
            os.write((byte)(b3 << 6 | b4));
        }
        b1 = base64Alphabet[base64Data[dataIndex++]];
        b2 = base64Alphabet[base64Data[dataIndex++]];

        //  first last bits.
        if (b1 == -1 || b2 == -1) {
            //if found "no data" just return null
            throw new Base64DecodingException("decoding.general");
        }

        byte d3, d4;
        b3 = base64Alphabet[d3 = base64Data[dataIndex++]];
        b4 = base64Alphabet[d4 = base64Data[dataIndex++]];
        if (b3 == -1 || b4 == -1) { //Check if they are PAD characters
            if (isPad(d3) && isPad(d4)) {               //Two PAD e.g. 3c[Pad][Pad]
                if ((b2 & 0xf) != 0) { //last 4 bits should be zero
                    throw new Base64DecodingException("decoding.general");
                }
                os.write((byte)(b1 << 2 | b2 >> 4));
            } else if (!isPad(d3) && isPad(d4)) {               //One PAD  e.g. 3cQ[Pad]
                if ((b3 & 0x3 ) != 0) { //last 2 bits should be zero
                    throw new Base64DecodingException("decoding.general");
                }
                os.write((byte)(b1 << 2 | b2 >> 4));
                os.write((byte)(((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)));
            } else {
                //an error  like "3c[Pad]r", "3cdX", "3cXd", "3cXX" where X is non data
                throw new Base64DecodingException("decoding.general");
            }
        } else {
            //No PAD e.g 3cQl
            os.write((byte)(b1 << 2 | b2 >> 4));
            os.write( (byte)(((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)));
            os.write((byte)(b3 << 6 | b4));
        }
    }

    /**
     * Decodes Base64 data into  outputstream
     *
     * @param is containing Base64 data
     * @param os the outputstream
     * @throws IOException
     * @throws Base64DecodingException
     */
    public static final void decode(InputStream is, OutputStream os)
        throws Base64DecodingException, IOException {
        //byte decodedData[] = null;
        byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;

        int index = 0;
        byte[] data = new byte[4];
        int read;
        //the begin
        while ((read = is.read()) > 0) {
            byte readed = (byte)read;
            if (isWhiteSpace(readed)) {
                continue;
            }
            if (isPad(readed)) {
                data[index++] = readed;
                if (index == 3) {
                    data[index++] = (byte)is.read();
                }
                break;
            }

            if ((data[index++] = readed) == -1) {
                //if found "no data" just return null
                throw new Base64DecodingException("decoding.general");
            }

            if (index != 4) {
                continue;
            }
            index = 0;
            b1 = base64Alphabet[data[0]];
            b2 = base64Alphabet[data[1]];
            b3 = base64Alphabet[data[2]];
            b4 = base64Alphabet[data[3]];

            os.write((byte)(b1 << 2 | b2 >> 4));
            os.write((byte)(((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)));
            os.write((byte)(b3 << 6 | b4));
        }

        byte d1 = data[0], d2 = data[1], d3 = data[2], d4 = data[3];
        b1 = base64Alphabet[d1];
        b2 = base64Alphabet[d2];
        b3 = base64Alphabet[d3];
        b4 = base64Alphabet[d4];
        if (b3 == -1 || b4 == -1) { //Check if they are PAD characters
            if (isPad(d3) && isPad(d4)) {               //Two PAD e.g. 3c[Pad][Pad]
                if ((b2 & 0xf) != 0) { //last 4 bits should be zero
                    throw new Base64DecodingException("decoding.general");
                }
                os.write((byte)(b1 << 2 | b2 >> 4));
            } else if (!isPad(d3) && isPad(d4)) {               //One PAD  e.g. 3cQ[Pad]
                b3 = base64Alphabet[d3];
                if ((b3 & 0x3) != 0) { //last 2 bits should be zero
                    throw new Base64DecodingException("decoding.general");
                }
                os.write((byte)(b1 << 2 | b2 >> 4));
                os.write((byte)(((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)));
            } else {
                //an error  like "3c[Pad]r", "3cdX", "3cXd", "3cXX" where X is non data
                throw new Base64DecodingException("decoding.general");
            }
        } else {
            //No PAD e.g 3cQl
            os.write((byte)(b1 << 2 | b2 >> 4));
            os.write((byte)(((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)));
            os.write((byte)(b3 << 6 | b4));
        }
    }

    /**
     * remove WhiteSpace from MIME containing encoded Base64 data.
     *
     * @param data  the byte array of base64 data (with WS)
     * @return the new length
     */
    protected static final int removeWhiteSpace(byte[] data) {
        if (data == null) {
            return 0;
        }

        // count characters that's not whitespace
        int newSize = 0;
        int len = data.length;
        for (int i = 0; i < len; i++) {
            byte dataS = data[i];
            if (!isWhiteSpace(dataS)) {
                data[newSize++] = dataS;
            }
        }
        return newSize;
    }
}
