}
protected byte[] _decodeBase64(Base64Variant b64variant)
throws IOException, JsonParseException
{
ByteArrayBuilder builder = _getByteArrayBuilder();
final String str = getText();
int ptr = 0;
int len = str.length();
main_loop:
while (ptr < len) {
// first, we'll skip preceding white space, if any
char ch;
do {
ch = str.charAt(ptr++);
if (ptr >= len) {
break main_loop;
}
} while (ch <= INT_SPACE);
int bits = b64variant.decodeBase64Char(ch);
if (bits < 0) {
_reportInvalidBase64(b64variant, ch, 0, null);
}
int decodedData = bits;
// then second base64 char; can't get padding yet, nor ws
if (ptr >= len) {
_reportBase64EOF();
}
ch = str.charAt(ptr++);
bits = b64variant.decodeBase64Char(ch);
if (bits < 0) {
_reportInvalidBase64(b64variant, ch, 1, null);
}
decodedData = (decodedData << 6) | bits;
// third base64 char; can be padding, but not ws
if (ptr >= len) {
_reportBase64EOF();
}
ch = str.charAt(ptr++);
bits = b64variant.decodeBase64Char(ch);
// First branch: can get padding (-> 1 byte)
if (bits < 0) {
if (bits != Base64Variant.BASE64_VALUE_PADDING) {
_reportInvalidBase64(b64variant, ch, 2, null);
}
// Ok, must get padding
if (ptr >= len) {
_reportBase64EOF();
}
ch = str.charAt(ptr++);
if (!b64variant.usesPaddingChar(ch)) {
_reportInvalidBase64(b64variant, ch, 3, "expected padding character '"+b64variant.getPaddingChar()+"'");
}
// Got 12 bits, only need 8, need to shift
decodedData >>= 4;
builder.append(decodedData);
continue;
}
// Nope, 2 or 3 bytes
decodedData = (decodedData << 6) | bits;
// fourth and last base64 char; can be padding, but not ws
if (ptr >= len) {
_reportBase64EOF();
}
ch = str.charAt(ptr++);
bits = b64variant.decodeBase64Char(ch);
if (bits < 0) {
if (bits != Base64Variant.BASE64_VALUE_PADDING) {
_reportInvalidBase64(b64variant, ch, 3, null);
}
decodedData >>= 2;
builder.appendTwoBytes(decodedData);
} else {
// otherwise, our triple is now complete
decodedData = (decodedData << 6) | bits;
builder.appendThreeBytes(decodedData);
}
}
return builder.toByteArray();
}