com.fasterxml.jackson.jr.private_.json.async.NonBlockingByteBufferJsonParser Maven / Gradle / Ivy
Show all versions of jackson-jr-all Show documentation
package com.fasterxml.jackson.core.json.async;
import com.fasterxml.jackson.core.async.ByteBufferFeeder;
import com.fasterxml.jackson.core.async.NonBlockingInputFeeder;
import com.fasterxml.jackson.core.io.IOContext;
import com.fasterxml.jackson.core.sym.ByteQuadsCanonicalizer;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.WritableByteChannel;
/**
* Non-blocking parser implementation for JSON content that takes its input
* via {@link java.nio.ByteBuffer} instance(s) passed.
*
* NOTE: only supports parsing of UTF-8 encoded content (and 7-bit US-ASCII since
* it is strict subset of UTF-8): other encodings are not supported.
*
* @since 2.14
*/
public class NonBlockingByteBufferJsonParser
extends NonBlockingUtf8JsonParserBase
implements ByteBufferFeeder
{
private ByteBuffer _inputBuffer = ByteBuffer.wrap(NO_BYTES);
public NonBlockingByteBufferJsonParser(IOContext ctxt, int parserFeatures,
ByteQuadsCanonicalizer sym) {
super(ctxt, parserFeatures, sym);
}
@Override
public NonBlockingInputFeeder getNonBlockingInputFeeder() {
return this;
}
@Override
public void feedInput(final ByteBuffer byteBuffer) throws IOException {
// Must not have remaining input
if (_inputPtr < _inputEnd) {
_reportError("Still have %d undecoded bytes, should not call 'feedInput'", _inputEnd - _inputPtr);
}
final int start = byteBuffer.position();
final int end = byteBuffer.limit();
if (end < start) {
_reportError("Input end (%d) may not be before start (%d)", end, start);
}
// and shouldn't have been marked as end-of-input
if (_endOfInput) {
_reportError("Already closed, can not feed more input");
}
// Time to update pointers first
_currInputProcessed += _origBufferLen;
// 06-Sep-2023, tatu: [core#1046] Enforce max doc length limit
_streamReadConstraints.validateDocumentLength(_currInputProcessed);
// Also need to adjust row start, to work as if it extended into the past wrt new buffer
_currInputRowStart = start - (_inputEnd - _currInputRowStart);
// And then update buffer settings
_currBufferStart = start;
_inputBuffer = byteBuffer;
_inputPtr = start;
_inputEnd = end;
_origBufferLen = end - start;
}
@Override
public int releaseBuffered(final OutputStream out) throws IOException {
final int avail = _inputEnd - _inputPtr;
if (avail > 0) {
final WritableByteChannel channel = Channels.newChannel(out);
channel.write(_inputBuffer);
}
return avail;
}
@Override
protected byte getNextSignedByteFromBuffer() {
return _inputBuffer.get(_inputPtr++);
}
@Override
protected int getNextUnsignedByteFromBuffer() {
return _inputBuffer.get(_inputPtr++) & 0xFF;
}
@Override
protected byte getByteFromBuffer(final int ptr) {
return _inputBuffer.get(ptr);
}
}