New: Indirect Ionization (tm)
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>mighty_utils</name>
|
||||
<name>MightyUtils</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package mightypork.utils;
|
||||
|
||||
|
||||
public class Profiler {
|
||||
|
||||
public static long begin()
|
||||
{
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
|
||||
public static double end(long begun)
|
||||
{
|
||||
return endLong(begun) / 1000D;
|
||||
}
|
||||
|
||||
|
||||
public static long endLong(long begun)
|
||||
{
|
||||
return System.currentTimeMillis() - begun;
|
||||
}
|
||||
|
||||
|
||||
public static String endStr(long begun)
|
||||
{
|
||||
return Support.str(end(begun)) + " s";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,6 +2,10 @@ package mightypork.utils;
|
||||
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
|
||||
/**
|
||||
@@ -36,4 +40,47 @@ public class Reflect {
|
||||
return tested.getClass().isAnnotationPresent(annotation);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get generic parameters of a class
|
||||
*
|
||||
* @param clazz the examined class
|
||||
* @return parameter types
|
||||
*/
|
||||
public static Class<?>[] getGenericParameters(Class<?> clazz)
|
||||
{
|
||||
// BEHOLD, MAGIC!
|
||||
|
||||
final Type evtc = clazz.getGenericSuperclass();
|
||||
|
||||
if (evtc instanceof ParameterizedType) {
|
||||
final Type[] types = ((ParameterizedType) evtc).getActualTypeArguments();
|
||||
|
||||
final Class<?>[] classes = new Class<?>[types.length];
|
||||
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
classes[i] = (Class<?>) types[i];
|
||||
}
|
||||
|
||||
return classes;
|
||||
}
|
||||
|
||||
throw new RuntimeException(Support.str(clazz) + " is not generic.");
|
||||
}
|
||||
|
||||
|
||||
public static Object getConstantFieldValue(Class<?> objClass, String fieldName) throws ReflectiveOperationException
|
||||
{
|
||||
final Field fld = objClass.getDeclaredField(fieldName);
|
||||
|
||||
final int modif = fld.getModifiers();
|
||||
|
||||
if (!Modifier.isFinal(modif) || !Modifier.isStatic(modif)) {
|
||||
throw new RuntimeException("The " + fieldName + " field of " + Support.str(objClass) + " field must be static and final!");
|
||||
}
|
||||
|
||||
fld.setAccessible(true);
|
||||
return fld.get(null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package mightypork.utils.eventbus;
|
||||
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
@@ -112,20 +110,7 @@ final public class EventBus implements Destroyable, BusAccess {
|
||||
|
||||
private static Class<?> getEventListenerClass(BusEvent<?> event)
|
||||
{
|
||||
// BEHOLD, MAGIC!
|
||||
|
||||
final Type evtc = event.getClass().getGenericSuperclass();
|
||||
|
||||
if (evtc instanceof ParameterizedType) {
|
||||
if (((ParameterizedType) evtc).getRawType() == BusEvent.class) {
|
||||
final Type[] types = ((ParameterizedType) evtc).getActualTypeArguments();
|
||||
for (final Type genericType : types) {
|
||||
return (Class<?>) genericType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw new RuntimeException("Could not detect event listener type.");
|
||||
return Reflect.getGenericParameters(event.getClass())[0];
|
||||
}
|
||||
|
||||
/** Log detailed messages (debug) */
|
||||
|
||||
@@ -7,13 +7,13 @@ import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import mightypork.utils.Reflect;
|
||||
import mightypork.utils.Support;
|
||||
|
||||
|
||||
/**
|
||||
@@ -90,13 +90,16 @@ public class Ion {
|
||||
private static Map<Integer, Class<?>> markToClass = new HashMap<>();
|
||||
private static Map<Class<?>, Integer> classToMark = new HashMap<>();
|
||||
|
||||
private static Map<Class<?>, IonizerBinary<?>> ionizersBinary = new HashMap<>();
|
||||
private static Map<Class<?>, IonizerBundled<?>> ionizersBundled = new HashMap<>();
|
||||
|
||||
private static boolean reservedMarkChecking;
|
||||
|
||||
static {
|
||||
reservedMarkChecking = false;
|
||||
|
||||
// register built-ins
|
||||
register(ION_BUNDLE, IonBundle.class);
|
||||
register(ION_BUNDLE, IonDataBundle.class);
|
||||
register(SEQUENCE_WRAPPER, IonSequenceWrapper.class);
|
||||
register(MAP_WRAPPER, IonMapWrapper.class);
|
||||
|
||||
@@ -105,12 +108,108 @@ public class Ion {
|
||||
|
||||
|
||||
/**
|
||||
* Register new {@link IonObjBinary} class for writing/loading.
|
||||
* Register a type for writing/loading.
|
||||
*
|
||||
* @param mark mark to be used 50..255, unless internal
|
||||
* @param mark binary ION mark
|
||||
* @param objClass class of the registered object
|
||||
*/
|
||||
public static void register(int mark, Class<?> objClass)
|
||||
{
|
||||
if (!IonBinary.class.isAssignableFrom(objClass)) {
|
||||
if (!IonBundled.class.isAssignableFrom(objClass)) {
|
||||
throw new IllegalArgumentException("Cannot register directly: " + Support.str(objClass));
|
||||
}
|
||||
}
|
||||
|
||||
assertHasImplicitConstructor(objClass);
|
||||
|
||||
registerUsingMark(mark, objClass);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Try to register a type using a static final ION_MARK int field.
|
||||
*
|
||||
* @param objClass type class
|
||||
*/
|
||||
public static void register(Class<?> objClass)
|
||||
{
|
||||
if (!IonBinary.class.isAssignableFrom(objClass)) {
|
||||
if (!IonBundled.class.isAssignableFrom(objClass)) {
|
||||
throw new IllegalArgumentException("Cannot register directly: " + Support.str(objClass));
|
||||
}
|
||||
}
|
||||
|
||||
assertHasImplicitConstructor(objClass);
|
||||
registerUsingConstant(objClass);
|
||||
}
|
||||
|
||||
|
||||
private static void registerUsingMark(int mark, Class<?> objClass)
|
||||
{
|
||||
assertMarkAvailable(mark, objClass);
|
||||
|
||||
markToClass.put(mark, objClass);
|
||||
classToMark.put(objClass, mark);
|
||||
}
|
||||
|
||||
|
||||
public static void registerUsingConstant(Class<?> objClass)
|
||||
{
|
||||
try {
|
||||
final int mark = ((Number) Reflect.getConstantFieldValue(objClass, "ION_MARK")).intValue();
|
||||
|
||||
registerUsingMark(mark, objClass);
|
||||
|
||||
} catch (final Exception e) {
|
||||
throw new RuntimeException("Could not register " + Support.str(objClass) + " using an ION_MARK field.", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register new binary ionizer.
|
||||
*
|
||||
* @param mark binary ION mark
|
||||
* @param ionizer ionizer
|
||||
*/
|
||||
public static void registerIndirect(int mark, IonizerBinary<?> ionizer)
|
||||
{
|
||||
final Class<?> objClass = Reflect.getGenericParameters(ionizer.getClass())[0];
|
||||
|
||||
registerUsingMark(mark, objClass);
|
||||
|
||||
ionizersBinary.put(objClass, ionizer);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register new bundled ionizer.
|
||||
*
|
||||
* @param mark binary ION mark
|
||||
* @param ionizer ionizer
|
||||
*/
|
||||
public static void registerIndirect(int mark, IonizerBundled<?> ionizer)
|
||||
{
|
||||
final Class<?> objClass = Reflect.getGenericParameters(ionizer.getClass())[0];
|
||||
|
||||
registerUsingMark(mark, objClass);
|
||||
|
||||
ionizersBundled.put(objClass, ionizer);
|
||||
}
|
||||
|
||||
|
||||
private static void assertHasImplicitConstructor(Class<?> objClass)
|
||||
{
|
||||
try {
|
||||
objClass.getConstructor();
|
||||
} catch (NoSuchMethodException | SecurityException e) {
|
||||
throw new RuntimeException("Class " + objClass + " doesn't have an implicit constructor.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void assertMarkAvailable(int mark, Class<?> objClass)
|
||||
{
|
||||
// negative marks are allowed.
|
||||
if (mark > RANGE_HIGH) throw new IllegalArgumentException("Mark must be < 256.");
|
||||
@@ -120,55 +219,12 @@ public class Ion {
|
||||
throw new IllegalArgumentException("Marks " + RESERVED_LOW + ".." + RESERVED_HIGH + " are reserved.");
|
||||
}
|
||||
|
||||
if (markToClass.containsKey(objClass)) {
|
||||
if (markToClass.containsKey(mark)) {
|
||||
throw new IllegalArgumentException("Mark " + mark + " is already in use.");
|
||||
}
|
||||
|
||||
if (classToMark.containsKey(objClass)) {
|
||||
throw new IllegalArgumentException(objClass + " is already registered.");
|
||||
}
|
||||
|
||||
if (!IonObjBundled.class.isAssignableFrom(objClass)) {
|
||||
if (!IonObjBinary.class.isAssignableFrom(objClass)) {
|
||||
throw new IllegalArgumentException(objClass + " cannot be registered to Ion.");
|
||||
}
|
||||
}
|
||||
|
||||
// make sure the type has implicit constructor
|
||||
try {
|
||||
objClass.getConstructor();
|
||||
} catch (NoSuchMethodException | SecurityException e) {
|
||||
throw new RuntimeException("Class " + objClass + " doesn't have an implicit constructor.");
|
||||
}
|
||||
|
||||
markToClass.put(mark, objClass);
|
||||
classToMark.put(objClass, mark);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Try to register the type using a static final ION_MARK int field.
|
||||
*
|
||||
* @param objClass type class
|
||||
*/
|
||||
public static void register(Class<?> objClass)
|
||||
{
|
||||
try {
|
||||
final Field fld = objClass.getDeclaredField("ION_MARK");
|
||||
|
||||
final int modif = fld.getModifiers();
|
||||
|
||||
if (!Modifier.isFinal(modif) || !Modifier.isStatic(modif)) {
|
||||
throw new RuntimeException("The ION_MARK field must be static and final.");
|
||||
}
|
||||
|
||||
fld.setAccessible(true);
|
||||
final int mark = fld.getInt(null);
|
||||
|
||||
register(mark, objClass);
|
||||
|
||||
} catch (final Exception e) {
|
||||
throw new RuntimeException("Could not register " + objClass + " using an ION_MARK field.", e);
|
||||
throw new IllegalArgumentException(Support.str(objClass) + " is already registered.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,9 +353,9 @@ public class Ion {
|
||||
/**
|
||||
* Create new bundle and write the object to it.
|
||||
*/
|
||||
public static IonBundle wrapBundled(IonObjBundled content) throws IOException
|
||||
public static IonDataBundle wrapBundled(IonBundled content) throws IOException
|
||||
{
|
||||
final IonBundle ib = new IonBundle();
|
||||
final IonDataBundle ib = new IonDataBundle();
|
||||
content.save(ib);
|
||||
return ib;
|
||||
}
|
||||
@@ -314,14 +370,14 @@ public class Ion {
|
||||
* @return the object unwrapped
|
||||
* @throws IOException
|
||||
*/
|
||||
public static <T extends IonObjBundled> T unwrapBundled(IonBundle bundle, Class<? extends T> objClass) throws IOException
|
||||
public static <T extends IonBundled> T unwrapBundled(IonDataBundle bundle, Class<? extends T> objClass) throws IOException
|
||||
{
|
||||
try {
|
||||
final T inst = objClass.newInstance();
|
||||
inst.load(bundle);
|
||||
return inst;
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
throw new IOException("Could not instantiate " + objClass + ".");
|
||||
throw new IOException("Could not instantiate " + Support.str(objClass) + ".");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,6 +388,18 @@ public class Ion {
|
||||
}
|
||||
|
||||
|
||||
static IonizerBinary<?> getIonizerBinaryForClass(Class<?> clz)
|
||||
{
|
||||
return ionizersBinary.get(clz);
|
||||
}
|
||||
|
||||
|
||||
static IonizerBundled<?> getIonizerBundledForClass(Class<?> clz)
|
||||
{
|
||||
return ionizersBundled.get(clz);
|
||||
}
|
||||
|
||||
|
||||
public static int getMark(Object object)
|
||||
{
|
||||
assertRegistered(object);
|
||||
@@ -341,24 +409,48 @@ public class Ion {
|
||||
|
||||
|
||||
/**
|
||||
* @return true if the mark is for a registered {@link IonObjBinary} object
|
||||
* @return true if the mark is for a registered {@link IonBinary} object
|
||||
*/
|
||||
static boolean isMarkForBinary(int mark)
|
||||
{
|
||||
if (!markToClass.containsKey(mark)) return false;
|
||||
|
||||
return IonObjBinary.class.isAssignableFrom(markToClass.get(mark));
|
||||
return IonBinary.class.isAssignableFrom(markToClass.get(mark));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return true if the mark is for a registered {@link IonObjBinary} object
|
||||
* @return true if the mark is for a registered {@link IonBinary} object
|
||||
*/
|
||||
static boolean isMarkForBundled(int mark)
|
||||
{
|
||||
if (!markToClass.containsKey(mark)) return false;
|
||||
|
||||
return IonObjBundled.class.isAssignableFrom(markToClass.get(mark));
|
||||
return IonBundled.class.isAssignableFrom(markToClass.get(mark));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return true if the mark is for a registered indirectly saved binary
|
||||
* object
|
||||
*/
|
||||
static boolean isMarkForIndirectBinary(int mark)
|
||||
{
|
||||
if (!markToClass.containsKey(mark)) return false;
|
||||
|
||||
return ionizersBinary.containsKey(markToClass.get(mark));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return true if the mark is for a registered indirectly saved bundled
|
||||
* object
|
||||
*/
|
||||
static boolean isMarkForIndirectBundled(int mark)
|
||||
{
|
||||
if (!markToClass.containsKey(mark)) return false;
|
||||
|
||||
return ionizersBundled.containsKey(markToClass.get(mark));
|
||||
}
|
||||
|
||||
|
||||
@@ -372,11 +464,14 @@ public class Ion {
|
||||
|
||||
|
||||
/**
|
||||
* @return true if the mark is for a registered {@link IonObjBinary} object
|
||||
* @return true if the mark is for a registered {@link IonBinary} object
|
||||
*/
|
||||
static boolean isRegistered(Object object)
|
||||
{
|
||||
return classToMark.containsKey(object.getClass());
|
||||
final Class<?> clazz = object.getClass();
|
||||
if (classToMark.containsKey(clazz)) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -388,7 +483,7 @@ public class Ion {
|
||||
static void assertRegistered(Object obj)
|
||||
{
|
||||
if (!isRegistered(obj)) {
|
||||
throw new RuntimeException("Type not registered: " + (obj.getClass()));
|
||||
throw new RuntimeException("Type not registered: " + Support.str(obj.getClass()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -400,16 +495,34 @@ public class Ion {
|
||||
public static void reset()
|
||||
{
|
||||
final List<Integer> toRemove = new ArrayList<>();
|
||||
for (final Entry<Integer, Class<?>> e : markToClass.entrySet()) {
|
||||
final int mark = e.getKey();
|
||||
|
||||
|
||||
|
||||
// remove direct
|
||||
for (final Integer mark : markToClass.keySet()) {
|
||||
if (!isMarkReserved(mark)) {
|
||||
toRemove.add(mark);
|
||||
}
|
||||
}
|
||||
|
||||
for (final int i : toRemove) {
|
||||
classToMark.remove(markToClass.remove(i));
|
||||
|
||||
final Class<?> clz = markToClass.remove(i);
|
||||
|
||||
classToMark.remove(clz);
|
||||
ionizersBinary.remove(clz);
|
||||
ionizersBundled.remove(clz);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static boolean isObjectIndirectBundled(Object obj)
|
||||
{
|
||||
return ionizersBundled.containsKey(obj.getClass());
|
||||
}
|
||||
|
||||
|
||||
public static boolean isObjectIndirectBinary(Object obj)
|
||||
{
|
||||
return ionizersBinary.containsKey(obj.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ import java.io.IOException;
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public interface IonObjBinary {
|
||||
public interface IonBinary {
|
||||
|
||||
/**
|
||||
* Load data from the input stream.
|
||||
@@ -0,0 +1,26 @@
|
||||
package mightypork.utils.ion;
|
||||
|
||||
|
||||
/**
|
||||
* Bundled ion object. If a class implements both binary and bundled, then
|
||||
* binary will be preferred by both IonInput and IonOutput.
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public interface IonBundled {
|
||||
|
||||
/**
|
||||
* Load this object from the data bundle
|
||||
*
|
||||
* @param in bundle to load from
|
||||
*/
|
||||
void load(IonDataBundle in);
|
||||
|
||||
|
||||
/**
|
||||
* Save this object to the data bundle
|
||||
*
|
||||
* @param out bundle to save into
|
||||
*/
|
||||
void save(IonDataBundle out);
|
||||
}
|
||||
+11
-19
@@ -15,7 +15,7 @@ import java.util.Map;
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public class IonBundle implements IonObjBinary {
|
||||
public class IonDataBundle implements IonBinary {
|
||||
|
||||
private final Map<String, Object> backingMap = new HashMap<>();
|
||||
|
||||
@@ -26,11 +26,11 @@ public class IonBundle implements IonObjBinary {
|
||||
* @param key key
|
||||
* @param filled bundle to fill
|
||||
*/
|
||||
public void loadBundle(String key, IonBundle filled)
|
||||
public void loadBundle(String key, IonDataBundle filled)
|
||||
{
|
||||
if (!containsKey(key)) return;
|
||||
|
||||
final IonBundle ib = get(key, new IonBundle());
|
||||
final IonDataBundle ib = get(key, new IonDataBundle());
|
||||
|
||||
filled.clear();
|
||||
filled.putAll(ib);
|
||||
@@ -127,9 +127,9 @@ public class IonBundle implements IonObjBinary {
|
||||
* @param loaded loaded object
|
||||
* @return the loaded object
|
||||
*/
|
||||
public <T extends IonObjBundled> T loadBundled(String key, T loaded)
|
||||
public <T extends IonBundled> T loadBundled(String key, T loaded)
|
||||
{
|
||||
final IonBundle bu = get(key, null);
|
||||
final IonDataBundle bu = get(key, null);
|
||||
if (bu == null) throw new RuntimeException("No such key: " + key);
|
||||
|
||||
loaded.load(bu);
|
||||
@@ -145,9 +145,9 @@ public class IonBundle implements IonObjBinary {
|
||||
* @param key key
|
||||
* @param saved saved object
|
||||
*/
|
||||
public void putBundled(String key, IonObjBundled saved)
|
||||
public void putBundled(String key, IonBundled saved)
|
||||
{
|
||||
final IonBundle bu = new IonBundle();
|
||||
final IonDataBundle bu = new IonDataBundle();
|
||||
saved.save(bu);
|
||||
put(key, bu);
|
||||
}
|
||||
@@ -184,15 +184,7 @@ public class IonBundle implements IonObjBinary {
|
||||
}
|
||||
|
||||
|
||||
public void put(String key, IonObjBundled value)
|
||||
{
|
||||
if (key == null || value == null) return;
|
||||
if (!Ion.isRegistered(value)) throw new IllegalArgumentException("Cannot add to bundle, not registered: " + value);
|
||||
backingMap.put(key, value);
|
||||
}
|
||||
|
||||
|
||||
public void put(String key, IonObjBinary value)
|
||||
public void put(String key, Object value)
|
||||
{
|
||||
if (key == null || value == null) return;
|
||||
if (!Ion.isRegistered(value)) throw new IllegalArgumentException("Cannot add to bundle, not registered: " + value);
|
||||
@@ -396,7 +388,7 @@ public class IonBundle implements IonObjBinary {
|
||||
*
|
||||
* @param anotherBundle another bundle
|
||||
*/
|
||||
public void putAll(IonBundle anotherBundle)
|
||||
public void putAll(IonDataBundle anotherBundle)
|
||||
{
|
||||
backingMap.putAll(anotherBundle.backingMap);
|
||||
}
|
||||
@@ -424,8 +416,8 @@ public class IonBundle implements IonObjBinary {
|
||||
{
|
||||
if (this == obj) return true;
|
||||
if (obj == null) return false;
|
||||
if (!(obj instanceof IonBundle)) return false;
|
||||
final IonBundle other = (IonBundle) obj;
|
||||
if (!(obj instanceof IonDataBundle)) return false;
|
||||
final IonDataBundle other = (IonDataBundle) obj;
|
||||
if (backingMap == null) {
|
||||
if (other.backingMap != null) return false;
|
||||
} else if (!backingMap.equals(other.backingMap)) return false;
|
||||
@@ -235,9 +235,9 @@ public class IonInput implements Closeable {
|
||||
/**
|
||||
* Read bundle without a mark
|
||||
*/
|
||||
public IonBundle readBundle() throws IOException
|
||||
public IonDataBundle readBundle() throws IOException
|
||||
{
|
||||
final IonBundle ib = new IonBundle();
|
||||
final IonDataBundle ib = new IonDataBundle();
|
||||
ib.load(this);
|
||||
return ib;
|
||||
}
|
||||
@@ -246,7 +246,7 @@ public class IonInput implements Closeable {
|
||||
/**
|
||||
* Read bundle without a mark, load into a provided one
|
||||
*/
|
||||
public void readBundle(IonBundle filled) throws IOException
|
||||
public void readBundle(IonDataBundle filled) throws IOException
|
||||
{
|
||||
filled.clear();
|
||||
filled.load(this);
|
||||
@@ -276,16 +276,16 @@ public class IonInput implements Closeable {
|
||||
*
|
||||
* @param def default value.
|
||||
* @return the loaded object
|
||||
* @throws IOException
|
||||
* @throws CorruptDataException
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T readObject(T def) throws IOException
|
||||
public <T> T readObject(T def) throws CorruptDataException
|
||||
{
|
||||
try {
|
||||
final Object o = readObject();
|
||||
return (T) (o == null ? def : o);
|
||||
} catch (final Exception e) {
|
||||
throw new IOException("Could not load object.", e);
|
||||
throw new CorruptDataException("Could not load object.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,31 +299,42 @@ public class IonInput implements Closeable {
|
||||
public Object readObject() throws IOException
|
||||
{
|
||||
final int mark = readMark();
|
||||
if (Ion.isMarkForBinary(mark)) {
|
||||
IonObjBinary loaded;
|
||||
|
||||
try {
|
||||
loaded = (IonObjBinary) Ion.getClassForMark(mark).newInstance();
|
||||
} catch (final Exception e) {
|
||||
throw new RuntimeException("Could not load binary object with mark: " + mark, e);
|
||||
}
|
||||
|
||||
loaded.load(this);
|
||||
return loaded;
|
||||
}
|
||||
|
||||
if (Ion.isMarkForBundled(mark)) {
|
||||
IonObjBundled loaded;
|
||||
|
||||
try {
|
||||
|
||||
try {
|
||||
loaded = (IonObjBundled) Ion.getClassForMark(mark).newInstance();
|
||||
} catch (final Exception e) {
|
||||
throw new RuntimeException("Could not load bundled object with mark: " + mark, e);
|
||||
if (Ion.isMarkForBinary(mark)) {
|
||||
IonBinary loaded;
|
||||
|
||||
loaded = (IonBinary) Ion.getClassForMark(mark).newInstance();
|
||||
|
||||
|
||||
loaded.load(this);
|
||||
return loaded;
|
||||
}
|
||||
|
||||
final IonBundle ib = readBundle();
|
||||
loaded.load(ib);
|
||||
return loaded;
|
||||
if (Ion.isMarkForBundled(mark)) {
|
||||
IonBundled loaded;
|
||||
|
||||
loaded = (IonBundled) Ion.getClassForMark(mark).newInstance();
|
||||
|
||||
final IonDataBundle ib = readBundle();
|
||||
loaded.load(ib);
|
||||
return loaded;
|
||||
}
|
||||
|
||||
if (Ion.isMarkForIndirectBundled(mark)) {
|
||||
final IonizerBundled<?> ionizer = Ion.getIonizerBundledForClass(Ion.getClassForMark(mark));
|
||||
return ionizer.load(readBundle());
|
||||
}
|
||||
|
||||
if (Ion.isMarkForIndirectBinary(mark)) {
|
||||
final IonizerBinary<?> ionizer = Ion.getIonizerBinaryForClass(Ion.getClassForMark(mark));
|
||||
return ionizer.load(this);
|
||||
}
|
||||
|
||||
} catch (final Exception e) {
|
||||
throw new RuntimeException("Could not load object for mark: " + mark, e);
|
||||
}
|
||||
|
||||
switch (mark) {
|
||||
|
||||
@@ -7,7 +7,7 @@ import java.util.Map;
|
||||
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
class IonMapWrapper implements IonObjBinary {
|
||||
class IonMapWrapper implements IonBinary {
|
||||
|
||||
private final Map map;
|
||||
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
package mightypork.utils.ion;
|
||||
|
||||
|
||||
/**
|
||||
* Bundled ion object. If a class implements both binary and bundled, then
|
||||
* binary will be preferred by both IonInput and IonOutput.
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
*/
|
||||
public interface IonObjBundled {
|
||||
|
||||
void load(IonBundle in);
|
||||
|
||||
|
||||
void save(IonBundle out);
|
||||
}
|
||||
@@ -195,7 +195,7 @@ public class IonOutput implements Closeable {
|
||||
/**
|
||||
* Write a bundle without a mark
|
||||
*/
|
||||
public void writeBundle(IonBundle bundle) throws IOException
|
||||
public void writeBundle(IonDataBundle bundle) throws IOException
|
||||
{
|
||||
bundle.save(this);
|
||||
}
|
||||
@@ -279,26 +279,47 @@ public class IonOutput implements Closeable {
|
||||
return;
|
||||
}
|
||||
|
||||
if (obj instanceof IonObjBinary) {
|
||||
final IonObjBinary iObj = (IonObjBinary) obj;
|
||||
if (obj instanceof IonBinary) {
|
||||
final IonBinary iObj = (IonBinary) obj;
|
||||
|
||||
writeMark(Ion.getMark(iObj));
|
||||
writeMark(Ion.getMark(obj));
|
||||
iObj.save(this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (obj instanceof IonObjBundled) {
|
||||
final IonObjBundled iObj = (IonObjBundled) obj;
|
||||
if (obj instanceof IonBundled) {
|
||||
final IonBundled iObj = (IonBundled) obj;
|
||||
|
||||
writeMark(Ion.getMark(iObj));
|
||||
writeMark(Ion.getMark(obj));
|
||||
|
||||
final IonBundle bundle = new IonBundle();
|
||||
final IonDataBundle bundle = new IonDataBundle();
|
||||
iObj.save(bundle);
|
||||
writeBundle(bundle);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (Ion.isObjectIndirectBundled(obj)) {
|
||||
final IonizerBundled<?> ionizer = Ion.getIonizerBundledForClass(obj.getClass());
|
||||
|
||||
writeMark(Ion.getMark(obj));
|
||||
|
||||
final IonDataBundle bundle = new IonDataBundle();
|
||||
ionizer._save(obj, bundle);
|
||||
writeBundle(bundle);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Ion.isObjectIndirectBinary(obj)) {
|
||||
final IonizerBinary<?> ionizer = Ion.getIonizerBinaryForClass(obj.getClass());
|
||||
|
||||
writeMark(Ion.getMark(obj));
|
||||
|
||||
ionizer._save(obj, this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (obj instanceof Map) {
|
||||
writeMark(Ion.MAP);
|
||||
writeMap((Map<?, ?>) obj);
|
||||
|
||||
@@ -7,7 +7,7 @@ import java.util.Collection;
|
||||
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
class IonSequenceWrapper implements IonObjBinary {
|
||||
class IonSequenceWrapper implements IonBinary {
|
||||
|
||||
private Collection collection = new ArrayList();
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package mightypork.utils.ion;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
/**
|
||||
* External ionizer using a IonOutput / IonInput - can be used if the data type
|
||||
* cannot be modified to implement the proper interface
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
* @param <T>
|
||||
*/
|
||||
public abstract class IonizerBinary<T> {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
final void _save(Object object, IonOutput out) throws IOException{
|
||||
save((T)object, out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save an object to ion output
|
||||
*
|
||||
* @param object object to save
|
||||
* @param out ion output
|
||||
* @throws IOException
|
||||
*/
|
||||
public abstract void save(T object, IonOutput out) throws IOException;
|
||||
|
||||
|
||||
/**
|
||||
* Load an object from ion input
|
||||
*
|
||||
* @param in ion input
|
||||
* @return the loaded object
|
||||
*/
|
||||
public abstract T load(IonInput in) throws IOException;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package mightypork.utils.ion;
|
||||
|
||||
|
||||
/**
|
||||
* External ionizer using a data bundle - can be used if the data type cannot be
|
||||
* modified to implement the proper interface
|
||||
*
|
||||
* @author Ondřej Hruška (MightyPork)
|
||||
* @param <T>
|
||||
*/
|
||||
public abstract class IonizerBundled<T> {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
final void _save(Object object, IonDataBundle out) {
|
||||
save((T)object, out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save an object to data bundle
|
||||
*
|
||||
* @param object object to save
|
||||
* @param out bundle to save to
|
||||
*/
|
||||
public abstract void save(T object, IonDataBundle out);
|
||||
|
||||
|
||||
/**
|
||||
* Load an object from a bundle
|
||||
*
|
||||
* @param in bundle to load from
|
||||
* @return the loaded object
|
||||
*/
|
||||
public abstract T load(IonDataBundle in);
|
||||
|
||||
}
|
||||
@@ -30,15 +30,9 @@ public class Move {
|
||||
return new Move(x, y);
|
||||
}
|
||||
|
||||
private byte x;
|
||||
private byte y;
|
||||
|
||||
|
||||
public Move()
|
||||
{
|
||||
// for ion
|
||||
}
|
||||
|
||||
private final byte x;
|
||||
private final byte y;
|
||||
|
||||
|
||||
public Move(int x, int y)
|
||||
{
|
||||
@@ -70,11 +64,4 @@ public class Move {
|
||||
{
|
||||
return "(" + x + " ; " + y + ")";
|
||||
}
|
||||
|
||||
|
||||
protected void setTo(byte x, byte y)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user