org.codehaus.jackson.impl.ReaderBasedParserBase Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ehcache Show documentation
Show all versions of ehcache Show documentation
Ehcache is an open source, standards-based cache used to boost performance,
offload the database and simplify scalability. Ehcache is robust, proven and full-featured and
this has made it the most widely-used Java-based cache.
package org.codehaus.jackson.impl;
import java.io.*;
import org.codehaus.jackson.*;
import org.codehaus.jackson.io.IOContext;
/**
* This is a simple low-level input reader base class, used by
* JSON parser.
* The reason for sub-classing (over composition)
* is due to need for direct access to character buffers
* and positions.
*
* @author Tatu Saloranta
*
* @deprecated Since 1.9 sub-classes should just include code
* from here as is.
*/
@Deprecated
public abstract class ReaderBasedParserBase
extends JsonParserBase
{
/*
/**********************************************************
/* Configuration
/**********************************************************
*/
/**
* Reader that can be used for reading more content, if one
* buffer from input source, but in some cases pre-loaded buffer
* is handed to the parser.
*/
protected Reader _reader;
/*
/**********************************************************
/* Current input data
/**********************************************************
*/
/**
* Current buffer from which data is read; generally data is read into
* buffer from input source.
*/
protected char[] _inputBuffer;
/*
/**********************************************************
/* Life-cycle
/**********************************************************
*/
protected ReaderBasedParserBase(IOContext ctxt, int features, Reader r)
{
super(ctxt, features);
_reader = r;
_inputBuffer = ctxt.allocTokenBuffer();
}
/*
/**********************************************************
/* Overrides
/**********************************************************
*/
@Override
public int releaseBuffered(Writer w) throws IOException
{
int count = _inputEnd - _inputPtr;
if (count < 1) {
return 0;
}
// let's just advance ptr to end
int origPtr = _inputPtr;
w.write(_inputBuffer, origPtr, count);
return count;
}
@Override
public Object getInputSource() {
return _reader;
}
/*
/**********************************************************
/* Low-level reading, other
/**********************************************************
*/
@Override
protected final boolean loadMore() throws IOException
{
_currInputProcessed += _inputEnd;
_currInputRowStart -= _inputEnd;
if (_reader != null) {
int count = _reader.read(_inputBuffer, 0, _inputBuffer.length);
if (count > 0) {
_inputPtr = 0;
_inputEnd = count;
return true;
}
// End of input
_closeInput();
// Should never return 0, so let's fail
if (count == 0) {
throw new IOException("Reader returned 0 characters when trying to read "+_inputEnd);
}
}
return false;
}
protected char getNextChar(String eofMsg)
throws IOException, JsonParseException
{
if (_inputPtr >= _inputEnd) {
if (!loadMore()) {
_reportInvalidEOF(eofMsg);
}
}
return _inputBuffer[_inputPtr++];
}
@Override
protected void _closeInput() throws IOException
{
/* 25-Nov-2008, tatus: As per [JACKSON-16] we are not to call close()
* on the underlying Reader, unless we "own" it, or auto-closing
* feature is enabled.
* One downside is that when using our optimized
* Reader (granted, we only do that for UTF-32...) this
* means that buffer recycling won't work correctly.
*/
if (_reader != null) {
if (_ioContext.isResourceManaged() || isEnabled(Feature.AUTO_CLOSE_SOURCE)) {
_reader.close();
}
_reader = null;
}
}
/**
* Method called to release internal buffers owned by the base
* reader. This may be called along with {@link #_closeInput} (for
* example, when explicitly closing this reader instance), or
* separately (if need be).
*/
@Override
protected void _releaseBuffers()
throws IOException
{
super._releaseBuffers();
char[] buf = _inputBuffer;
if (buf != null) {
_inputBuffer = null;
_ioContext.releaseTokenBuffer(buf);
}
}
/*
/**********************************************************
/* Helper methods for subclasses
/**********************************************************
*/
/**
* Helper method for checking whether input matches expected token
*
* @since 1.8
*/
protected final boolean _matchToken(String matchStr, int i)
throws IOException, JsonParseException
{
final int len = matchStr.length();
do {
if (_inputPtr >= _inputEnd) {
if (!loadMore()) {
_reportInvalidEOFInValue();
}
}
if (_inputBuffer[_inputPtr] != matchStr.charAt(i)) {
_reportInvalidToken(matchStr.substring(0, i), "'null', 'true', 'false' or NaN");
}
++_inputPtr;
} while (++i < len);
// but let's also ensure we either get EOF, or non-alphanum char...
if (_inputPtr >= _inputEnd) {
if (!loadMore()) {
return true;
}
}
char c = _inputBuffer[_inputPtr];
// if Java letter, it's a problem tho
if (Character.isJavaIdentifierPart(c)) {
++_inputPtr;
_reportInvalidToken(matchStr.substring(0, i), "'null', 'true', 'false' or NaN");
}
return true;
}
protected void _reportInvalidToken(String matchedPart, String msg)
throws IOException, JsonParseException
{
StringBuilder sb = new StringBuilder(matchedPart);
/* Let's just try to find what appears to be the token, using
* regular Java identifier character rules. It's just a heuristic,
* nothing fancy here.
*/
while (true) {
if (_inputPtr >= _inputEnd) {
if (!loadMore()) {
break;
}
}
char c = _inputBuffer[_inputPtr];
if (!Character.isJavaIdentifierPart(c)) {
break;
}
++_inputPtr;
sb.append(c);
}
_reportError("Unrecognized token '"+sb.toString()+"': was expecting ");
}
}