下面列出了com.fasterxml.jackson.core.util.BufferRecycler#com.fasterxml.jackson.core.util.ByteArrayBuilder 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Method for accessing textual contents assuming they were
* base64 encoded; if so, they are decoded and resulting binary
* data is returned.
*/
@SuppressWarnings("resource")
public byte[] getBinaryValue(Base64Variant b64variant) throws IOException
{
final String str = _value.trim();
ByteArrayBuilder builder = new ByteArrayBuilder(4 + ((str.length() * 3) << 2));
try {
b64variant.decode(str, builder);
} catch (IllegalArgumentException e) {
throw InvalidFormatException.from(null,
String.format(
"Cannot access contents of TextNode as binary due to broken Base64 encoding: %s",
e.getMessage()),
str, byte[].class);
}
return builder.toByteArray();
}
private int _appendByte(int ch, int esc, ByteArrayBuilder bb, int ptr)
{
bb.setCurrentSegmentLength(ptr);
bb.append('\\');
if (esc < 0) { // standard escape
bb.append('u');
if (ch > 0xFF) {
int hi = (ch >> 8);
bb.append(HB[hi >> 4]);
bb.append(HB[hi & 0xF]);
ch &= 0xFF;
} else {
bb.append('0');
bb.append('0');
}
bb.append(HB[ch >> 4]);
bb.append(HB[ch & 0xF]);
} else { // 2-char simple escape
bb.append((byte) esc);
}
return bb.getCurrentSegmentLength();
}
private int _appendByte(int ch, int esc, ByteArrayBuilder bb, int ptr)
{
bb.setCurrentSegmentLength(ptr);
bb.append('\\');
if (esc < 0) { // standard escape
bb.append('u');
if (ch > 0xFF) {
int hi = (ch >> 8);
bb.append(HB[hi >> 4]);
bb.append(HB[hi & 0xF]);
ch &= 0xFF;
} else {
bb.append('0');
bb.append('0');
}
bb.append(HB[ch >> 4]);
bb.append(HB[ch & 0xF]);
} else { // 2-char simple escape
bb.append((byte) esc);
}
return bb.getCurrentSegmentLength();
}
protected ContentChunk toJsonChunk(Object data, boolean stream){
try {
ByteArrayBuilder byteArrayBuilder = new ByteArrayBuilder();
bodyWriter.writeValue(byteArrayBuilder, data);
if(stream) {
byteArrayBuilder.write(NEWLINE_SEPARATOR);
}
ByteBuffer buffer = ByteBuffer.wrap(byteArrayBuilder.toByteArray());
return new ContentChunk(buffer);
} catch (java.io.IOException e) {
throw new UncheckedIOException(e);
}
}
@Override
@SuppressWarnings("resource")
public byte[] getBinaryValue(Base64Variant b64variant) throws IOException, JsonParseException
{
// First: maybe we some special types?
if (_currToken == JsonToken.VALUE_EMBEDDED_OBJECT) {
// Embedded byte array would work nicely...
Object ob = _currentObject();
if (ob instanceof byte[]) {
return (byte[]) ob;
}
// fall through to error case
}
if (_currToken != JsonToken.VALUE_STRING) {
throw _constructError("Current token ("+_currToken+") not VALUE_STRING (or VALUE_EMBEDDED_OBJECT with byte[]), cannot access as binary");
}
final String str = getText();
if (str == null) {
return null;
}
ByteArrayBuilder builder = _byteBuilder;
if (builder == null) {
_byteBuilder = builder = new ByteArrayBuilder(100);
} else {
_byteBuilder.reset();
}
_decodeBase64(str, builder, b64variant);
return builder.toByteArray();
}
@SuppressWarnings("resource")
@Override // since 2.7
public byte[] getBinaryValue(Base64Variant variant) throws IOException
{
if (_binaryValue == null) {
if (_currToken != JsonToken.VALUE_STRING) {
_reportError("Current token ("+_currToken+") not VALUE_STRING, can not access as binary");
}
ByteArrayBuilder builder = _getByteArrayBuilder();
_decodeBase64(getText(), builder, variant);
_binaryValue = builder.toByteArray();
}
return _binaryValue;
}
/**
* Helper method that can be used for base64 decoding in cases where
* encoded content has already been read as a String.
*/
protected void _decodeBase64(String str, ByteArrayBuilder builder, Base64Variant b64variant) throws IOException
{
try {
b64variant.decode(str, builder);
} catch (IllegalArgumentException e) {
_reportError(e.getMessage());
}
}
@Override
public byte[] getBinaryValue(Base64Variant b64variant) throws IOException
{
if (_currToken != JsonToken.VALUE_STRING) {
_reportError("Current token (%s) not VALUE_STRING or VALUE_EMBEDDED_OBJECT, can not access as binary",
_currToken);
}
if (_binaryValue == null) {
@SuppressWarnings("resource")
ByteArrayBuilder builder = _getByteArrayBuilder();
_decodeBase64(getText(), builder, b64variant);
_binaryValue = builder.toByteArray();
}
return _binaryValue;
}
/**
* Converts a {@link Message} into JSON as UTF-8 encoded bytes.
*
* @throws InvalidProtocolBufferException if there are unknown Any types in the message.
*/
public <T extends Message> byte[] writeValueAsBytes(T message) throws IOException {
checkNotNull(message, "message");
ByteArrayBuilder builder = new ByteArrayBuilder(jsonFactory._getBufferRecycler());
try (JsonGenerator gen = jsonFactory.createGenerator(builder)) {
writeValue(message, gen);
}
return builder.toByteArray();
}
/**
* Helper method that can be used for base64 decoding in cases where
* encoded content has already been read as a String.
*/
protected void _decodeBase64(String str, ByteArrayBuilder builder, Base64Variant b64variant) throws IOException
{
// just call helper method introduced in 2.2.3
try {
b64variant.decode(str, builder);
} catch (IllegalArgumentException e) {
_reportError(e.getMessage());
}
}
private byte[] serializeToBytes(T value, ObjectMapper mapper, SerializerProvider provider) throws IOException {
try (ByteArrayBuilder array = new ByteArrayBuilder(new BufferRecycler())) {
if (trySerialzieToArray(value, mapper, provider, array)) {
byte[] result = array.toByteArray();
array.release();
return result;
}
}
// fallback on old behavior
return mapper.writeValueAsBytes(value);
}
protected JSONComposer(int features, JsonGenerator gen, ByteArrayBuilder w)
{
super(gen);
_features = features;
_stringWriter = null;
_byteWriter = w;
_closeGenerator = true;
}
private byte[] writeInMemory() {
try (ByteArrayBuilder byteArrayBuilder = new ByteArrayBuilder()) {
JsonLoadFlowParameters.write(this, byteArrayBuilder);
return byteArrayBuilder.toByteArray();
}
}
/**
* Convenience method for decoding contents of a Base64-encoded String,
* using this variant's settings
* and appending decoded binary data using provided {@link ByteArrayBuilder}.
*<p>
* NOTE: builder will NOT be reset before decoding (nor cleared afterwards);
* assumption is that caller will ensure it is given in proper state, and
* used as appropriate afterwards.
*
* @since 2.3
*
* @throws IllegalArgumentException if input is not valid base64 encoded data
*/
public void decode(String str, ByteArrayBuilder builder) throws IllegalArgumentException
{
int ptr = 0;
int len = str.length();
main_loop:
while (true) {
// first, we'll skip preceding white space, if any
char ch;
do {
if (ptr >= len) {
break main_loop;
}
ch = str.charAt(ptr++);
} while (ch <= INT_SPACE);
int bits = decodeBase64Char(ch);
if (bits < 0) {
_reportInvalidBase64(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 = decodeBase64Char(ch);
if (bits < 0) {
_reportInvalidBase64(ch, 1, null);
}
decodedData = (decodedData << 6) | bits;
// third base64 char; can be padding, but not ws
if (ptr >= len) {
// but as per [JACKSON-631] can be end-of-input, iff not using padding
if (!usesPadding()) {
decodedData >>= 4;
builder.append(decodedData);
break;
}
_reportBase64EOF();
}
ch = str.charAt(ptr++);
bits = decodeBase64Char(ch);
// First branch: can get padding (-> 1 byte)
if (bits < 0) {
if (bits != Base64Variant.BASE64_VALUE_PADDING) {
_reportInvalidBase64(ch, 2, null);
}
// Ok, must get padding
if (ptr >= len) {
_reportBase64EOF();
}
ch = str.charAt(ptr++);
if (!usesPaddingChar(ch)) {
_reportInvalidBase64(ch, 3, "expected padding character '"+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) {
// but as per [JACKSON-631] can be end-of-input, iff not using padding
if (!usesPadding()) {
decodedData >>= 2;
builder.appendTwoBytes(decodedData);
break;
}
_reportBase64EOF();
}
ch = str.charAt(ptr++);
bits = decodeBase64Char(ch);
if (bits < 0) {
if (bits != Base64Variant.BASE64_VALUE_PADDING) {
_reportInvalidBase64(ch, 3, null);
}
decodedData >>= 2;
builder.appendTwoBytes(decodedData);
} else {
// otherwise, our triple is now complete
decodedData = (decodedData << 6) | bits;
builder.appendThreeBytes(decodedData);
}
}
}
/**
* Will encode given String as UTF-8 (without any quoting), return
* resulting byte array.
*/
@SuppressWarnings("resource")
public byte[] encodeAsUTF8(String text)
{
ByteArrayBuilder byteBuilder = _bytes;
if (byteBuilder == null) {
// no allocator; can add if we must, shouldn't need to
_bytes = byteBuilder = new ByteArrayBuilder(null);
}
int inputPtr = 0;
int inputEnd = text.length();
int outputPtr = 0;
byte[] outputBuffer = byteBuilder.resetAndGetFirstSegment();
int outputEnd = outputBuffer.length;
main_loop:
while (inputPtr < inputEnd) {
int c = text.charAt(inputPtr++);
// first tight loop for ascii
while (c <= 0x7F) {
if (outputPtr >= outputEnd) {
outputBuffer = byteBuilder.finishCurrentSegment();
outputEnd = outputBuffer.length;
outputPtr = 0;
}
outputBuffer[outputPtr++] = (byte) c;
if (inputPtr >= inputEnd) {
break main_loop;
}
c = text.charAt(inputPtr++);
}
// then multi-byte...
if (outputPtr >= outputEnd) {
outputBuffer = byteBuilder.finishCurrentSegment();
outputEnd = outputBuffer.length;
outputPtr = 0;
}
if (c < 0x800) { // 2-byte
outputBuffer[outputPtr++] = (byte) (0xc0 | (c >> 6));
} else { // 3 or 4 bytes
// Surrogates?
if (c < SURR1_FIRST || c > SURR2_LAST) { // nope
outputBuffer[outputPtr++] = (byte) (0xe0 | (c >> 12));
if (outputPtr >= outputEnd) {
outputBuffer = byteBuilder.finishCurrentSegment();
outputEnd = outputBuffer.length;
outputPtr = 0;
}
outputBuffer[outputPtr++] = (byte) (0x80 | ((c >> 6) & 0x3f));
} else { // yes, surrogate pair
if (c > SURR1_LAST) { // must be from first range
_illegal(c);
}
// and if so, followed by another from next range
if (inputPtr >= inputEnd) {
_illegal(c);
}
c = _convert(c, text.charAt(inputPtr++));
if (c > 0x10FFFF) { // illegal, as per RFC 4627
_illegal(c);
}
outputBuffer[outputPtr++] = (byte) (0xf0 | (c >> 18));
if (outputPtr >= outputEnd) {
outputBuffer = byteBuilder.finishCurrentSegment();
outputEnd = outputBuffer.length;
outputPtr = 0;
}
outputBuffer[outputPtr++] = (byte) (0x80 | ((c >> 12) & 0x3f));
if (outputPtr >= outputEnd) {
outputBuffer = byteBuilder.finishCurrentSegment();
outputEnd = outputBuffer.length;
outputPtr = 0;
}
outputBuffer[outputPtr++] = (byte) (0x80 | ((c >> 6) & 0x3f));
}
}
if (outputPtr >= outputEnd) {
outputBuffer = byteBuilder.finishCurrentSegment();
outputEnd = outputBuffer.length;
outputPtr = 0;
}
outputBuffer[outputPtr++] = (byte) (0x80 | (c & 0x3f));
}
return _bytes.completeAndCoalesce(outputPtr);
}
/**
* Convenience method for decoding contents of a Base64-encoded String,
* using this variant's settings
* and appending decoded binary data using provided {@link ByteArrayBuilder}.
*<p>
* NOTE: builder will NOT be reset before decoding (nor cleared afterwards);
* assumption is that caller will ensure it is given in proper state, and
* used as appropriate afterwards.
*
* @since 2.2.3
*
* @throws IllegalArgumentException if input is not valid base64 encoded data
*/
public void decode(String str, ByteArrayBuilder builder) throws IllegalArgumentException
{
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 = decodeBase64Char(ch);
if (bits < 0) {
_reportInvalidBase64(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 = decodeBase64Char(ch);
if (bits < 0) {
_reportInvalidBase64(ch, 1, null);
}
decodedData = (decodedData << 6) | bits;
// third base64 char; can be padding, but not ws
if (ptr >= len) {
// but as per [JACKSON-631] can be end-of-input, iff not using padding
if (!usesPadding()) {
decodedData >>= 4;
builder.append(decodedData);
break;
}
_reportBase64EOF();
}
ch = str.charAt(ptr++);
bits = decodeBase64Char(ch);
// First branch: can get padding (-> 1 byte)
if (bits < 0) {
if (bits != Base64Variant.BASE64_VALUE_PADDING) {
_reportInvalidBase64(ch, 2, null);
}
// Ok, must get padding
if (ptr >= len) {
_reportBase64EOF();
}
ch = str.charAt(ptr++);
if (!usesPaddingChar(ch)) {
_reportInvalidBase64(ch, 3, "expected padding character '"+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) {
// but as per [JACKSON-631] can be end-of-input, iff not using padding
if (!usesPadding()) {
decodedData >>= 2;
builder.appendTwoBytes(decodedData);
break;
}
_reportBase64EOF();
}
ch = str.charAt(ptr++);
bits = decodeBase64Char(ch);
if (bits < 0) {
if (bits != Base64Variant.BASE64_VALUE_PADDING) {
_reportInvalidBase64(ch, 3, null);
}
decodedData >>= 2;
builder.appendTwoBytes(decodedData);
} else {
// otherwise, our triple is now complete
decodedData = (decodedData << 6) | bits;
builder.appendThreeBytes(decodedData);
}
}
}
/**
* Will encode given String as UTF-8 (without any quoting), return
* resulting byte array.
*/
@SuppressWarnings("resource")
public byte[] encodeAsUTF8(String text)
{
ByteArrayBuilder byteBuilder = _bytes;
if (byteBuilder == null) {
// no allocator; can add if we must, shouldn't need to
_bytes = byteBuilder = new ByteArrayBuilder(null);
}
int inputPtr = 0;
int inputEnd = text.length();
int outputPtr = 0;
byte[] outputBuffer = byteBuilder.resetAndGetFirstSegment();
int outputEnd = outputBuffer.length;
main_loop:
while (inputPtr < inputEnd) {
int c = text.charAt(inputPtr++);
// first tight loop for ascii
while (c <= 0x7F) {
if (outputPtr >= outputEnd) {
outputBuffer = byteBuilder.finishCurrentSegment();
outputEnd = outputBuffer.length;
outputPtr = 0;
}
outputBuffer[outputPtr++] = (byte) c;
if (inputPtr >= inputEnd) {
break main_loop;
}
c = text.charAt(inputPtr++);
}
// then multi-byte...
if (outputPtr >= outputEnd) {
outputBuffer = byteBuilder.finishCurrentSegment();
outputEnd = outputBuffer.length;
outputPtr = 0;
}
if (c < 0x800) { // 2-byte
outputBuffer[outputPtr++] = (byte) (0xc0 | (c >> 6));
} else { // 3 or 4 bytes
// Surrogates?
if (c < SURR1_FIRST || c > SURR2_LAST) { // nope
outputBuffer[outputPtr++] = (byte) (0xe0 | (c >> 12));
if (outputPtr >= outputEnd) {
outputBuffer = byteBuilder.finishCurrentSegment();
outputEnd = outputBuffer.length;
outputPtr = 0;
}
outputBuffer[outputPtr++] = (byte) (0x80 | ((c >> 6) & 0x3f));
} else { // yes, surrogate pair
if (c > SURR1_LAST) { // must be from first range
_illegal(c);
}
// and if so, followed by another from next range
if (inputPtr >= inputEnd) {
_illegal(c);
}
c = _convert(c, text.charAt(inputPtr++));
if (c > 0x10FFFF) { // illegal, as per RFC 4627
_illegal(c);
}
outputBuffer[outputPtr++] = (byte) (0xf0 | (c >> 18));
if (outputPtr >= outputEnd) {
outputBuffer = byteBuilder.finishCurrentSegment();
outputEnd = outputBuffer.length;
outputPtr = 0;
}
outputBuffer[outputPtr++] = (byte) (0x80 | ((c >> 12) & 0x3f));
if (outputPtr >= outputEnd) {
outputBuffer = byteBuilder.finishCurrentSegment();
outputEnd = outputBuffer.length;
outputPtr = 0;
}
outputBuffer[outputPtr++] = (byte) (0x80 | ((c >> 6) & 0x3f));
}
}
if (outputPtr >= outputEnd) {
outputBuffer = byteBuilder.finishCurrentSegment();
outputEnd = outputBuffer.length;
outputPtr = 0;
}
outputBuffer[outputPtr++] = (byte) (0x80 | (c & 0x3f));
}
return _bytes.completeAndCoalesce(outputPtr);
}
private boolean trySerialzieToArray(T value, ObjectMapper mapper, SerializerProvider provider, ByteArrayBuilder builder) throws IOException {
try (JsonGenerator gen = mapper.getFactory().createGenerator(builder, JsonEncoding.UTF8)) {
return trySerializeToGenerator(value, mapper, provider, gen);
}
}
public static JSONComposer<byte[]> bytesComposer(int features,
JsonGenerator gen, ByteArrayBuilder w) {
return new JSONComposer<byte[]>(features, gen, w);
}
public JSONComposer<byte[]> composeBytes() throws IOException, JSONObjectException {
ByteArrayBuilder out = new ByteArrayBuilder(_streamFactory._getBufferRecycler());
JsonGenerator gen = _config(_streamFactory.createGenerator(this, out));
return JSONComposer.bytesComposer(_features, gen, out);
}
/**
* Convenience method for decoding contents of a Base64-encoded String,
* using this variant's settings.
*
* @param input
*
* @since 2.2.3
*
* @throws IllegalArgumentException if input is not valid base64 encoded data
*/
@SuppressWarnings("resource")
public byte[] decode(String input) throws IllegalArgumentException
{
ByteArrayBuilder b = new ByteArrayBuilder();
decode(input, b);
return b.toByteArray();
}
/**
* Convenience method for decoding contents of a Base64-encoded String,
* using this variant's settings.
*
* @param input
*
* @since 2.2.3
*
* @throws IllegalArgumentException if input is not valid base64 encoded data
*/
@SuppressWarnings("resource")
public byte[] decode(String input) throws IllegalArgumentException
{
ByteArrayBuilder b = new ByteArrayBuilder();
decode(input, b);
return b.toByteArray();
}