parent
							
								
									2f26602d15
								
							
						
					
					
						commit
						c94cd05da5
					
				@ -0,0 +1,127 @@ | 
				
			||||
package mightypork.rogue.world; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
import java.io.IOException; | 
				
			||||
 | 
				
			||||
import mightypork.util.constraints.vect.Vect; | 
				
			||||
import mightypork.util.constraints.vect.mutable.VectAnimated; | 
				
			||||
import mightypork.util.control.timing.Updateable; | 
				
			||||
import mightypork.util.ion.IonBundle; | 
				
			||||
import mightypork.util.ion.IonBundled; | 
				
			||||
import mightypork.util.math.Easing; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * Player info | 
				
			||||
 *  | 
				
			||||
 * @author MightyPork | 
				
			||||
 */ | 
				
			||||
public class Player implements IonBundled, MapObserver, Updateable { | 
				
			||||
	 | 
				
			||||
	private final WorldPos position = new WorldPos(); | 
				
			||||
	private final VectAnimated walkOffset = new VectAnimated(Vect.ZERO, Easing.LINEAR); | 
				
			||||
	private final WorldPos target = new WorldPos(); | 
				
			||||
	private Runnable targetListener; | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public Player() | 
				
			||||
	{ | 
				
			||||
		walkOffset.setDefaultDuration(0.25); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public Player(int x, int y, int floor) | 
				
			||||
	{ | 
				
			||||
		this.position.setTo(x, y, floor); | 
				
			||||
		this.target.setTo(position); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public Player(WorldPos pos) | 
				
			||||
	{ | 
				
			||||
		this(pos.x, pos.y, pos.floor); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public void load(IonBundle in) throws IOException | 
				
			||||
	{ | 
				
			||||
		in.loadBundled("pos", position); | 
				
			||||
		in.loadBundled("target", target); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public void save(IonBundle out) throws IOException | 
				
			||||
	{ | 
				
			||||
		out.putBundled("pos", position); | 
				
			||||
		out.putBundled("target", target); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public WorldPos getLogicalPosition() | 
				
			||||
	{ | 
				
			||||
		return position; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public Vect getVisualOffset() | 
				
			||||
	{ | 
				
			||||
		return walkOffset; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public int getViewRange() | 
				
			||||
	{ | 
				
			||||
		return 15; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void teleport(WorldPos pos) | 
				
			||||
	{ | 
				
			||||
		position.setTo(pos); | 
				
			||||
		target.setTo(pos); | 
				
			||||
		walkOffset.reset(); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void walk(int offsetX, int offsetY) | 
				
			||||
	{ | 
				
			||||
		this.target.setTo(position.x + offsetX, position.y + offsetY, this.position.floor); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public void update(double delta) | 
				
			||||
	{ | 
				
			||||
		if (!walkOffset.isFinished()) { | 
				
			||||
			walkOffset.update(delta); | 
				
			||||
			if (walkOffset.isFinished()) { | 
				
			||||
				position.add(walkOffset.xi(), walkOffset.yi(), position.floor); | 
				
			||||
				walkOffset.reset(); | 
				
			||||
				targetListener.run(); | 
				
			||||
			} | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		if (walkOffset.isFinished() && !target.equals(position)) { | 
				
			||||
			 | 
				
			||||
			int x = (target.x - position.x); | 
				
			||||
			if (x > 0) x = 1; | 
				
			||||
			if (x < 0) x = -1; | 
				
			||||
			int y = (target.y - position.y); | 
				
			||||
			if (y > 0) y = 1; | 
				
			||||
			if (y < 0) y = -1; | 
				
			||||
			 | 
				
			||||
			walkOffset.animate(x, y, 0); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void setTargetListener(Runnable r) | 
				
			||||
	{ | 
				
			||||
		this.targetListener = r; | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -1,83 +0,0 @@ | 
				
			||||
package mightypork.rogue.world; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
import java.io.IOException; | 
				
			||||
import java.io.InputStream; | 
				
			||||
import java.io.OutputStream; | 
				
			||||
 | 
				
			||||
import mightypork.util.files.ion.Ion; | 
				
			||||
import mightypork.util.files.ion.IonBundle; | 
				
			||||
import mightypork.util.files.ion.IonConstructor; | 
				
			||||
import mightypork.util.files.ion.Ionizable; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * Player info | 
				
			||||
 *  | 
				
			||||
 * @author MightyPork | 
				
			||||
 */ | 
				
			||||
public class PlayerInfo implements Ionizable, MapObserver { | 
				
			||||
	 | 
				
			||||
	public static final short ION_MARK = 708; | 
				
			||||
	 | 
				
			||||
	public WorldPos position = new WorldPos(); | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@IonConstructor | 
				
			||||
	public PlayerInfo() | 
				
			||||
	{ | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public PlayerInfo(int x, int y, int floor) | 
				
			||||
	{ | 
				
			||||
		this.position.setTo(x, y, floor); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public PlayerInfo(WorldPos pos) | 
				
			||||
	{ | 
				
			||||
		this.position = pos; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public void load(InputStream in) throws IOException | 
				
			||||
	{ | 
				
			||||
		final IonBundle ib = (IonBundle) Ion.readObject(in); | 
				
			||||
		 | 
				
			||||
		position = ib.get("pos", position); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public void save(OutputStream out) throws IOException | 
				
			||||
	{ | 
				
			||||
		final IonBundle ib = new IonBundle(); | 
				
			||||
		 | 
				
			||||
		ib.put("pos", position); | 
				
			||||
		 | 
				
			||||
		Ion.writeObject(out, ib); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public short getIonMark() | 
				
			||||
	{ | 
				
			||||
		return ION_MARK; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public WorldPos getPosition() | 
				
			||||
	{ | 
				
			||||
		return position; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public int getViewRange() | 
				
			||||
	{ | 
				
			||||
		return 15; | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -0,0 +1,13 @@ | 
				
			||||
package mightypork.rogue.world; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
import mightypork.util.constraints.vect.Vect; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
public interface WorldEntity { | 
				
			||||
	 | 
				
			||||
	WorldPos getLogicalPosition(); | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	Vect getVisualOffset(); | 
				
			||||
} | 
				
			||||
@ -0,0 +1,14 @@ | 
				
			||||
package mightypork.rogue.world.map; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
import mightypork.util.constraints.rect.Rect; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
public class EntityRenderContext extends MapRenderContext { | 
				
			||||
	 | 
				
			||||
	public EntityRenderContext(MapAccess map, Rect drawArea) | 
				
			||||
	{ | 
				
			||||
		super(map, drawArea); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,33 @@ | 
				
			||||
package mightypork.rogue.world.map; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
import mightypork.util.constraints.rect.Rect; | 
				
			||||
import mightypork.util.constraints.rect.builders.TiledRect; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
public abstract class MapRenderContext { | 
				
			||||
	 | 
				
			||||
	protected final MapAccess map; | 
				
			||||
	protected final TiledRect tiler; | 
				
			||||
	private final Rect mapRect; | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public MapRenderContext(MapAccess map, Rect drawArea) | 
				
			||||
	{ | 
				
			||||
		this.map = map; | 
				
			||||
		this.tiler = drawArea.tiles(map.getWidth(), map.getHeight()); | 
				
			||||
		this.mapRect = drawArea; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public Rect getRectForTile(int x, int y) | 
				
			||||
	{ | 
				
			||||
		return tiler.tile(x, y); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public Rect getMapRect() | 
				
			||||
	{ | 
				
			||||
		return mapRect; | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -1,25 +0,0 @@ | 
				
			||||
package mightypork.test; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
import java.io.File; | 
				
			||||
import java.io.IOException; | 
				
			||||
import java.util.Random; | 
				
			||||
 | 
				
			||||
import mightypork.util.files.ion.Ion; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
public class TestIonArray { | 
				
			||||
	 | 
				
			||||
	public static void main(String[] args) throws IOException | 
				
			||||
	{ | 
				
			||||
		final byte[] array = new byte[1024 * 8]; | 
				
			||||
		 | 
				
			||||
		final Random rand = new Random(); | 
				
			||||
		 | 
				
			||||
		for (int i = 0; i < array.length; i++) { | 
				
			||||
			array[i] = (byte) rand.nextInt(); | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		Ion.toFile(new File("hello.ion"), array); | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -1,43 +0,0 @@ | 
				
			||||
package mightypork.test; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
import java.io.FileInputStream; | 
				
			||||
import java.io.FileOutputStream; | 
				
			||||
import java.io.IOException; | 
				
			||||
import java.io.InputStream; | 
				
			||||
import java.io.OutputStream; | 
				
			||||
 | 
				
			||||
import mightypork.util.files.ion.Ion; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
public class TestIonArray2 { | 
				
			||||
	 | 
				
			||||
	public static void main(String[] args) throws IOException | 
				
			||||
	{ | 
				
			||||
		final int[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 99999, 8888888 }; | 
				
			||||
		 | 
				
			||||
		final OutputStream out = new FileOutputStream("fuck.ion"); | 
				
			||||
		 | 
				
			||||
		Ion.writeIntArray(out, array); | 
				
			||||
		Ion.writeString(out, "HELLO DUDE WHATSUP"); | 
				
			||||
		Ion.writeCharArray(out, "HERE'S ONE COOL ARRAY!!!".toCharArray()); | 
				
			||||
		 | 
				
			||||
		// ---
 | 
				
			||||
		 | 
				
			||||
		final InputStream in = new FileInputStream("fuck.ion"); | 
				
			||||
		 | 
				
			||||
		final int[] a = Ion.readIntArray(in); | 
				
			||||
		 | 
				
			||||
		for (final int i : a) | 
				
			||||
			System.out.println(i); | 
				
			||||
		 | 
				
			||||
		final String s = Ion.readString(in); | 
				
			||||
		System.out.println(s); | 
				
			||||
		 | 
				
			||||
		final char[] v = Ion.readCharArray(in); | 
				
			||||
		 | 
				
			||||
		for (final int i : v) | 
				
			||||
			System.out.print((char) i); | 
				
			||||
		 | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -1,35 +0,0 @@ | 
				
			||||
package mightypork.test; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
import java.util.Random; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
public class TestRandomSeed { | 
				
			||||
	 | 
				
			||||
	public static void main(String[] args) | 
				
			||||
	{ | 
				
			||||
		 | 
				
			||||
		{ | 
				
			||||
			final Random rand = new Random(); | 
				
			||||
			final long begin = System.currentTimeMillis(); | 
				
			||||
			 | 
				
			||||
			for (int i = 0; i < 1000000; i++) { | 
				
			||||
				rand.setSeed(1000); | 
				
			||||
			} | 
				
			||||
			 | 
				
			||||
			System.out.println((System.currentTimeMillis() - begin) / 1000D); | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		{ | 
				
			||||
			final long begin = System.currentTimeMillis(); | 
				
			||||
			 | 
				
			||||
			for (int i = 0; i < 1000000; i++) { | 
				
			||||
				final Random rand = new Random(); | 
				
			||||
				rand.setSeed(1000); | 
				
			||||
			} | 
				
			||||
			 | 
				
			||||
			System.out.println((System.currentTimeMillis() - begin) / 1000D); | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -1,6 +0,0 @@ | 
				
			||||
package mightypork.test; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
public class testworldtofile { | 
				
			||||
	 | 
				
			||||
} | 
				
			||||
									
										
											File diff suppressed because it is too large
											Load Diff
										
									
								
							
						@ -1,58 +0,0 @@ | 
				
			||||
package mightypork.util.files.ion; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
import mightypork.util.files.ion.templates.StreamableHashMap; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * <p> | 
				
			||||
 * Data bundle. | 
				
			||||
 * </p> | 
				
			||||
 * <p> | 
				
			||||
 * Storing data in a bundle guarantees that future versions will be compatible | 
				
			||||
 * with the older format. Reading using default values ensures that you will get | 
				
			||||
 * some value even if it was not saved in the file. | 
				
			||||
 * </p> | 
				
			||||
 *  | 
				
			||||
 * @author MightyPork | 
				
			||||
 */ | 
				
			||||
public class IonBundle extends StreamableHashMap<String, Object> implements Ionizable { | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Get an object. If not found, fallback is returned. | 
				
			||||
	 *  | 
				
			||||
	 * @param key key | 
				
			||||
	 * @param fallback fallback | 
				
			||||
	 * @return element | 
				
			||||
	 */ | 
				
			||||
	public <T> T get(String key, T fallback) | 
				
			||||
	{ | 
				
			||||
		try { | 
				
			||||
			final T itm = (T) super.get(key); | 
				
			||||
			if (itm == null) return fallback; | 
				
			||||
			return itm; | 
				
			||||
		} catch (final ClassCastException e) { | 
				
			||||
			return fallback; | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Store an element. It's allowed to store any object, but only primitive | 
				
			||||
	 * types, String, their arrays, and Ionizable objects can be successfully | 
				
			||||
	 * stored to stream.. | 
				
			||||
	 */ | 
				
			||||
	@Override | 
				
			||||
	public Object put(String key, Object value) | 
				
			||||
	{ | 
				
			||||
		return super.put(key, value); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public short getIonMark() | 
				
			||||
	{ | 
				
			||||
		return Ion.DATA_BUNDLE; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
} | 
				
			||||
@ -1,31 +0,0 @@ | 
				
			||||
package mightypork.util.files.ion; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
import java.lang.annotation.Documented; | 
				
			||||
import java.lang.annotation.ElementType; | 
				
			||||
import java.lang.annotation.Retention; | 
				
			||||
import java.lang.annotation.RetentionPolicy; | 
				
			||||
import java.lang.annotation.Target; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * <p> | 
				
			||||
 * Implicit constructor marked like this is intended to be solely used for ION | 
				
			||||
 * de-serialization. | 
				
			||||
 * </p> | 
				
			||||
 * <p> | 
				
			||||
 * Constructors marked like this should create a functional instance with | 
				
			||||
 * default values. | 
				
			||||
 * </p> | 
				
			||||
 * <p> | 
				
			||||
 * This is a descriptive annotation and has no other function. | 
				
			||||
 * </p> | 
				
			||||
 *  | 
				
			||||
 * @author MightyPork | 
				
			||||
 */ | 
				
			||||
@Retention(RetentionPolicy.SOURCE) | 
				
			||||
@Target(ElementType.CONSTRUCTOR) | 
				
			||||
@Documented | 
				
			||||
public @interface IonConstructor { | 
				
			||||
	 | 
				
			||||
} | 
				
			||||
@ -1,24 +0,0 @@ | 
				
			||||
package mightypork.util.files.ion; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * <p> | 
				
			||||
 * Data object that can be reconstructed by Ion based on it's mark. Such object | 
				
			||||
 * MUST provide an implicit constructor. | 
				
			||||
 * </p> | 
				
			||||
 * <p> | 
				
			||||
 * All {@link Ionizable}s must be registered to {@link Ion}, otherwise they | 
				
			||||
 * can't be written/loaded using the mark. | 
				
			||||
 * </p> | 
				
			||||
 *  | 
				
			||||
 * @author MightyPork | 
				
			||||
 */ | 
				
			||||
public interface Ionizable extends Streamable { | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Get Ion mark byte. | 
				
			||||
	 *  | 
				
			||||
	 * @return Ion mark byte. | 
				
			||||
	 */ | 
				
			||||
	public short getIonMark(); | 
				
			||||
} | 
				
			||||
@ -1,36 +0,0 @@ | 
				
			||||
package mightypork.util.files.ion; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
import java.io.IOException; | 
				
			||||
import java.io.InputStream; | 
				
			||||
import java.io.OutputStream; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 *  | 
				
			||||
 * Saveable to a stream. | 
				
			||||
 *  | 
				
			||||
 *  | 
				
			||||
 * @author MightyPork | 
				
			||||
 */ | 
				
			||||
public interface Streamable { | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Load data from the input stream. Must be compatible with the | 
				
			||||
	 * <code>save</code> method. | 
				
			||||
	 *  | 
				
			||||
	 * @param in input stream | 
				
			||||
	 * @throws IOException | 
				
			||||
	 */ | 
				
			||||
	void load(InputStream in) throws IOException; | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Store data to output stream. | 
				
			||||
	 *  | 
				
			||||
	 * @param out Output stream | 
				
			||||
	 * @throws IOException | 
				
			||||
	 */ | 
				
			||||
	void save(OutputStream out) throws IOException; | 
				
			||||
	 | 
				
			||||
} | 
				
			||||
@ -1,28 +0,0 @@ | 
				
			||||
package mightypork.util.files.ion.templates; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
import java.io.IOException; | 
				
			||||
import java.io.InputStream; | 
				
			||||
import java.io.OutputStream; | 
				
			||||
import java.util.ArrayList; | 
				
			||||
 | 
				
			||||
import mightypork.util.files.ion.Ion; | 
				
			||||
import mightypork.util.files.ion.Streamable; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
public class StreamableArrayList<E> extends ArrayList<E> implements Streamable { | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public void load(InputStream in) throws IOException | 
				
			||||
	{ | 
				
			||||
		Ion.readSequence(in, this); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public void save(OutputStream out) throws IOException | 
				
			||||
	{ | 
				
			||||
		Ion.writeSequence(out, this); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
} | 
				
			||||
@ -1,28 +0,0 @@ | 
				
			||||
package mightypork.util.files.ion.templates; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
import java.io.IOException; | 
				
			||||
import java.io.InputStream; | 
				
			||||
import java.io.OutputStream; | 
				
			||||
import java.util.HashMap; | 
				
			||||
 | 
				
			||||
import mightypork.util.files.ion.Ion; | 
				
			||||
import mightypork.util.files.ion.Streamable; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
public class StreamableHashMap<K, V> extends HashMap<K, V> implements Streamable { | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public void load(InputStream in) throws IOException | 
				
			||||
	{ | 
				
			||||
		Ion.readMap(in, this); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public void save(OutputStream out) throws IOException | 
				
			||||
	{ | 
				
			||||
		Ion.writeMap(out, this); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
} | 
				
			||||
@ -1,28 +0,0 @@ | 
				
			||||
package mightypork.util.files.ion.templates; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
import java.io.IOException; | 
				
			||||
import java.io.InputStream; | 
				
			||||
import java.io.OutputStream; | 
				
			||||
import java.util.HashSet; | 
				
			||||
 | 
				
			||||
import mightypork.util.files.ion.Ion; | 
				
			||||
import mightypork.util.files.ion.Streamable; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
public abstract class StreamableHashSet<E> extends HashSet<E> implements Streamable { | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public void load(InputStream in) throws IOException | 
				
			||||
	{ | 
				
			||||
		Ion.readSequence(in, this); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public void save(OutputStream out) throws IOException | 
				
			||||
	{ | 
				
			||||
		Ion.writeSequence(out, this); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
} | 
				
			||||
@ -1,28 +0,0 @@ | 
				
			||||
package mightypork.util.files.ion.templates; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
import java.io.IOException; | 
				
			||||
import java.io.InputStream; | 
				
			||||
import java.io.OutputStream; | 
				
			||||
import java.util.LinkedHashMap; | 
				
			||||
 | 
				
			||||
import mightypork.util.files.ion.Ion; | 
				
			||||
import mightypork.util.files.ion.Streamable; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
public class StreamableLinkedHashMap<K, V> extends LinkedHashMap<K, V> implements Streamable { | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public void load(InputStream in) throws IOException | 
				
			||||
	{ | 
				
			||||
		Ion.readMap(in, this); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public void save(OutputStream out) throws IOException | 
				
			||||
	{ | 
				
			||||
		Ion.writeMap(out, this); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
} | 
				
			||||
@ -1,28 +0,0 @@ | 
				
			||||
package mightypork.util.files.ion.templates; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
import java.io.IOException; | 
				
			||||
import java.io.InputStream; | 
				
			||||
import java.io.OutputStream; | 
				
			||||
import java.util.LinkedList; | 
				
			||||
 | 
				
			||||
import mightypork.util.files.ion.Ion; | 
				
			||||
import mightypork.util.files.ion.Streamable; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
public class StreamableLinkedList<E> extends LinkedList<E> implements Streamable { | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public void load(InputStream in) throws IOException | 
				
			||||
	{ | 
				
			||||
		Ion.readSequence(in, this); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public void save(OutputStream out) throws IOException | 
				
			||||
	{ | 
				
			||||
		Ion.writeSequence(out, this); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
} | 
				
			||||
@ -1,28 +0,0 @@ | 
				
			||||
package mightypork.util.files.ion.templates; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
import java.io.IOException; | 
				
			||||
import java.io.InputStream; | 
				
			||||
import java.io.OutputStream; | 
				
			||||
import java.util.Stack; | 
				
			||||
 | 
				
			||||
import mightypork.util.files.ion.Ion; | 
				
			||||
import mightypork.util.files.ion.Streamable; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
public class StreamableStack<E> extends Stack<E> implements Streamable { | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public void load(InputStream in) throws IOException | 
				
			||||
	{ | 
				
			||||
		Ion.readSequence(in, this); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public void save(OutputStream out) throws IOException | 
				
			||||
	{ | 
				
			||||
		Ion.writeSequence(out, this); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
} | 
				
			||||
@ -1,28 +0,0 @@ | 
				
			||||
package mightypork.util.files.ion.templates; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
import java.io.IOException; | 
				
			||||
import java.io.InputStream; | 
				
			||||
import java.io.OutputStream; | 
				
			||||
import java.util.TreeSet; | 
				
			||||
 | 
				
			||||
import mightypork.util.files.ion.Ion; | 
				
			||||
import mightypork.util.files.ion.Streamable; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
public class StreamableTreeSet<E> extends TreeSet<E> implements Streamable { | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public void load(InputStream in) throws IOException | 
				
			||||
	{ | 
				
			||||
		Ion.readSequence(in, this); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public void save(OutputStream out) throws IOException | 
				
			||||
	{ | 
				
			||||
		Ion.writeSequence(out, this); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,296 @@ | 
				
			||||
package mightypork.util.ion; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
import java.io.*; | 
				
			||||
 | 
				
			||||
import mightypork.util.logging.Log; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * Universal data storage system (main API class) | 
				
			||||
 *  | 
				
			||||
 * @author MightyPork | 
				
			||||
 */ | 
				
			||||
public class Ion { | 
				
			||||
	 | 
				
			||||
	// marks for object saving
 | 
				
			||||
	/** Null mark */ | 
				
			||||
	static final int NULL = 0; | 
				
			||||
	/** Boolean mark */ | 
				
			||||
	static final int BOOLEAN = 1; | 
				
			||||
	/** Byte mark */ | 
				
			||||
	static final int BYTE = 2; | 
				
			||||
	/** Character mark */ | 
				
			||||
	static final int CHAR = 3; | 
				
			||||
	/** Short mark */ | 
				
			||||
	static final int SHORT = 4; | 
				
			||||
	/** Integer mark */ | 
				
			||||
	static final int INT = 5; | 
				
			||||
	/** Long mark */ | 
				
			||||
	static final int LONG = 6; | 
				
			||||
	/** Float mark */ | 
				
			||||
	static final int FLOAT = 7; | 
				
			||||
	/** Double mark */ | 
				
			||||
	static final int DOUBLE = 8; | 
				
			||||
	/** String mark */ | 
				
			||||
	static final int STRING = 9; | 
				
			||||
	/** Boolean array mark */ | 
				
			||||
	static final int BOOLEAN_ARRAY = 10; | 
				
			||||
	/** Byte array mark */ | 
				
			||||
	static final int BYTE_ARRAY = 11; | 
				
			||||
	/** Character array mark */ | 
				
			||||
	static final int CHAR_ARRAY = 12; | 
				
			||||
	/** Short array mark */ | 
				
			||||
	static final int SHORT_ARRAY = 13; | 
				
			||||
	/** Integer array mark */ | 
				
			||||
	static final int INT_ARRAY = 14; | 
				
			||||
	/** Long array mark */ | 
				
			||||
	static final int LONG_ARRAY = 15; | 
				
			||||
	/** Float array mark */ | 
				
			||||
	static final int FLOAT_ARRAY = 16; | 
				
			||||
	/** Double array mark */ | 
				
			||||
	static final int DOUBLE_ARRAY = 17; | 
				
			||||
	/** String array mark */ | 
				
			||||
	static final int STRING_ARRAY = 18; | 
				
			||||
	/** Entry mark - start of map or sequence entry */ | 
				
			||||
	static final int ENTRY = 19; | 
				
			||||
	/** End mark - end of sequence or map */ | 
				
			||||
	static final int END = 20; | 
				
			||||
	/** Map mark (built-in data structure) */ | 
				
			||||
	static final int DATA_BUNDLE = 21; | 
				
			||||
	/** Sequence wrapper for bundle */ | 
				
			||||
	static final int SEQUENCE_WRAPPER = 22; | 
				
			||||
	/** Map wrapper for bundle */ | 
				
			||||
	static final int MAP_WRAPPER = 23; | 
				
			||||
	 | 
				
			||||
	// technical 20..39
 | 
				
			||||
	 | 
				
			||||
	/** Ionizables<Mark, Class> */ | 
				
			||||
	@SuppressWarnings("rawtypes") | 
				
			||||
	private static Class[] registered = new Class[256]; | 
				
			||||
	 | 
				
			||||
	private static boolean reservedMarkChecking; | 
				
			||||
	 | 
				
			||||
	static { | 
				
			||||
		reservedMarkChecking = false; | 
				
			||||
		 | 
				
			||||
		// register built-ins
 | 
				
			||||
		registerBinary(DATA_BUNDLE, IonBundle.class); | 
				
			||||
		registerBinary(SEQUENCE_WRAPPER, IonSequenceWrapper.class); | 
				
			||||
		registerBinary(MAP_WRAPPER, IonMapWrapper.class); | 
				
			||||
		 | 
				
			||||
		reservedMarkChecking = true; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Register new {@link IonBinary} class for writing/loading. | 
				
			||||
	 *  | 
				
			||||
	 * @param mark mark to be used 50..255, unless internal | 
				
			||||
	 * @param objClass class of the registered object | 
				
			||||
	 */ | 
				
			||||
	public static void registerBinary(int mark, Class<? extends IonBinary> objClass) | 
				
			||||
	{ | 
				
			||||
		// negative marks are allowed.
 | 
				
			||||
		if (mark > 255) throw new IllegalArgumentException("Mark must be < 256."); | 
				
			||||
		if (mark < 0) throw new IllegalArgumentException("Mark must be positive."); | 
				
			||||
		 | 
				
			||||
		if (reservedMarkChecking && mark < 50) { | 
				
			||||
			throw new IllegalArgumentException("Marks 0..49 are reserved."); | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		if (registered[mark] != null) { | 
				
			||||
			throw new IllegalArgumentException("Mark " + mark + " is already in use."); | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		try { | 
				
			||||
			objClass.getConstructor(); | 
				
			||||
		} catch (NoSuchMethodException | SecurityException e) { | 
				
			||||
			throw new IllegalArgumentException("Class " + Log.str(objClass) + " doesn't have an implicit constructor."); | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		registered[mark] = objClass; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Load binary from file and cast. | 
				
			||||
	 */ | 
				
			||||
	public static <T extends IonBinary> T fromFile(String path) throws IOException | 
				
			||||
	{ | 
				
			||||
		return fromFile(new File(path)); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Load binary from file and cast. | 
				
			||||
	 */ | 
				
			||||
	public static <T extends IonBinary> T fromFile(File file) throws IOException | 
				
			||||
	{ | 
				
			||||
		try(InputStream in = new FileInputStream(file)) { | 
				
			||||
			return fromStream(in); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Load bundled from file and unwrap. | 
				
			||||
	 */ | 
				
			||||
	public static <T extends IonBundled> T fromFile(String path, Class<? extends T> objClass) throws IOException | 
				
			||||
	{ | 
				
			||||
		return fromFile(new File(path), objClass); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Load bundled from file and unwrap. | 
				
			||||
	 */ | 
				
			||||
	public static <T extends IonBundled> T fromFile(File file, Class<? extends T> objClass) throws IOException | 
				
			||||
	{ | 
				
			||||
		try(InputStream in = new FileInputStream(file)) { | 
				
			||||
			 | 
				
			||||
			return fromStream(in, objClass); | 
				
			||||
			 | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public static void toFile(String path, IonBundled obj) throws IOException | 
				
			||||
	{ | 
				
			||||
		toFile(new File(path), obj); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Wrap bundled and save to file. | 
				
			||||
	 */ | 
				
			||||
	public static void toFile(File file, IonBundled obj) throws IOException | 
				
			||||
	{ | 
				
			||||
		toFile(file, wrap(obj)); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Write binary to file with mark. | 
				
			||||
	 */ | 
				
			||||
	public static void toFile(String path, IonBinary obj) throws IOException | 
				
			||||
	{ | 
				
			||||
		toFile(new File(path), obj); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Write binary to file with mark. | 
				
			||||
	 */ | 
				
			||||
	public static void toFile(File file, IonBinary obj) throws IOException | 
				
			||||
	{ | 
				
			||||
		try(OutputStream out = new FileOutputStream(file)) { | 
				
			||||
			 | 
				
			||||
			toStream(out, obj); | 
				
			||||
			 | 
				
			||||
			out.flush(); | 
				
			||||
			out.close(); | 
				
			||||
		} catch (final Exception e) { | 
				
			||||
			throw new IOException("Error writing to ION file.", e); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Load object from stream based on mark, try to cast. | 
				
			||||
	 */ | 
				
			||||
	public static <T> T fromStream(InputStream in) throws IOException | 
				
			||||
	{ | 
				
			||||
		final IonInput inp = new IonInput(in); | 
				
			||||
		 | 
				
			||||
		return (T) inp.readObject(); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Load bundled object from stream, unwrap. | 
				
			||||
	 */ | 
				
			||||
	public static <T extends IonBundled> T fromStream(InputStream in, Class<? extends T> objClass) throws IOException | 
				
			||||
	{ | 
				
			||||
		return unwrap(new IonInput(in).readBundle(), objClass); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Write object to output with a mark. | 
				
			||||
	 */ | 
				
			||||
	public static void toStream(OutputStream out, IonBinary obj) throws IOException | 
				
			||||
	{ | 
				
			||||
		new IonOutput(out).writeObject(obj); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Create new bundle and write the object to it. | 
				
			||||
	 */ | 
				
			||||
	public static IonBundle wrap(IonBundled content) throws IOException | 
				
			||||
	{ | 
				
			||||
		final IonBundle ib = new IonBundle(); | 
				
			||||
		content.save(ib); | 
				
			||||
		return ib; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Try to unwrap an object from bundle. The object class must have implicit | 
				
			||||
	 * accessible constructor. | 
				
			||||
	 *  | 
				
			||||
	 * @param bundle unwrapped bundle | 
				
			||||
	 * @param objClass class of desired object | 
				
			||||
	 * @return the object unwrapped | 
				
			||||
	 * @throws IOException | 
				
			||||
	 */ | 
				
			||||
	public static <T extends IonBundled> T unwrap(IonBundle 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 " + Log.str(objClass) + "."); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@SuppressWarnings("unchecked") | 
				
			||||
	static Class<? extends IonBinary> getClassForMark(int mark) | 
				
			||||
	{ | 
				
			||||
		return registered[mark]; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * @return true if the mark is for a registered {@link IonBinary} object | 
				
			||||
	 */ | 
				
			||||
	static boolean isMarkForBinary(int mark) | 
				
			||||
	{ | 
				
			||||
		return registered[mark] != null; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Make sure object is registered in the table | 
				
			||||
	 *  | 
				
			||||
	 * @throws IOException if not registered or class mismatch | 
				
			||||
	 */ | 
				
			||||
	static void assertRegistered(IonBinary obj) throws IOException | 
				
			||||
	{ | 
				
			||||
		final int mark = obj.getIonMark(); | 
				
			||||
		 | 
				
			||||
		final Class<? extends IonBinary> clz = Ion.getClassForMark(mark); | 
				
			||||
		 | 
				
			||||
		if (clz == null) { | 
				
			||||
			throw new IOException("Not registered - mark: " + mark + ", class: " + Log.str(obj.getClass())); | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		if (clz != obj.getClass()) { | 
				
			||||
			throw new IOException("Class mismatch - mark: " + mark + ", class: " + Log.str(obj.getClass())); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,39 @@ | 
				
			||||
package mightypork.util.ion; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
import java.io.IOException; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * Binary ion object | 
				
			||||
 *  | 
				
			||||
 * @author MightyPork | 
				
			||||
 */ | 
				
			||||
public interface IonBinary { | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Load data from the input stream. | 
				
			||||
	 *  | 
				
			||||
	 * @param in input stream | 
				
			||||
	 * @throws IOException | 
				
			||||
	 */ | 
				
			||||
	void load(IonInput in) throws IOException; | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Store data to output stream (in such way that the load method will later | 
				
			||||
	 * be able to read it). | 
				
			||||
	 *  | 
				
			||||
	 * @param out Output stream | 
				
			||||
	 * @throws IOException | 
				
			||||
	 */ | 
				
			||||
	void save(IonOutput out) throws IOException; | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Get Ion mark byte. | 
				
			||||
	 *  | 
				
			||||
	 * @return Ion mark byte. | 
				
			||||
	 */ | 
				
			||||
	public short getIonMark(); | 
				
			||||
} | 
				
			||||
@ -0,0 +1,284 @@ | 
				
			||||
package mightypork.util.ion; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
import java.io.IOException; | 
				
			||||
import java.util.ArrayList; | 
				
			||||
import java.util.Collection; | 
				
			||||
import java.util.HashMap; | 
				
			||||
import java.util.Map; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * Ion data bundle - simplified Map | 
				
			||||
 *  | 
				
			||||
 * @author MightyPork | 
				
			||||
 */ | 
				
			||||
public class IonBundle implements IonBinary { | 
				
			||||
	 | 
				
			||||
	private final Map<String, Object> backingMap = new HashMap<>(); | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void putBundled(String key, IonBundled saved) throws IOException | 
				
			||||
	{ | 
				
			||||
		final IonBundle ib = new IonBundle(); | 
				
			||||
		saved.save(ib); | 
				
			||||
		put(key, ib); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public <T extends IonBundled> T getBundled(String key, Class<T> objClass) throws IOException | 
				
			||||
	{ | 
				
			||||
		return Ion.unwrap(get(key, (IonBundle) null), objClass); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void loadBundled(String key, IonBundled loaded) throws IOException | 
				
			||||
	{ | 
				
			||||
		IonBundle ib = get(key, null); | 
				
			||||
		 | 
				
			||||
		if (ib == null) ib = new IonBundle(); | 
				
			||||
		 | 
				
			||||
		loaded.load(ib); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public <K, V> Map<K, V> getMap(String key) | 
				
			||||
	{ | 
				
			||||
		final Map<K, V> m = new HashMap<>(); | 
				
			||||
		loadMap(key, m); | 
				
			||||
		return m; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public <K, V> void loadMap(String key, Map<K, V> map) | 
				
			||||
	{ | 
				
			||||
		final IonMapWrapper imw = get(key, null); | 
				
			||||
		if (imw == null) return; | 
				
			||||
		map.clear(); | 
				
			||||
		imw.fill(map); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public <E> Collection<E> getSequence(String key) | 
				
			||||
	{ | 
				
			||||
		final Collection<E> s = new ArrayList<>(); | 
				
			||||
		loadSequence(key, s); | 
				
			||||
		return s; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public <E> void loadSequence(String key, Collection<E> sequence) | 
				
			||||
	{ | 
				
			||||
		final IonSequenceWrapper isw = get(key, null); | 
				
			||||
		if (isw == null) return; | 
				
			||||
		sequence.clear(); | 
				
			||||
		isw.fill(sequence); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * <p> | 
				
			||||
	 * Get an object. | 
				
			||||
	 * </p> | 
				
			||||
	 * <p> | 
				
			||||
	 * If not found or of type incompatible with fallback, fallback is returned. | 
				
			||||
	 * </p> | 
				
			||||
	 *  | 
				
			||||
	 * @param key | 
				
			||||
	 * @param fallback value | 
				
			||||
	 * @return value | 
				
			||||
	 */ | 
				
			||||
	public <T> T get(String key, T fallback) | 
				
			||||
	{ | 
				
			||||
		try { | 
				
			||||
			final T itm = (T) backingMap.get(key); | 
				
			||||
			if (itm == null) return fallback; | 
				
			||||
			return itm; | 
				
			||||
		} catch (final ClassCastException e) { | 
				
			||||
			return fallback; | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void put(String key, IonBinary value) | 
				
			||||
	{ | 
				
			||||
		if (key == null || value == null) return; | 
				
			||||
		backingMap.put(key, value); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void put(String key, boolean value) | 
				
			||||
	{ | 
				
			||||
		backingMap.put(key, value); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void put(String key, char value) | 
				
			||||
	{ | 
				
			||||
		backingMap.put(key, value); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void put(String key, short value) | 
				
			||||
	{ | 
				
			||||
		backingMap.put(key, value); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void put(String key, int value) | 
				
			||||
	{ | 
				
			||||
		backingMap.put(key, value); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void put(String key, long value) | 
				
			||||
	{ | 
				
			||||
		backingMap.put(key, value); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void put(String key, double value) | 
				
			||||
	{ | 
				
			||||
		backingMap.put(key, value); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void put(String key, float value) | 
				
			||||
	{ | 
				
			||||
		backingMap.put(key, value); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void put(String key, String value) | 
				
			||||
	{ | 
				
			||||
		backingMap.put(key, value); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void put(String key, boolean[] value) | 
				
			||||
	{ | 
				
			||||
		backingMap.put(key, value); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void put(String key, char[] value) | 
				
			||||
	{ | 
				
			||||
		backingMap.put(key, value); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void put(String key, short[] value) | 
				
			||||
	{ | 
				
			||||
		backingMap.put(key, value); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void put(String key, int[] value) | 
				
			||||
	{ | 
				
			||||
		backingMap.put(key, value); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void put(String key, long[] value) | 
				
			||||
	{ | 
				
			||||
		backingMap.put(key, value); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void put(String key, double[] value) | 
				
			||||
	{ | 
				
			||||
		backingMap.put(key, value); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void put(String key, float[] value) | 
				
			||||
	{ | 
				
			||||
		backingMap.put(key, value); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void put(String key, String[] value) | 
				
			||||
	{ | 
				
			||||
		backingMap.put(key, value); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@SuppressWarnings("rawtypes") | 
				
			||||
	public void putSequence(String key, Collection c) | 
				
			||||
	{ | 
				
			||||
		backingMap.put(key, new IonSequenceWrapper(c)); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@SuppressWarnings("rawtypes") | 
				
			||||
	public void putMap(String key, Map m) | 
				
			||||
	{ | 
				
			||||
		backingMap.put(key, new IonMapWrapper(m)); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public short getIonMark() | 
				
			||||
	{ | 
				
			||||
		return Ion.DATA_BUNDLE; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public void load(IonInput in) throws IOException | 
				
			||||
	{ | 
				
			||||
		in.readMap(backingMap); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public void save(IonOutput out) throws IOException | 
				
			||||
	{ | 
				
			||||
		out.writeMap(backingMap); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public int size() | 
				
			||||
	{ | 
				
			||||
		return backingMap.size(); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public boolean isEmpty() | 
				
			||||
	{ | 
				
			||||
		return backingMap.isEmpty(); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void clear() | 
				
			||||
	{ | 
				
			||||
		backingMap.clear(); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public Object remove(Object key) | 
				
			||||
	{ | 
				
			||||
		return backingMap.remove(key); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public String toString() | 
				
			||||
	{ | 
				
			||||
		return backingMap.toString(); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public boolean equals(Object o) | 
				
			||||
	{ | 
				
			||||
		return backingMap.equals(o); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public int hashCode() | 
				
			||||
	{ | 
				
			||||
		return 47 ^ backingMap.hashCode(); | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -0,0 +1,18 @@ | 
				
			||||
package mightypork.util.ion; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
import java.io.IOException; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * Bundled ion object | 
				
			||||
 *  | 
				
			||||
 * @author MightyPork | 
				
			||||
 */ | 
				
			||||
public interface IonBundled { | 
				
			||||
	 | 
				
			||||
	void load(IonBundle bundle) throws IOException; | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	void save(IonBundle bundle) throws IOException; | 
				
			||||
} | 
				
			||||
@ -0,0 +1,439 @@ | 
				
			||||
package mightypork.util.ion; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
import java.io.DataInput; | 
				
			||||
import java.io.DataInputStream; | 
				
			||||
import java.io.IOException; | 
				
			||||
import java.io.InputStream; | 
				
			||||
import java.util.ArrayList; | 
				
			||||
import java.util.Collection; | 
				
			||||
import java.util.HashMap; | 
				
			||||
import java.util.Map; | 
				
			||||
 | 
				
			||||
import mightypork.util.error.CorruptedDataException; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * Ion input stream | 
				
			||||
 *  | 
				
			||||
 * @author MightyPork | 
				
			||||
 */ | 
				
			||||
public class IonInput { | 
				
			||||
	 | 
				
			||||
	private final DataInput in; | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public IonInput(InputStream in) | 
				
			||||
	{ | 
				
			||||
		this.in = new DataInputStream(in); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Read int 0-255. Suitable when the int was written using | 
				
			||||
	 * <code>writeIntByte()</code> method. | 
				
			||||
	 *  | 
				
			||||
	 * @return int | 
				
			||||
	 * @throws IOException | 
				
			||||
	 */ | 
				
			||||
	public int readIntByte() throws IOException | 
				
			||||
	{ | 
				
			||||
		return in.readUnsignedByte(); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Read an int 0-65535. Suitable when the int was written using | 
				
			||||
	 * <code>writeIntShort()</code> method. | 
				
			||||
	 *  | 
				
			||||
	 * @return int | 
				
			||||
	 * @throws IOException | 
				
			||||
	 */ | 
				
			||||
	public int readIntShort() throws IOException | 
				
			||||
	{ | 
				
			||||
		return in.readUnsignedShort(); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public boolean readBoolean() throws IOException | 
				
			||||
	{ | 
				
			||||
		return in.readBoolean(); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public byte readByte() throws IOException | 
				
			||||
	{ | 
				
			||||
		return in.readByte(); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public short readShort() throws IOException | 
				
			||||
	{ | 
				
			||||
		return in.readShort(); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public char readChar() throws IOException | 
				
			||||
	{ | 
				
			||||
		return in.readChar(); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public int readInt() throws IOException | 
				
			||||
	{ | 
				
			||||
		return in.readInt(); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public long readLong() throws IOException | 
				
			||||
	{ | 
				
			||||
		return in.readLong(); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public float readFloat() throws IOException | 
				
			||||
	{ | 
				
			||||
		return in.readFloat(); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public double readDouble() throws IOException | 
				
			||||
	{ | 
				
			||||
		return in.readDouble(); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public String readString() throws IOException | 
				
			||||
	{ | 
				
			||||
		return in.readUTF(); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public boolean[] readBooleans() throws IOException | 
				
			||||
	{ | 
				
			||||
		final int length = readLength(); | 
				
			||||
		final boolean[] arr = new boolean[length]; | 
				
			||||
		for (int i = 0; i < length; i++) { | 
				
			||||
			arr[i] = in.readBoolean(); | 
				
			||||
		} | 
				
			||||
		return arr; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public byte[] readBytes() throws IOException | 
				
			||||
	{ | 
				
			||||
		final int length = readLength(); | 
				
			||||
		final byte[] arr = new byte[length]; | 
				
			||||
		for (int i = 0; i < length; i++) { | 
				
			||||
			arr[i] = in.readByte(); | 
				
			||||
		} | 
				
			||||
		return arr; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public char[] readChars() throws IOException | 
				
			||||
	{ | 
				
			||||
		final int length = readLength(); | 
				
			||||
		final char[] arr = new char[length]; | 
				
			||||
		for (int i = 0; i < length; i++) { | 
				
			||||
			arr[i] = in.readChar(); | 
				
			||||
		} | 
				
			||||
		return arr; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public short[] readShorts() throws IOException | 
				
			||||
	{ | 
				
			||||
		final int length = readLength(); | 
				
			||||
		final short[] arr = new short[length]; | 
				
			||||
		for (int i = 0; i < length; i++) { | 
				
			||||
			arr[i] = in.readShort(); | 
				
			||||
		} | 
				
			||||
		return arr; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public int[] readInts() throws IOException | 
				
			||||
	{ | 
				
			||||
		final int length = readLength(); | 
				
			||||
		final int[] arr = new int[length]; | 
				
			||||
		for (int i = 0; i < length; i++) { | 
				
			||||
			arr[i] = in.readInt(); | 
				
			||||
		} | 
				
			||||
		return arr; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public long[] readLongs() throws IOException | 
				
			||||
	{ | 
				
			||||
		final int length = readLength(); | 
				
			||||
		final long[] arr = new long[length]; | 
				
			||||
		for (int i = 0; i < length; i++) { | 
				
			||||
			arr[i] = in.readLong(); | 
				
			||||
		} | 
				
			||||
		return arr; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public float[] readFloats() throws IOException | 
				
			||||
	{ | 
				
			||||
		final int length = readLength(); | 
				
			||||
		final float[] arr = new float[length]; | 
				
			||||
		for (int i = 0; i < length; i++) { | 
				
			||||
			arr[i] = in.readFloat(); | 
				
			||||
		} | 
				
			||||
		return arr; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public double[] readDoubles() throws IOException | 
				
			||||
	{ | 
				
			||||
		final int length = readLength(); | 
				
			||||
		final double[] arr = new double[length]; | 
				
			||||
		for (int i = 0; i < length; i++) { | 
				
			||||
			arr[i] = in.readDouble(); | 
				
			||||
		} | 
				
			||||
		return arr; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public String[] readStrings() throws IOException | 
				
			||||
	{ | 
				
			||||
		final int length = readLength(); | 
				
			||||
		final String[] arr = new String[length]; | 
				
			||||
		for (int i = 0; i < length; i++) { | 
				
			||||
			arr[i] = in.readUTF(); | 
				
			||||
		} | 
				
			||||
		return arr; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public Object[] readObjects() throws IOException | 
				
			||||
	{ | 
				
			||||
		final int length = readLength(); | 
				
			||||
		final Object[] arr = new Object[length]; | 
				
			||||
		for (int i = 0; i < length; i++) { | 
				
			||||
			arr[i] = readObject(); | 
				
			||||
		} | 
				
			||||
		return arr; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public IonBundle readBundle() throws IOException | 
				
			||||
	{ | 
				
			||||
		return (IonBundle) readObject(); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	private int readMark() throws IOException | 
				
			||||
	{ | 
				
			||||
		return readIntByte(); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	private int readLength() throws IOException | 
				
			||||
	{ | 
				
			||||
		return readIntShort(); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * <p> | 
				
			||||
	 * Read object based on mark; if null mark is found, returns default value. | 
				
			||||
	 * </p> | 
				
			||||
	 * <p> | 
				
			||||
	 * If, however, an object of invalid or different type is found, an | 
				
			||||
	 * exception will be thrown. | 
				
			||||
	 * </p> | 
				
			||||
	 *  | 
				
			||||
	 * @param def default value. | 
				
			||||
	 * @return the loaded object | 
				
			||||
	 * @throws IOException | 
				
			||||
	 */ | 
				
			||||
	@SuppressWarnings("unchecked") | 
				
			||||
	public <T> T readObject(T def) throws IOException | 
				
			||||
	{ | 
				
			||||
		try { | 
				
			||||
			final Object o = readObject(); | 
				
			||||
			return (T) (o == null ? def : o); | 
				
			||||
		} catch (final Exception e) { | 
				
			||||
			throw new IOException("Could not load object.", e); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Read single object, preceded by a mark. | 
				
			||||
	 *  | 
				
			||||
	 * @return the loaded object | 
				
			||||
	 * @throws IOException | 
				
			||||
	 */ | 
				
			||||
	public Object readObject() throws IOException | 
				
			||||
	{ | 
				
			||||
		final int mark = readMark(); | 
				
			||||
		if (Ion.isMarkForBinary(mark)) { | 
				
			||||
			IonBinary loaded; | 
				
			||||
			 | 
				
			||||
			try { | 
				
			||||
				 | 
				
			||||
				loaded = Ion.getClassForMark(mark).newInstance(); | 
				
			||||
				 | 
				
			||||
			} catch (InstantiationException | IllegalAccessException e) { | 
				
			||||
				throw new RuntimeException("Couldn not load object with mark: " + mark, e); | 
				
			||||
			} | 
				
			||||
			 | 
				
			||||
			loaded.load(this); | 
				
			||||
			return loaded; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		switch (mark) { | 
				
			||||
			case Ion.NULL: | 
				
			||||
				return null; | 
				
			||||
				 | 
				
			||||
			case Ion.BOOLEAN: | 
				
			||||
				return readBoolean(); | 
				
			||||
				 | 
				
			||||
			case Ion.BYTE: | 
				
			||||
				return readByte(); | 
				
			||||
				 | 
				
			||||
			case Ion.CHAR: | 
				
			||||
				return readChar(); | 
				
			||||
				 | 
				
			||||
			case Ion.SHORT: | 
				
			||||
				return readShort(); | 
				
			||||
				 | 
				
			||||
			case Ion.INT: | 
				
			||||
				return readInt(); | 
				
			||||
				 | 
				
			||||
			case Ion.LONG: | 
				
			||||
				return readLong(); | 
				
			||||
				 | 
				
			||||
			case Ion.FLOAT: | 
				
			||||
				return readFloat(); | 
				
			||||
				 | 
				
			||||
			case Ion.DOUBLE: | 
				
			||||
				return readDouble(); | 
				
			||||
				 | 
				
			||||
			case Ion.STRING: | 
				
			||||
				return readString(); | 
				
			||||
				 | 
				
			||||
			case Ion.BOOLEAN_ARRAY: | 
				
			||||
				return readBooleans(); | 
				
			||||
				 | 
				
			||||
			case Ion.BYTE_ARRAY: | 
				
			||||
				return readBytes(); | 
				
			||||
				 | 
				
			||||
			case Ion.CHAR_ARRAY: | 
				
			||||
				return readChars(); | 
				
			||||
				 | 
				
			||||
			case Ion.SHORT_ARRAY: | 
				
			||||
				return readShorts(); | 
				
			||||
				 | 
				
			||||
			case Ion.INT_ARRAY: | 
				
			||||
				return readInts(); | 
				
			||||
				 | 
				
			||||
			case Ion.LONG_ARRAY: | 
				
			||||
				return readLongs(); | 
				
			||||
				 | 
				
			||||
			case Ion.FLOAT_ARRAY: | 
				
			||||
				return readFloats(); | 
				
			||||
				 | 
				
			||||
			case Ion.DOUBLE_ARRAY: | 
				
			||||
				return readDoubles(); | 
				
			||||
				 | 
				
			||||
			case Ion.STRING_ARRAY: | 
				
			||||
				return readStrings(); | 
				
			||||
				 | 
				
			||||
			default: | 
				
			||||
				throw new CorruptedDataException("Invalid mark: " + mark); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Reads mark and returns true if the mark is ENTRY, false if the mark is | 
				
			||||
	 * END. Throws an exception otherwise. | 
				
			||||
	 *  | 
				
			||||
	 * @return mark was ENTRY | 
				
			||||
	 * @throws IOException when the mark is neither ENTRY or END. | 
				
			||||
	 */ | 
				
			||||
	public boolean hasNextEntry() throws IOException | 
				
			||||
	{ | 
				
			||||
		final int mark = readMark(); | 
				
			||||
		if (mark == Ion.ENTRY) return true; | 
				
			||||
		if (mark == Ion.END) return false; | 
				
			||||
		 | 
				
			||||
		throw new CorruptedDataException("Unexpected mark in sequence: " + mark); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Read a sequence of elements into an ArrayList | 
				
			||||
	 *  | 
				
			||||
	 * @return the collection | 
				
			||||
	 * @throws IOException | 
				
			||||
	 */ | 
				
			||||
	public <T> Collection<T> readSequence() throws IOException | 
				
			||||
	{ | 
				
			||||
		return readSequence(new ArrayList<T>()); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Load entries into a collection. The collection is cleaned first. | 
				
			||||
	 *  | 
				
			||||
	 * @param filled collection to populate | 
				
			||||
	 * @return the collection | 
				
			||||
	 * @throws IOException | 
				
			||||
	 */ | 
				
			||||
	@SuppressWarnings("unchecked") | 
				
			||||
	public <T> Collection<T> readSequence(Collection<T> filled) throws IOException | 
				
			||||
	{ | 
				
			||||
		try { | 
				
			||||
			filled.clear(); | 
				
			||||
			while (hasNextEntry()) { | 
				
			||||
				filled.add((T) readObject()); | 
				
			||||
			} | 
				
			||||
			return filled; | 
				
			||||
		} catch (final ClassCastException e) { | 
				
			||||
			throw new CorruptedDataException("Unexpected element type in sequence.", e); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Read element pairs into a HashMap | 
				
			||||
	 *  | 
				
			||||
	 * @return the map | 
				
			||||
	 * @throws IOException | 
				
			||||
	 */ | 
				
			||||
	public <K, V> Map<K, V> readMap() throws IOException | 
				
			||||
	{ | 
				
			||||
		return readMap(new HashMap<K, V>()); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Load data into a map. The map is cleaned first. | 
				
			||||
	 *  | 
				
			||||
	 * @param filled filled map | 
				
			||||
	 * @return the map | 
				
			||||
	 * @throws IOException | 
				
			||||
	 */ | 
				
			||||
	@SuppressWarnings("unchecked") | 
				
			||||
	public <K, V> Map<K, V> readMap(Map<K, V> filled) throws IOException | 
				
			||||
	{ | 
				
			||||
		try { | 
				
			||||
			filled.clear(); | 
				
			||||
			while (hasNextEntry()) { | 
				
			||||
				final K key = (K) readObject(); | 
				
			||||
				final V value = (V) readObject(); | 
				
			||||
				 | 
				
			||||
				filled.put(key, value); | 
				
			||||
			} | 
				
			||||
			return filled; | 
				
			||||
		} catch (final ClassCastException e) { | 
				
			||||
			throw new CorruptedDataException("Unexpected element type in map.", e); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -0,0 +1,55 @@ | 
				
			||||
package mightypork.util.ion; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
import java.io.IOException; | 
				
			||||
import java.util.HashMap; | 
				
			||||
import java.util.Map; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
@SuppressWarnings({ "rawtypes", "unchecked" }) | 
				
			||||
public class IonMapWrapper implements IonBinary { | 
				
			||||
	 | 
				
			||||
	private final Map map; | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public IonMapWrapper() | 
				
			||||
	{ | 
				
			||||
		map = new HashMap(); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public IonMapWrapper(Map saved) | 
				
			||||
	{ | 
				
			||||
		map = saved; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public void load(IonInput in) throws IOException | 
				
			||||
	{ | 
				
			||||
		map.clear(); | 
				
			||||
		in.readMap(map); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public void save(IonOutput out) throws IOException | 
				
			||||
	{ | 
				
			||||
		out.writeMap(map); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void fill(Map o) | 
				
			||||
	{ | 
				
			||||
		o.clear(); | 
				
			||||
		o.putAll(map); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public short getIonMark() | 
				
			||||
	{ | 
				
			||||
		return Ion.MAP_WRAPPER; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,383 @@ | 
				
			||||
package mightypork.util.ion; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
import java.io.DataOutput; | 
				
			||||
import java.io.DataOutputStream; | 
				
			||||
import java.io.IOException; | 
				
			||||
import java.io.OutputStream; | 
				
			||||
import java.util.Collection; | 
				
			||||
import java.util.Map; | 
				
			||||
import java.util.Map.Entry; | 
				
			||||
 | 
				
			||||
import mightypork.util.logging.Log; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * Ion output stream | 
				
			||||
 *  | 
				
			||||
 * @author MightyPork | 
				
			||||
 */ | 
				
			||||
public class IonOutput { | 
				
			||||
	 | 
				
			||||
	private final DataOutput out; | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public IonOutput(OutputStream out) | 
				
			||||
	{ | 
				
			||||
		this.out = new DataOutputStream(out); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void writeBoolean(boolean a) throws IOException | 
				
			||||
	{ | 
				
			||||
		out.writeBoolean(a); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void writeByte(int a) throws IOException | 
				
			||||
	{ | 
				
			||||
		out.writeByte(a); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void writeShort(int a) throws IOException | 
				
			||||
	{ | 
				
			||||
		out.writeShort(a); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void writeChar(int a) throws IOException | 
				
			||||
	{ | 
				
			||||
		out.writeChar(a); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void writeInt(int a) throws IOException | 
				
			||||
	{ | 
				
			||||
		out.writeInt(a); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void writeIntShort(int a) throws IOException | 
				
			||||
	{ | 
				
			||||
		out.writeShort(a); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void writeIntByte(int a) throws IOException | 
				
			||||
	{ | 
				
			||||
		out.writeByte(a); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void writeLong(long a) throws IOException | 
				
			||||
	{ | 
				
			||||
		out.writeLong(a); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void writeFloat(float a) throws IOException | 
				
			||||
	{ | 
				
			||||
		out.writeFloat(a); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void writeDouble(double a) throws IOException | 
				
			||||
	{ | 
				
			||||
		out.writeDouble(a); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void writeBytes(String a) throws IOException | 
				
			||||
	{ | 
				
			||||
		out.writeBytes(a); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void writeString(String a) throws IOException | 
				
			||||
	{ | 
				
			||||
		out.writeUTF(a); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void writeBooleans(boolean[] arr) throws IOException | 
				
			||||
	{ | 
				
			||||
		writeLength(arr.length); | 
				
			||||
		for (final boolean a : arr) { | 
				
			||||
			out.writeBoolean(a); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void writeBytes(byte[] arr) throws IOException | 
				
			||||
	{ | 
				
			||||
		writeLength(arr.length); | 
				
			||||
		for (final byte a : arr) { | 
				
			||||
			out.writeByte(a); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void writeChars(char[] arr) throws IOException | 
				
			||||
	{ | 
				
			||||
		writeLength(arr.length); | 
				
			||||
		for (final char a : arr) { | 
				
			||||
			out.writeChar(a); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void writeShorts(short[] arr) throws IOException | 
				
			||||
	{ | 
				
			||||
		writeLength(arr.length); | 
				
			||||
		for (final short a : arr) { | 
				
			||||
			out.writeShort(a); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void writeInts(int[] arr) throws IOException | 
				
			||||
	{ | 
				
			||||
		writeLength(arr.length); | 
				
			||||
		for (final int a : arr) { | 
				
			||||
			out.writeInt(a); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void writeLongs(long[] arr) throws IOException | 
				
			||||
	{ | 
				
			||||
		writeLength(arr.length); | 
				
			||||
		for (final long a : arr) { | 
				
			||||
			out.writeLong(a); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void writeFloats(float[] arr) throws IOException | 
				
			||||
	{ | 
				
			||||
		writeLength(arr.length); | 
				
			||||
		for (final float a : arr) { | 
				
			||||
			out.writeFloat(a); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void writeDoubles(double[] arr) throws IOException | 
				
			||||
	{ | 
				
			||||
		writeLength(arr.length); | 
				
			||||
		for (final double a : arr) { | 
				
			||||
			out.writeDouble(a); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void writeStrings(String[] arr) throws IOException | 
				
			||||
	{ | 
				
			||||
		writeLength(arr.length); | 
				
			||||
		for (final String a : arr) { | 
				
			||||
			out.writeUTF(a); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void writeBundle(IonBundle bundle) throws IOException | 
				
			||||
	{ | 
				
			||||
		writeObject(bundle); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Write array of objects. Supported are Ionizables, primitive types, | 
				
			||||
	 * String, and their arrays. | 
				
			||||
	 *  | 
				
			||||
	 * @param arr array to write | 
				
			||||
	 * @throws IOException on IO error or on invalid object type. | 
				
			||||
	 */ | 
				
			||||
	public void writeObjects(Object[] arr) throws IOException | 
				
			||||
	{ | 
				
			||||
		writeLength(arr.length); | 
				
			||||
		for (final Object a : arr) { | 
				
			||||
			writeObject(a); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public <T> void writeSequence(Collection<T> sequence) throws IOException | 
				
			||||
	{ | 
				
			||||
		for (final T element : sequence) { | 
				
			||||
			writeMark(Ion.ENTRY); | 
				
			||||
			writeObject(element); | 
				
			||||
		} | 
				
			||||
		writeMark(Ion.END); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public <K, V> void writeMap(Map<K, V> map) throws IOException | 
				
			||||
	{ | 
				
			||||
		for (final Entry<K, V> e : map.entrySet()) { | 
				
			||||
			if (e.getValue() == null) { | 
				
			||||
				continue; | 
				
			||||
			} | 
				
			||||
			 | 
				
			||||
			writeMark(Ion.ENTRY); | 
				
			||||
			writeObject(e.getKey()); | 
				
			||||
			writeObject(e.getValue()); | 
				
			||||
		} | 
				
			||||
		writeMark(Ion.END); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	private void writeMark(int mark) throws IOException | 
				
			||||
	{ | 
				
			||||
		writeIntByte(mark); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	private void writeLength(int length) throws IOException | 
				
			||||
	{ | 
				
			||||
		writeIntShort(length); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	/** | 
				
			||||
	 * Write an object. Supported are Ionizable, primitive types, String, and | 
				
			||||
	 * their arrays. | 
				
			||||
	 *  | 
				
			||||
	 * @param obj obj to write | 
				
			||||
	 * @throws IOException on IO error or invalid object type. | 
				
			||||
	 */ | 
				
			||||
	public void writeObject(Object obj) throws IOException | 
				
			||||
	{ | 
				
			||||
		if (obj == null) { | 
				
			||||
			writeMark(Ion.NULL); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		if (obj instanceof IonBinary) { | 
				
			||||
			 | 
				
			||||
			final IonBinary ionObject = (IonBinary) obj; | 
				
			||||
			 | 
				
			||||
			Ion.assertRegistered(ionObject); | 
				
			||||
			 | 
				
			||||
			writeMark(ionObject.getIonMark()); | 
				
			||||
			ionObject.save(this); | 
				
			||||
			 | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		if (obj instanceof IonBundled) { | 
				
			||||
			throw new IOException("Bundled objects cannot be written to ION stream directly."); | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		if (obj instanceof Boolean) { | 
				
			||||
			writeMark(Ion.BOOLEAN); | 
				
			||||
			writeBoolean((Boolean) obj); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		if (obj instanceof Byte) { | 
				
			||||
			writeMark(Ion.BYTE); | 
				
			||||
			writeByte((Byte) obj); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		if (obj instanceof Character) { | 
				
			||||
			writeMark(Ion.CHAR); | 
				
			||||
			writeChar((Character) obj); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		if (obj instanceof Short) { | 
				
			||||
			writeMark(Ion.SHORT); | 
				
			||||
			writeShort((Short) obj); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		if (obj instanceof Integer) { | 
				
			||||
			writeMark(Ion.INT); | 
				
			||||
			writeInt((Integer) obj); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		if (obj instanceof Long) { | 
				
			||||
			writeMark(Ion.LONG); | 
				
			||||
			writeLong((Long) obj); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		if (obj instanceof Float) { | 
				
			||||
			writeMark(Ion.FLOAT); | 
				
			||||
			writeFloat((Float) obj); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		if (obj instanceof Double) { | 
				
			||||
			writeMark(Ion.DOUBLE); | 
				
			||||
			writeDouble((Double) obj); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		if (obj instanceof String) { | 
				
			||||
			writeMark(Ion.STRING); | 
				
			||||
			writeString((String) obj); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		if (obj instanceof boolean[]) { | 
				
			||||
			writeMark(Ion.BOOLEAN_ARRAY); | 
				
			||||
			writeBooleans((boolean[]) obj); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		if (obj instanceof byte[]) { | 
				
			||||
			writeMark(Ion.BYTE_ARRAY); | 
				
			||||
			writeBytes((byte[]) obj); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		if (obj instanceof char[]) { | 
				
			||||
			writeMark(Ion.CHAR_ARRAY); | 
				
			||||
			writeChars((char[]) obj); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		if (obj instanceof short[]) { | 
				
			||||
			writeMark(Ion.SHORT_ARRAY); | 
				
			||||
			writeShorts((short[]) obj); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		if (obj instanceof int[]) { | 
				
			||||
			writeMark(Ion.INT_ARRAY); | 
				
			||||
			writeInts((int[]) obj); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		if (obj instanceof long[]) { | 
				
			||||
			writeMark(Ion.LONG_ARRAY); | 
				
			||||
			writeLongs((long[]) obj); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		if (obj instanceof float[]) { | 
				
			||||
			writeMark(Ion.FLOAT_ARRAY); | 
				
			||||
			writeFloats((float[]) obj); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		if (obj instanceof double[]) { | 
				
			||||
			writeMark(Ion.DOUBLE_ARRAY); | 
				
			||||
			writeDoubles((double[]) obj); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		if (obj instanceof String[]) { | 
				
			||||
			writeMark(Ion.STRING_ARRAY); | 
				
			||||
			writeStrings((String[]) obj); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		throw new IOException("Object " + Log.str(obj) + " could not be be written to stream."); | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -0,0 +1,55 @@ | 
				
			||||
package mightypork.util.ion; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
import java.io.IOException; | 
				
			||||
import java.util.ArrayList; | 
				
			||||
import java.util.Collection; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
@SuppressWarnings({ "rawtypes", "unchecked" }) | 
				
			||||
public class IonSequenceWrapper implements IonBinary { | 
				
			||||
	 | 
				
			||||
	private Collection collection = new ArrayList(); | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public IonSequenceWrapper() | 
				
			||||
	{ | 
				
			||||
		collection = new ArrayList(); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public IonSequenceWrapper(Collection saved) | 
				
			||||
	{ | 
				
			||||
		collection = saved; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public void load(IonInput in) throws IOException | 
				
			||||
	{ | 
				
			||||
		collection.clear(); | 
				
			||||
		in.readSequence(collection); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public void save(IonOutput out) throws IOException | 
				
			||||
	{ | 
				
			||||
		out.writeSequence(collection); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public void fill(Collection o) | 
				
			||||
	{ | 
				
			||||
		o.clear(); | 
				
			||||
		o.addAll(collection); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	@Override | 
				
			||||
	public short getIonMark() | 
				
			||||
	{ | 
				
			||||
		return Ion.SEQUENCE_WRAPPER; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
} | 
				
			||||
					Loading…
					
					
				
		Reference in new issue