// 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);
      }
    }
  }
Example #2
0
  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);
      }
    }
  }