
com.tangosol.io.pof.PofParser Maven / Gradle / Ivy
/*
* Copyright (c) 2000, 2020, Oracle and/or its affiliates.
*
* Licensed under the Universal Permissive License v 1.0 as shown at
* http://oss.oracle.com/licenses/upl.
*/
package com.tangosol.io.pof;
import com.tangosol.io.ByteArrayReadBuffer;
import com.tangosol.io.ReadBuffer;
import java.io.IOException;
/**
* A "push" parser (event-based parser) for ripping through a POF stream and
* delivering the contents as events to a PofHandler object.
*
* @author cp 2006.07.12
*
* @since Coherence 3.2
*/
public class PofParser
extends PofHelper
implements PofConstants
{
// ----- constructors ---------------------------------------------------
/**
* Construct a POF parser that will push events to the specified handler.
*
* @param handler a POF handler object
*/
public PofParser(PofHandler handler)
{
m_handler = handler;
}
// ----- public API -----------------------------------------------------
/**
* Parse a POF value that is in the passed BufferInput.
*
* @param in the BufferInput to read the POF value from
*/
public void parse(ReadBuffer.BufferInput in)
{
try
{
parseValue(in, -1);
}
catch (IOException e)
{
throw ensureRuntimeException(e);
}
}
// ----- internal -------------------------------------------------------
/**
* Within the POF stream, parse a POF value that is in the passed
* BufferInput.
*
* @param in the BufferInput to read from
* @param iPos the position of the value that is about to be read, which
* is a property index, an array index, or -1
*
* @throws IOException if an I/O error occurs
*/
protected void parseValue(ReadBuffer.BufferInput in, int iPos)
throws IOException
{
int nType = in.readPackedInt();
if (nType == T_IDENTITY)
{
m_handler.registerIdentity(in.readPackedInt());
nType = in.readPackedInt();
}
parseUniformValue(in, iPos, nType);
}
/**
* Within the POF stream, parse a POF value of the specified type that is
* in the passed BufferInput.
*
* @param in the BufferInput to read from
* @param iPos the position of the value that is about to be read, which
* is a property index, an array index, or -1
* @param nType the Type ID to parse
*
* @throws IOException if an I/O error occurs
*/
protected void parseUniformValue(ReadBuffer.BufferInput in, int iPos, int nType)
throws IOException
{
if (nType >= 0)
{
parseUserType(in, iPos, nType);
}
else
{
PofHandler handler = m_handler;
switch (nType)
{
case T_INT16: // int16
handler.onInt16(iPos, (short) in.readPackedInt());
break;
case T_INT32: // int32
handler.onInt32(iPos, in.readPackedInt());
break;
case T_INT64: // int64
handler.onInt64(iPos, in.readPackedLong());
break;
case T_INT128: // int128
handler.onInt128(iPos, readBigInteger(in));
break;
case T_FLOAT32: // float32
handler.onFloat32(iPos, in.readFloat());
break;
case T_FLOAT64: // float64
handler.onFloat64(iPos, in.readDouble());
break;
case T_FLOAT128: // float128*
handler.onFloat128(iPos, new RawQuad(in.readBuffer(16).toBinary()));
case T_DECIMAL32: // decimal32
handler.onDecimal32(iPos, readBigDecimal(in, 4));
break;
case T_DECIMAL64: // decimal64
handler.onDecimal64(iPos, readBigDecimal(in, 8));
break;
case T_DECIMAL128: // decimal128
handler.onDecimal128(iPos, readBigDecimal(in, 16));
break;
case T_BOOLEAN: // boolean
handler.onBoolean(iPos, in.readPackedInt() != 0);
break;
case T_OCTET: // octet
handler.onOctet(iPos, in.readUnsignedByte());
break;
case T_OCTET_STRING: // octet-string
{
int cb = in.readPackedInt();
int of = in.getOffset();
in.skipBytes(cb);
handler.onOctetString(iPos, in.getBuffer().toBinary(of, cb));
}
break;
case T_CHAR: // char
{
handler.onChar(iPos, readChar(in));
}
break;
case T_CHAR_STRING: // char-string
handler.onCharString(iPos, in.readSafeUTF());
break;
case T_DATE: // date
{
int nYear = in.readPackedInt();
int nMonth = in.readPackedInt();
int nDay = in.readPackedInt();
handler.onDate(iPos, nYear, nMonth, nDay);
}
break;
case T_YEAR_MONTH_INTERVAL: // year-month-interval
{
int cYears = in.readPackedInt();
int dMonths = in.readPackedInt();
handler.onYearMonthInterval(iPos, cYears, dMonths);
}
break;
case T_TIME: // time
{
int nHour = in.readPackedInt();
int nMinute = in.readPackedInt();
int nSecond = in.readPackedInt();
int nFraction = in.readPackedInt();
int nNanos = nFraction <= 0 ? -nFraction : nFraction * 1000000;
int nZoneType = in.readPackedInt();
if (nZoneType == 2)
{
int nHourOffset = in.readPackedInt();
int nMinuteOffset = in.readPackedInt();
handler.onTime(iPos, nHour, nMinute, nSecond,
nNanos, nHourOffset, nMinuteOffset);
}
else
{
assert nZoneType == 0 || nZoneType == 1;
boolean fUTC = nZoneType == 1;
handler.onTime(iPos, nHour, nMinute, nSecond,
nNanos, fUTC);
}
}
break;
case T_TIME_INTERVAL: // time-interval
{
int cHours = in.readPackedInt();
int cMinutes = in.readPackedInt();
int cSeconds = in.readPackedInt();
int cNanos = in.readPackedInt();
handler.onTimeInterval(iPos, cHours, cMinutes, cSeconds, cNanos);
}
break;
case T_DATETIME: // datetime
{
int nYear = in.readPackedInt();
int nMonth = in.readPackedInt();
int nDay = in.readPackedInt();
int nHour = in.readPackedInt();
int nMinute = in.readPackedInt();
int nSecond = in.readPackedInt();
int nFraction = in.readPackedInt();
int nNano = nFraction <= 0 ? -nFraction : nFraction * 1000000;
int nZoneType = in.readPackedInt();
if (nZoneType == 2)
{
int nHourOffset = in.readPackedInt();
int nMinuteOffset = in.readPackedInt();
handler.onDateTime(iPos, nYear, nMonth, nDay, nHour,
nMinute, nSecond, nNano, nHourOffset, nMinuteOffset);
}
else
{
assert nZoneType == 0 || nZoneType == 1;
boolean fUTC = nZoneType == 1;
handler.onDateTime(iPos, nYear, nMonth, nDay,
nHour, nMinute, nSecond, nNano, fUTC);
}
}
break;
case T_DAY_TIME_INTERVAL: // day-time-interval
{
int cDays = in.readPackedInt();
int cHours = in.readPackedInt();
int cMinutes = in.readPackedInt();
int cSeconds = in.readPackedInt();
int cNanos = in.readPackedInt();
handler.onDayTimeInterval(iPos, cDays, cHours, cMinutes,
cSeconds, cNanos);
}
break;
case T_COLLECTION: // collection
parseCollection(in, iPos);
break;
case T_UNIFORM_COLLECTION: // uniform-collection
parseUniformCollection(in, iPos);
break;
case T_ARRAY: // array
parseArray(in, iPos);
break;
case T_UNIFORM_ARRAY: // uniform-array
parseUniformArray(in, iPos);
break;
case T_SPARSE_ARRAY: // sparse-array
parseSparseArray(in, iPos);
break;
case T_UNIFORM_SPARSE_ARRAY: // uniform-sparse-array
parseUniformSparseArray(in, iPos);
break;
case T_MAP: // map
parseMap(in, iPos);
break;
case T_UNIFORM_KEYS_MAP: // uniform-keys-map
parseUniformKeysMap(in, iPos);
break;
case T_UNIFORM_MAP: // uniform-map
parseUniformMap(in, iPos);
break;
case T_IDENTITY: // identity
throw azzert();
case T_REFERENCE: // reference
handler.onIdentityReference(iPos, in.readPackedInt());
break;
case V_BOOLEAN_FALSE: // boolean:false
case V_BOOLEAN_TRUE: // boolean:true
handler.onBoolean(iPos, nType == V_BOOLEAN_TRUE);
break;
case V_STRING_ZERO_LENGTH: // string:zero-length
handler.onOctetString(iPos, BINARY_EMPTY);
break;
case V_COLLECTION_EMPTY: // collection:empty
handler.beginCollection(iPos, 0);
handler.endComplexValue();
break;
case V_REFERENCE_NULL: // reference:null
handler.onNullReference(iPos);
break;
case V_FP_POS_INFINITY: // floating-point:+infinity
handler.onFloat32(iPos, Float.POSITIVE_INFINITY);
break;
case V_FP_NEG_INFINITY: // floating-point:-infinity
handler.onFloat32(iPos, Float.NEGATIVE_INFINITY);
break;
case V_FP_NAN: // floating-point:NaN
handler.onFloat32(iPos, Float.NaN);
break;
case V_INT_NEG_1: // int:-1
case V_INT_0: // int:0
case V_INT_1: // int:1
case V_INT_2: // int:2
case V_INT_3: // int:3
case V_INT_4: // int:4
case V_INT_5: // int:5
case V_INT_6: // int:6
case V_INT_7: // int:7
case V_INT_8: // int:8
case V_INT_9: // int:9
case V_INT_10: // int:10
case V_INT_11: // int:11
case V_INT_12: // int:12
case V_INT_13: // int:13
case V_INT_14: // int:14
case V_INT_15: // int:15
case V_INT_16: // int:16
case V_INT_17: // int:17
case V_INT_18: // int:18
case V_INT_19: // int:19
case V_INT_20: // int:20
case V_INT_21: // int:21
case V_INT_22: // int:22
handler.onInt32(iPos, V_INT_0 - nType);
break;
default:
azzert();
}
}
}
/**
* Parse a User Type from the POF stream.
*
* @param in the BufferInput to read from
* @param iPos the position of the value that is about to be read, which
* is a property index, an array index, or -1
* @param nType the Type ID for the User Type
*
* @throws IOException if an I/O error occurs
*/
protected void parseUserType(ReadBuffer.BufferInput in, int iPos, int nType)
throws IOException
{
PofHandler handler = m_handler;
handler.beginUserType(iPos, nType, in.readPackedInt());
while (true)
{
int iProp = in.readPackedInt();
if (iProp < 0)
{
handler.endComplexValue();
break;
}
else
{
parseValue(in, iProp);
}
}
}
/**
* Parse a Collection from the POF stream.
*
* @param in the BufferInput to read from
* @param iPos the position of the value that is about to be read, which
* is a property index, an array index, or -1
*
* @throws IOException if an I/O error occurs
*/
protected void parseCollection(ReadBuffer.BufferInput in, int iPos)
throws IOException
{
int cElements = in.readPackedInt();
PofHandler handler = m_handler;
handler.beginCollection(iPos, cElements);
for (int i = 0; i < cElements; ++i)
{
parseValue(in, i);
}
handler.endComplexValue();
}
/**
* Parse a Uniform Collection from the POF stream.
*
* @param in the BufferInput to read from
* @param iPos the position of the value that is about to be read, which
* is a property index, an array index, or -1
*
* @throws IOException if an I/O error occurs
*/
protected void parseUniformCollection(ReadBuffer.BufferInput in, int iPos)
throws IOException
{
int nType = in.readPackedInt();
int cElements = in.readPackedInt();
PofHandler handler = m_handler;
handler.beginUniformCollection(iPos, cElements, nType);
for (int i = 0; i < cElements; ++i)
{
parseUniformValue(in, i, nType);
}
handler.endComplexValue();
}
/**
* Parse an Array from the POF stream.
*
* @param in the BufferInput to read from
* @param iPos the position of the value that is about to be read, which
* is a property index, an array index, or -1
*
* @throws IOException if an I/O error occurs
*/
protected void parseArray(ReadBuffer.BufferInput in, int iPos)
throws IOException
{
int cElements = in.readPackedInt();
PofHandler handler = m_handler;
handler.beginArray(iPos, cElements);
for (int i = 0; i < cElements; ++i)
{
parseValue(in, i);
}
handler.endComplexValue();
}
/**
* Parse a Uniform Array from the POF stream.
*
* @param in the BufferInput to read from
* @param iPos the position of the value that is about to be read, which
* is a property index, an array index, or -1
*
* @throws IOException if an I/O error occurs
*/
protected void parseUniformArray(ReadBuffer.BufferInput in, int iPos)
throws IOException
{
int nType = in.readPackedInt();
int cElements = in.readPackedInt();
PofHandler handler = m_handler;
handler.beginUniformArray(iPos, cElements, nType);
for (int i = 0; i < cElements; ++i)
{
parseUniformValue(in, i, nType);
}
handler.endComplexValue();
}
/**
* Parse a Sparse Array from the POF stream.
*
* @param in the BufferInput to read from
* @param iPos the position of the value that is about to be read, which
* is a property index, an array index, or -1
*
* @throws IOException if an I/O error occurs
*/
protected void parseSparseArray(ReadBuffer.BufferInput in, int iPos)
throws IOException
{
int cElements = in.readPackedInt();
PofHandler handler = m_handler;
handler.beginSparseArray(iPos, cElements);
for (int i = 0; i < cElements; ++i)
{
int iArrayIndex = in.readPackedInt();
if (iArrayIndex < 0)
{
break;
}
parseValue(in, iArrayIndex);
}
handler.endComplexValue();
}
/**
* Parse a Uniform Sparse Array from the POF stream.
*
* @param in the BufferInput to read from
* @param iPos the position of the value that is about to be read, which
* is a property index, an array index, or -1
*
* @throws IOException if an I/O error occurs
*/
protected void parseUniformSparseArray(ReadBuffer.BufferInput in, int iPos)
throws IOException
{
int nType = in.readPackedInt();
int cElements = in.readPackedInt();
PofHandler handler = m_handler;
handler.beginUniformSparseArray(iPos, cElements, nType);
for (int i = 0; i < cElements; ++i)
{
int iArrayIndex = in.readPackedInt();
if (iArrayIndex < 0)
{
break;
}
parseUniformValue(in, iArrayIndex, nType);
}
handler.endComplexValue();
}
/**
* Parse a Map from the POF stream.
*
* @param in the BufferInput to read from
* @param iPos the position of the value that is about to be read, which
* is a property index, an array index, or -1
*
* @throws IOException if an I/O error occurs
*/
protected void parseMap(ReadBuffer.BufferInput in, int iPos)
throws IOException
{
int cElements = in.readPackedInt();
PofHandler handler = m_handler;
handler.beginMap(iPos, cElements);
for (int i = 0; i < cElements; ++i)
{
parseValue(in, i);
parseValue(in, i);
}
handler.endComplexValue();
}
/**
* Parse a Uniform-Keys Map from the POF stream.
*
* @param in the BufferInput to read from
* @param iPos the position of the value that is about to be read, which
* is a property index, an array index, or -1
*
* @throws IOException if an I/O error occurs
*/
protected void parseUniformKeysMap(ReadBuffer.BufferInput in, int iPos)
throws IOException
{
int nTypeKeys = in.readPackedInt();
int cElements = in.readPackedInt();
PofHandler handler = m_handler;
handler.beginUniformKeysMap(iPos, cElements, nTypeKeys);
for (int i = 0; i < cElements; ++i)
{
parseUniformValue(in, i, nTypeKeys);
parseValue(in, i);
}
handler.endComplexValue();
}
/**
* Parse a Uniform Map from the POF stream.
*
* @param in the BufferInput to read from
* @param iPos the position of the value that is about to be read, which
* is a property index, an array index, or -1
*
* @throws IOException if an I/O error occurs
*/
protected void parseUniformMap(ReadBuffer.BufferInput in, int iPos)
throws IOException
{
int nTypeKeys = in.readPackedInt();
int nTypeVals = in.readPackedInt();
int cElements = in.readPackedInt();
PofHandler handler = m_handler;
handler.beginUniformMap(iPos, cElements, nTypeKeys, nTypeVals);
for (int i = 0; i < cElements; ++i)
{
parseUniformValue(in, i, nTypeKeys);
parseUniformValue(in, i, nTypeVals);
}
handler.endComplexValue();
}
// ----- unit test ------------------------------------------------------
/**
* Unit test:
*
* java PofParser <hex string>
*
*
* @param asArg command line arguments
*
* @throws Exception if an error occurs
*/
public static void main(String[] asArg) throws Exception
{
if (asArg.length > 0)
{
ReadBuffer.BufferInput in = new ByteArrayReadBuffer(
parseHex(asArg[0])).getBufferInput();
new PofParser(new LoggingPofHandler()).parse(in);
}
}
// ----- data members ---------------------------------------------------
/**
* The PofHandler to deliver events to.
*/
private PofHandler m_handler;
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy