in core/src/main/java/org/apache/james/mime4j/codec/Base64InputStream.java [153:255]
private int read0(final byte[] buffer, final int off, final int len) throws IOException {
int to = off + len;
int index = off;
// check if a previous invocation left decoded content
if (decodedBuf.length() > 0) {
int chunk = Math.min(decodedBuf.length(), len);
System.arraycopy(decodedBuf.buffer(), 0, buffer, index, chunk);
decodedBuf.remove(0, chunk);
index += chunk;
}
// eof or pad reached?
if (eof)
return index == off ? EOF : index - off;
// decode into given buffer
int data = 0; // holds decoded data; up to four sextets
int sextets = 0; // number of sextets
while (index < to) {
// make sure buffer not empty
while (position == size) {
int n = in.read(encoded, 0, encoded.length);
if (n == EOF) {
eof = true;
if (sextets != 0) {
// error in encoded data
handleUnexpectedEof(sextets);
}
return index == off ? EOF : index - off;
} else if (n > 0) {
position = 0;
size = n;
} else {
assert n == 0;
}
}
// decode buffer
while (position < size && index < to) {
int value = encoded[position++] & 0xff;
if (value == BASE64_PAD) {
index = decodePad(data, sextets, buffer, index, to);
return index - off;
}
int decoded = BASE64_DECODE[value];
if (decoded < 0) { // -1: not a base64 char
if (value != 0x0D && value != 0x0A && value != 0x20) {
if (monitor.warn("Unexpected base64 byte: "+(byte) value, "ignoring."))
throw new IOException("Unexpected base64 byte");
}
continue;
}
data = (data << 6) | decoded;
sextets++;
if (sextets == 4) {
sextets = 0;
byte b1 = (byte) (data >>> 16);
byte b2 = (byte) (data >>> 8);
byte b3 = (byte) data;
if (index < to - 2) {
buffer[index++] = b1;
buffer[index++] = b2;
buffer[index++] = b3;
} else {
if (index < to - 1) {
buffer[index++] = b1;
buffer[index++] = b2;
decodedBuf.append(b3);
} else if (index < to) {
buffer[index++] = b1;
decodedBuf.append(b2);
decodedBuf.append(b3);
} else {
decodedBuf.append(b1);
decodedBuf.append(b2);
decodedBuf.append(b3);
}
assert index == to;
return to - off;
}
}
}
}
assert sextets == 0;
assert index == to;
return to - off;
}