/** * @param bindex Relative index within base64 character unit; between 0 and 3 (as unit has exactly * 4 characters) */ protected IllegalArgumentException reportInvalidBase64Char( Base64Variant b64variant, int ch, int bindex, String msg) throws IllegalArgumentException { String base; if (ch <= INT_SPACE) { base = "Illegal white space character (code 0x" + Integer.toHexString(ch) + ") as character #" + (bindex + 1) + " of 4-char base64 unit: can only used between units"; } else if (b64variant.usesPaddingChar(ch)) { base = "Unexpected padding character ('" + b64variant.getPaddingChar() + "') as character #" + (bindex + 1) + " of 4-char base64 unit: padding only legal as 3rd or 4th character"; } else if (!Character.isDefined(ch) || Character.isISOControl(ch)) { // Not sure if we can really get here... ? (most illegal xml chars are caught at lower level) base = "Illegal character (code 0x" + Integer.toHexString(ch) + ") in base64 content"; } else { base = "Illegal character '" + ((char) ch) + "' (code 0x" + Integer.toHexString(ch) + ") in base64 content"; } if (msg != null) { base = base + ": " + msg; } return new IllegalArgumentException(base); }
protected void _writeBinary( Base64Variant b64variant, byte[] input, int inputPtr, final int inputEnd) throws IOException, JsonGenerationException { // Encoding is by chunks of 3 input, 4 output chars, so: int safeInputEnd = inputEnd - 3; // Let's also reserve room for possible (and quoted) lf char each round int safeOutputEnd = _outputEnd - 6; int chunksBeforeLF = b64variant.getMaxLineLength() >> 2; // Ok, first we loop through all full triplets of data: while (inputPtr <= safeInputEnd) { if (_outputTail > safeOutputEnd) { // need to flush _flushBuffer(); } // First, mash 3 bytes into lsb of 32-bit int int b24 = ((int) input[inputPtr++]) << 8; b24 |= ((int) input[inputPtr++]) & 0xFF; b24 = (b24 << 8) | (((int) input[inputPtr++]) & 0xFF); _outputTail = b64variant.encodeBase64Chunk(b24, _outputBuffer, _outputTail); if (--chunksBeforeLF <= 0) { // note: must quote in JSON value _outputBuffer[_outputTail++] = '\\'; _outputBuffer[_outputTail++] = 'n'; chunksBeforeLF = b64variant.getMaxLineLength() >> 2; } } // And then we may have 1 or 2 leftover bytes to encode int inputLeft = inputEnd - inputPtr; // 0, 1 or 2 if (inputLeft > 0) { // yes, but do we have room for output? if (_outputTail > safeOutputEnd) { // don't really need 6 bytes but... _flushBuffer(); } int b24 = ((int) input[inputPtr++]) << 16; if (inputLeft == 2) { b24 |= (((int) input[inputPtr++]) & 0xFF) << 8; } _outputTail = b64variant.encodeBase64Partial(b24, inputLeft, _outputBuffer, _outputTail); } }
protected final int _decodeBase64Escape(Base64Variant b64variant, char ch, int index) throws IOException, JsonParseException { // 17-May-2011, tatu: As per [JACKSON-xxx], need to handle escaped chars if (ch != '\\') { throw reportInvalidBase64Char(b64variant, ch, index); } char unescaped = _decodeEscaped(); // if white space, skip if first triplet; otherwise errors if (unescaped <= INT_SPACE) { if (index == 0) { // whitespace only allowed to be skipped between triplets return -1; } } // otherwise try to find actual triplet value int bits = b64variant.decodeBase64Char(unescaped); if (bits < 0) { throw reportInvalidBase64Char(b64variant, unescaped, index); } return bits; }