//------------------------------------------------- // Litchi Game Server Framework // Copyright(c) 2019 phantaci <[email protected]> // MIT Licensed //------------------------------------------------- package litchi.core.net.rpc.serializer; import io.protostuff.LinkedBuffer; import io.protostuff.ProtostuffIOUtil; import io.protostuff.Schema; import io.protostuff.runtime.RuntimeSchema; import java.io.IOException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; public class ProtoStuffSerializer implements Serializer { private static Map<Class<?>, Schema<?>> cachedSchema = new ConcurrentHashMap<>(); @Override public <T> byte[] encode(T obj) throws IOException { Class<?> clazz = obj.getClass(); LinkedBuffer buffer = LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE); try { @SuppressWarnings("unchecked") Schema<T> schema = (Schema<T>) getSchema(clazz); return ProtostuffIOUtil.toByteArray(obj, schema, buffer); } catch (Exception e) { throw new IllegalStateException(e.getMessage(), e); } finally { buffer.clear(); } } @Override public <T> T decode(byte[] bytes, Class<T> clazz) throws IOException { try { T t = clazz.newInstance(); @SuppressWarnings("unchecked") Schema<T> schema = (Schema<T>) getSchema(clazz); ProtostuffIOUtil.mergeFrom(bytes, t, schema); return t; } catch (Exception e) { throw new IllegalStateException(e.getMessage(), e); } } private static Schema<?> getSchema(Class<?> clazz) { Schema<?> schema = cachedSchema.get(clazz); if (schema == null) { schema = RuntimeSchema.createFrom(clazz); if (schema != null) { cachedSchema.put(clazz, schema); } } return schema; } }