// Test for [JACKSON-631] public void testBase64Text() throws Exception { // let's actually iterate over sets of encoding modes, lengths final int[] LENS = {1, 2, 3, 4, 7, 9, 32, 33, 34, 35}; final Base64Variant[] VARIANTS = { Base64Variants.MIME, Base64Variants.MIME_NO_LINEFEEDS, Base64Variants.MODIFIED_FOR_URL, Base64Variants.PEM }; for (int len : LENS) { byte[] input = new byte[len]; for (int i = 0; i < input.length; ++i) { input[i] = (byte) i; } for (Base64Variant variant : VARIANTS) { TextNode n = new TextNode(variant.encode(input)); byte[] data = null; try { data = n.getBinaryValue(variant); } catch (Exception e) { throw new IOException( "Failed (variant " + variant + ", data length " + len + "): " + e.getMessage()); } assertNotNull(data); assertArrayEquals(data, input); } } }
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 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: RISON does not escape newlines _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); } }
@Override public void writeBinary(Base64Variant b64variant, byte[] data, int offset, int len) throws IOException, JsonGenerationException { if (data == null) { writeNull(); return; } _verifyValueWrite("write Binary value"); if (!_skipValue) { // ok, better just Base64 encode as a String... if (offset > 0 || (offset + len) != data.length) { data = Arrays.copyOfRange(data, offset, offset + len); } String encoded = b64variant.encode(data); if (_arraySeparator >= 0) { _addToArray(encoded); } else { _writer.write(_columnIndex(), encoded); } } }