/*
 * 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.commons.fileupload.util.mime;

import java.io.IOException;
import java.io.OutputStream;

/**
 * @since 1.3
 */
final class Base64Decoder {

    /**
     * Set up the encoding table.
     */
    private static final byte[] ENCODING_TABLE = {
        (byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F', (byte) 'G',
        (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L', (byte) 'M', (byte) 'N',
        (byte) 'O', (byte) 'P', (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U',
        (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z',
        (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f', (byte) 'g',
        (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n',
        (byte) 'o', (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u',
        (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y', (byte) 'z',
        (byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6',
        (byte) '7', (byte) '8', (byte) '9',
        (byte) '+', (byte) '/'
    };

    /**
     * The padding byte.
     */
    private static final byte PADDING = (byte) '=';

    /**
     * Set up the decoding table; this is indexed by a byte converted to an int,
     * so must be at least as large as the number of different byte values,
     * positive and negative and zero.
     */
    private static final byte[] DECODING_TABLE = new byte[Byte.MAX_VALUE - Byte.MIN_VALUE + 1];

    static {
        for (int i = 0; i < ENCODING_TABLE.length; i++) {
            DECODING_TABLE[ENCODING_TABLE[i]] = (byte) i;
        }
    }

    /**
     * Hidden constructor, this class must not be instantiated.
     */
    private Base64Decoder() {
        // do nothing
    }

    /**
     * Checks if the input char must be skipped from the decode.
     * The method skips whitespace characters LF, CR, horizontal tab and space.
     *
     * @param c the char to be checked.
     * @return true, if the input char has to be skipped, false otherwise.
     */
    private static boolean ignore(char c) {
        return (c == '\n' || c == '\r' || c == '\t' || c == ' ');
    }

    /**
     * Decode the base 64 encoded byte data writing it to the given output stream,
     * whitespace characters will be ignored.
     *
     * @param data the buffer containing the Base64-encoded data
     * @param out the output stream to hold the decoded bytes
     *
     * @return the number of bytes produced.
     */
    public static int decode(byte[] data, OutputStream out) throws IOException {
        byte    b1, b2, b3, b4;
        int        outLen = 0;

        if (data.length == 0) {
            return outLen;
        }

        int        end = data.length;

        while (end > 0) {
            if (!ignore((char) data[end - 1])) {
                break;
            }

            end--;
        }

        int  i = 0;
        // CHECKSTYLE IGNORE MagicNumber FOR NEXT 1 LINE
        int  finish = end - 4; // last set of 4 bytes might include padding

        while (i < finish) {
            while ((i < finish) && ignore((char) data[i])) {
                i++;
            }

            b1 = DECODING_TABLE[data[i++]];

            while ((i < finish) && ignore((char) data[i])) {
                i++;
            }

            b2 = DECODING_TABLE[data[i++]];

            while ((i < finish) && ignore((char) data[i])) {
                i++;
            }

            b3 = DECODING_TABLE[data[i++]];

            while ((i < finish) && ignore((char) data[i])) {
                i++;
            }

            b4 = DECODING_TABLE[data[i++]];

            // Convert 4 6-bit bytes to 3 8-bit bytes
            // CHECKSTYLE IGNORE MagicNumber FOR NEXT 3 LINES
            out.write((b1 << 2) | (b2 >> 4)); // 6 bits of b1 plus 2 bits of b2
            out.write((b2 << 4) | (b3 >> 2)); // 4 bits of b2 plus 4 bits of b3
            out.write((b3 << 6) | b4);        // 2 bits of b3 plus 6 bits of b4

            // CHECKSTYLE IGNORE MagicNumber FOR NEXT 1 LINE
            outLen += 3;
        }

        // Get the last 4 bytes; only last two can be padding
        b1 = DECODING_TABLE[data[i++]];
        b2 = DECODING_TABLE[data[i++]];

        // always write the first byte
        // CHECKSTYLE IGNORE MagicNumber FOR NEXT 1 LINE
        out.write((b1 << 2) | (b2 >> 4)); // 6 bits of b1 plus 2 bits of b2
        outLen++;

        byte p1 = data[i++];
        byte p2 = data[i++];

        b3 = DECODING_TABLE[p1]; // may be needed later

        if (p1 != PADDING) { // Nothing more to do if p1 == PADDING
            // CHECKSTYLE IGNORE MagicNumber FOR NEXT 1 LINE
            out.write((b2 << 4) | (b3 >> 2)); // 4 bits of b2 plus 4 bits of b3
            outLen++; 
            if (p2 != PADDING) { // Nothing more to do if p2 == PADDING
                b4 = DECODING_TABLE[p2];
                // CHECKSTYLE IGNORE MagicNumber FOR NEXT 1 LINE
                out.write((b3 << 6) | b4);        // 2 bits of b3 plus 6 bits of b4
                outLen++;
            }
        }

        return outLen;
    }

}
