in src/main/java/org/apache/xml/security/utils/Base64.java [693:762]
public static 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));
}
}