package de.jpaw.bonaparte.core;
import java.io.DataInput;
import java.io.EOFException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import de.jpaw.bonaparte.pojos.meta.NumericElementaryDataItem;
import de.jpaw.bonaparte.util.BigDecimalTools;
import de.jpaw.util.ByteArray;
public class CompactParser extends AbstractCompactParser<IOException> {
protected final DataInput in;
private int pushedBack = -1;
public static void deserialize(BonaPortable obj, DataInput _in) throws IOException {
obj.deserialize(new CompactParser(_in));
}
public CompactParser(DataInput in) {
super();
this.in = in;
}
/**************************************************************************************************
* Deserialization goes here. Code below does not use the ByteBuilder class,
* but reads from the byte[] directly
**************************************************************************************************/
@Override
protected IOException newMPE(int errorCode, String msg) {
return new IOException(String.format("Error " + errorCode + " in " + currentClass + ": " + msg));
}
@Override
protected BonaPortable createObject(String classname) throws IOException { // same method - overloading required for possible exception mapping
try {
return BonaPortableFactory.createObject(classname);
} catch (MessageParserException e) {
throw new IOException(e); // wrap exception
}
}
@Override
protected BigDecimal checkAndScale(BigDecimal num, NumericElementaryDataItem di) throws IOException {
try {
return BigDecimalTools.checkAndScale(num, di, -1, currentClass);
} catch (MessageParserException e) {
throw new IOException(e); // wrap exception
}
}
@Override
protected boolean atEnd() throws IOException {
try {
pushback(needToken()); // DataInput has no EOF method - specific types of DataInput could use better ways to determine end of input
} catch (EOFException e) {
return true;
}
return false;
}
@Override
protected int needToken() throws IOException {
if (pushedBack >= 0) {
int c = pushedBack;
pushedBack = -1;
return c;
}
return 0xff & in.readUnsignedByte(); // workaround hazelcast 3.4.0/1 bug
}
@Override
protected void needToken(int c) throws IOException {
int d = needToken();
if (c != d) {
throw new IOException(String.format("expected 0x%02x, got 0x%02x in class %s", c, d, currentClass));
}
}
@Override
protected void pushback(int c) {
pushedBack = c;
}
@Override
protected void skipBytes(int howMany) throws IOException {
in.skipBytes(howMany);
}
@Override
protected char readChar() throws IOException {
return in.readChar();
}
@Override
protected int readFixed2ByteInt() throws IOException {
return in.readShort();
}
@Override
protected int readFixed3ByteInt() throws IOException {
int nn = in.readByte() << 16; // does sign-extend as required
return nn | in.readUnsignedShort();
}
@Override
protected int readFixed4ByteInt() throws IOException {
return in.readInt();
}
@Override
protected long readFixed6ByteLong() throws IOException {
int nn1 = in.readShort();
return (long)nn1 << 32 | (in.readInt() & 0xffffffffL);
}
@Override
protected long readFixed8ByteLong() throws IOException {
return in.readLong();
}
@Override
protected byte [] readBytes(int len) throws IOException {
if (len == 0)
return EMPTY_BYTE_ARRAY;
byte [] data = new byte [len];
in.readFully(data);
return data;
}
@Override
protected ByteArray readByteArray(int len) throws IOException {
return ByteArray.fromDataInput(in, len);
}
@Override
protected String readISO(int len) throws IOException {
char data [] = new char [len];
for (int i = 0; i < len; ++i)
data[i] = (char)(0xff & in.readUnsignedByte()); // workaround hazelcast 3.4.x bug
return new String(data);
}
@Override
protected String readUTF16(int len) throws IOException {
char data [] = new char [len];
for (int i = 0; i < len; ++i)
data[i] = in.readChar();
return new String(data);
}
@Override
protected String readUTF8(int len) throws IOException {
final byte [] tmp = new byte [len];
in.readFully(tmp);
try {
return new String(tmp, CHARSET_UTF8);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e); // should never happen, CHARSET_UTF16 is guaranteed to exist
}
}
}