in java/fury-format/src/main/java/org/apache/fury/format/encoder/Encoders.java [446:534]
public static <T extends Map, K, V> MapEncoder<T> mapEncoder(
TypeRef<? extends Map> mapToken, TypeRef<K> keyToken, TypeRef<V> valToken, Fury fury) {
Preconditions.checkNotNull(mapToken);
Preconditions.checkNotNull(keyToken);
Preconditions.checkNotNull(valToken);
Schema schema = TypeInference.inferSchema(mapToken, false);
Field field = DataTypes.fieldOfSchema(schema, 0);
Field keyField = DataTypes.keyArrayFieldForMap(field);
Field valField = DataTypes.itemArrayFieldForMap(field);
BinaryArrayWriter keyWriter = new BinaryArrayWriter(keyField);
BinaryArrayWriter valWriter = new BinaryArrayWriter(valField, keyWriter.getBuffer());
try {
Class<?> rowCodecClass = loadOrGenMapCodecClass(mapToken, keyToken, valToken);
Object references = new Object[] {keyField, valField, keyWriter, valWriter, fury, field};
GeneratedMapEncoder codec =
rowCodecClass
.asSubclass(GeneratedMapEncoder.class)
.getConstructor(Object[].class)
.newInstance(references);
return new MapEncoder<T>() {
@Override
public Field keyField() {
return keyField;
}
@Override
public Field valueField() {
return valField;
}
@SuppressWarnings("unchecked")
@Override
public T fromMap(BinaryArray key, BinaryArray value) {
return (T) codec.fromMap(key, value);
}
@Override
public BinaryMap toMap(T obj) {
return codec.toMap(obj);
}
@Override
public T decode(MemoryBuffer buffer) {
return decode(buffer, buffer.readInt32());
}
public T decode(MemoryBuffer buffer, int size) {
BinaryMap map = new BinaryMap(field);
int readerIndex = buffer.readerIndex();
map.pointTo(buffer, readerIndex, size);
buffer.readerIndex(readerIndex + size);
return fromMap(map);
}
@Override
public T decode(byte[] bytes) {
return decode(MemoryUtils.wrap(bytes), bytes.length);
}
@Override
public byte[] encode(T obj) {
BinaryMap map = toMap(obj);
return map.getBuf().getBytes(map.getBaseOffset(), map.getSizeInBytes());
}
@Override
public void encode(MemoryBuffer buffer, T obj) {
MemoryBuffer prevBuffer = keyWriter.getBuffer();
int writerIndex = buffer.writerIndex();
buffer.writeInt32(-1);
try {
keyWriter.setBuffer(buffer);
valWriter.setBuffer(buffer);
toMap(obj);
buffer.putInt32(writerIndex, buffer.writerIndex() - writerIndex - 4);
} finally {
keyWriter.setBuffer(prevBuffer);
valWriter.setBuffer(prevBuffer);
}
}
};
} catch (Exception e) {
String msg =
String.format("Create encoder failed, \nkeyType: %s, valueType: %s", keyToken, valToken);
throw new EncoderException(msg, e);
}
}