protected static void decode()

in src/main/java/org/apache/xml/security/utils/Base64.java [610:683]


    protected static 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));
        }
    }