Skip to content

Instantly share code, notes, and snippets.

@ClickerMonkey
Created November 18, 2013 19:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ClickerMonkey/7534225 to your computer and use it in GitHub Desktop.
Save ClickerMonkey/7534225 to your computer and use it in GitHub Desktop.
Custom object serialization with compression (requires Compress.java) to and from ByteBuffers.
public interface Reflect<T>
{
public T get(ByteBuffer in);
public void getAndSet(ByteBuffer in, Object obj, Field field) throws IllegalAccessException;
public void put(ByteBuffer out, T v);
public int sizeOf(T v);
public Class<?> type();
}
public class ReflectByte implements Reflect<Byte>
{
@Override
public Byte get( ByteBuffer in )
{
return in.get();
}
@Override
public void getAndSet( ByteBuffer in, Object obj, Field field ) throws IllegalAccessException
{
field.setByte( obj, in.get() );
}
@Override
public void put( ByteBuffer out, Byte v )
{
out.put( v.byteValue() );
}
@Override
public int sizeOf( Byte v )
{
return 1;
}
@Override
public Class<?> type()
{
return byte.class;
}
}
public class ReflectInt implements Reflect<Integer>
{
@Override
public Integer get( ByteBuffer in )
{
return Compress.getInt( in );
}
@Override
public void getAndSet( ByteBuffer in, Object obj, Field field ) throws IllegalAccessException
{
field.setInt( obj, Compress.getInt( in ) );
}
@Override
public void put( ByteBuffer out, Integer v )
{
Compress.putInt( out, v.intValue() );
}
@Override
public int sizeOf( Integer v )
{
return Compress.sizeOf( v.intValue() );
}
@Override
public Class<?> type()
{
return int.class;
}
}
public class Reflector
{
private static Map<Class<?>, Reflect<?>> reflectMap = new HashMap<Class<?>, Reflect<?>>();
static
{
addReflect( new ReflectInt() );
addReflect( new ReflectShort() );
addReflect( new ReflectByte() );
addReflect( new ReflectUUID() );
addReflect( new ReflectString() );
}
public static void addReflect(Reflect<?> reflect)
{
reflectMap.put( reflect.type(), reflect );
}
public static Reflect<?> getReflect(Class<?> type)
{
return reflectMap.get( type );
}
@SuppressWarnings ({ "unchecked", "rawtypes" } )
public static int sizeOf(Object o) throws IllegalArgumentException, IllegalAccessException
{
final Class<?> c = o.getClass();
final Field[] f = c.getFields();
int size = 0;
for (int i = 0; i < f.length; i++)
{
Reflect r = getReflect( f[i].getType() );
size += r.sizeOf( f[i].get( o ) );
}
return size;
}
@SuppressWarnings ({ "unchecked", "rawtypes" } )
public static void put(ByteBuffer out, Object o) throws IllegalArgumentException, IllegalAccessException
{
final Class<?> c = o.getClass();
final Field[] f = c.getFields();
for (int i = 0; i < f.length; i++)
{
Reflect r = getReflect( f[i].getType() );
r.put( out, f[i].get( o ) );
}
}
public static <T> T get(ByteBuffer in, Class<T> c) throws IllegalArgumentException, IllegalAccessException, InstantiationException
{
final Field[] f = c.getFields();
final T o = c.newInstance();
for (int i = 0; i < f.length; i++)
{
Reflect<?> r = getReflect( f[i].getType() );
r.getAndSet( in, o, f[i] );
}
return o;
}
}
public class ReflectShort implements Reflect<Short>
{
@Override
public Short get( ByteBuffer in )
{
return Compress.getShort( in );
}
@Override
public void getAndSet( ByteBuffer in, Object obj, Field field ) throws IllegalAccessException
{
field.setShort( obj, Compress.getShort( in ) );
}
@Override
public void put( ByteBuffer out, Short v )
{
Compress.putShort( out, v.shortValue() );
}
@Override
public int sizeOf( Short v )
{
return Compress.sizeOf( v.intValue() );
}
@Override
public Class<?> type()
{
return short.class;
}
}
public class ReflectUUID implements Reflect<UUID>
{
public static final byte BYTE_NULL = 1;
@Override
public UUID get( ByteBuffer in )
{
return in.get() == BYTE_NULL ? null : new UUID( in.getLong(), in.getLong() );
}
@Override
public void getAndSet( ByteBuffer in, Object obj, Field field ) throws IllegalAccessException
{
field.set( obj, get( in ) );
}
@Override
public void put( ByteBuffer out, UUID v )
{
out.put( v == null ? BYTE_NULL : 0 );
if (v != null)
{
out.putLong( v.getMostSignificantBits() );
out.putLong( v.getLeastSignificantBits() );
}
}
@Override
public int sizeOf( UUID v )
{
return (v == null ? 1 : 17);
}
@Override
public Class<?> type()
{
return UUID.class;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment