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