package water.serial;
import java.io.IOException;
import java.lang.reflect.Field;
import water.AutoBuffer;
import water.Model;
/**
* A simple serializer interface.
*/
interface Serializer<T, O, I> {
/**
* Save given object into given target.
* @param e object to serialize
* @param output serialization destination
* @throws IOException
*/
public void save(T e, O output) throws IOException;
/**
* Load object from given destination.
* @param e object to be filled from
* @param output
* @return
*/
public T load(T e, I input) throws IOException;
public T load(I input) throws IOException;
}
abstract class BinarySerializer<T,O,I> implements Serializer<Model, O, I> {
protected int id(T m) {
int r = m.getClass().getCanonicalName().hashCode();
for (Field f : m.getClass().getDeclaredFields()) r ^= f.getName().hashCode();
return r;
}
protected AutoBuffer saveHeader(T m, AutoBuffer ab) {
ab.put4(id(m));
ab.putStr(m.getClass().getName());
return ab;
}
protected T loadHeader(AutoBuffer ab) {
int smId = ab.get4(); // type hash
String smCN = ab.getStr(); // type name
// Load it
Class klazz = null;
T m = null;
try {
klazz = Class.forName(smCN);
m = (T) klazz.newInstance();
} catch( Exception e ) {
throw new IllegalArgumentException("Cannot instantiate the type " + smCN, e);
}
int amId = id(m);
if (amId != smId) throw new IllegalArgumentException("Trying to load incompatible model! Actual model id = " + amId + ", stored id = " + smId+", type="+smCN);
return m;
}
}