in java/fury-format/src/main/java/org/apache/fury/format/encoder/Encoders.java [132:219]
public static <T> RowEncoder<T> bean(Class<T> beanClass, BinaryRowWriter writer, Fury fury) {
Schema schema = writer.getSchema();
try {
Class<?> rowCodecClass = loadOrGenRowCodecClass(beanClass);
Object references = new Object[] {schema, writer, fury};
GeneratedRowEncoder codec =
rowCodecClass
.asSubclass(GeneratedRowEncoder.class)
.getConstructor(Object[].class)
.newInstance(references);
long schemaHash = DataTypes.computeSchemaHash(schema);
return new RowEncoder<T>() {
private final MemoryBuffer buffer = MemoryUtils.buffer(16);
@Override
public Schema schema() {
return schema;
}
@SuppressWarnings("unchecked")
@Override
public T fromRow(BinaryRow row) {
return (T) codec.fromRow(row);
}
@Override
public BinaryRow toRow(T obj) {
return codec.toRow(obj);
}
@Override
public T decode(MemoryBuffer buffer) {
return decode(buffer, buffer.readInt32());
}
public T decode(MemoryBuffer buffer, int size) {
long peerSchemaHash = buffer.readInt64();
if (peerSchemaHash != schemaHash) {
throw new ClassNotCompatibleException(
String.format(
"Schema is not consistent, encoder schema is %s. "
+ "self/peer schema hash are %s/%s. "
+ "Please check writer schema.",
schema, schemaHash, peerSchemaHash));
}
BinaryRow row = new BinaryRow(schema);
row.pointTo(buffer, buffer.readerIndex(), size);
buffer.increaseReaderIndex(size - 8);
return fromRow(row);
}
@Override
public T decode(byte[] bytes) {
return decode(MemoryUtils.wrap(bytes), bytes.length);
}
@Override
public byte[] encode(T obj) {
buffer.writerIndex(0);
buffer.writeInt64(schemaHash);
writer.setBuffer(buffer);
writer.reset();
BinaryRow row = toRow(obj);
return buffer.getBytes(0, 8 + row.getSizeInBytes());
}
@Override
public void encode(MemoryBuffer buffer, T obj) {
int writerIndex = buffer.writerIndex();
buffer.writeInt32(-1);
try {
buffer.writeInt64(schemaHash);
writer.setBuffer(buffer);
writer.reset();
toRow(obj);
buffer.putInt32(writerIndex, buffer.writerIndex() - writerIndex - 4);
} finally {
writer.setBuffer(this.buffer);
}
}
};
} catch (Exception e) {
String msg = String.format("Create encoder failed, \nbeanClass: %s", beanClass);
throw new EncoderException(msg, e);
}
}