Added support for arrays in ION (dense storing of primitive arrays)

v5stable
Ondřej Hruška 11 years ago
parent 4721351ed9
commit b70279acd5
  1. 25
      src/mightypork/test/TestIonArray.java
  2. 39
      src/mightypork/test/TestIonArray2.java
  3. 598
      src/mightypork/util/files/ion/Ion.java
  4. 10
      src/mightypork/util/objects/ObjectUtils.java

@ -0,0 +1,25 @@
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
{
byte[] array = new byte[1024 * 8];
Random rand = new Random();
for (int i = 0; i < array.length; i++) {
array[i] = (byte) rand.nextInt();
}
Ion.toFile(new File("hello.ion"), array);
}
}

@ -0,0 +1,39 @@
package mightypork.test;
import java.io.*;
import mightypork.util.files.ion.Ion;
public class TestIonArray2 {
public static void main(String[] args) throws IOException
{
int[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9,99999,8888888 };
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());
// ---
InputStream in = new FileInputStream("fuck.ion");
int[] a = Ion.readIntArray(in);
for (int i : a)
System.out.println(i);
String s = Ion.readString(in);
System.out.println(s);
char[] v = Ion.readCharArray(in);
for (int i : v)
System.out.print((char)i);
}
}

@ -17,32 +17,50 @@ import mightypork.util.logging.Log;
public class Ion { public class Ion {
/* /*
* 0-19 ... primitive and Java built-in types * 0-49 ... primitive and built-in types
* 20-39 ... technical marks * 60-79 ... technical marks
* 40-99 ... built-in ION types * 80-99 ... internal ION data types
*/ */
// primitives 0..19 // primitives 0..19
/** Null mark (for internal use) */ /** Null mark */
private static final short NULL = 0; private static final short NULL = 0;
/** Boolean mark (for internal use) */ /** Boolean mark */
private static final short BOOLEAN = 1; private static final short BOOLEAN = 1;
/** Byte mark (for internal use) */ /** Byte mark */
private static final short BYTE = 2; private static final short BYTE = 2;
/** Character mark (for internal use) */ /** Character mark */
private static final short CHAR = 3; private static final short CHAR = 3;
/** Short mark (for internal use) */ /** Short mark */
private static final short SHORT = 4; private static final short SHORT = 4;
/** Integer mark (for internal use) */ /** Integer mark */
private static final short INT = 5; private static final short INT = 5;
/** Long mark (for internal use) */ /** Long mark */
private static final short LONG = 6; private static final short LONG = 6;
/** Float mark (for internal use) */ /** Float mark */
private static final short FLOAT = 7; private static final short FLOAT = 7;
/** Double mark (for internal use) */ /** Double mark */
private static final short DOUBLE = 8; private static final short DOUBLE = 8;
/** String mark (for internal use) */ /** String mark */
private static final short STRING = 9; private static final short STRING = 9;
/** Boolean array mark */
private static final short BOOLEAN_ARRAY = 10;
/** Byte array mark */
private static final short BYTE_ARRAY = 11;
/** Character array mark */
private static final short CHAR_ARRAY = 12;
/** Short array mark */
private static final short SHORT_ARRAY = 13;
/** Integer array mark */
private static final short INT_ARRAY = 14;
/** Long array mark */
private static final short LONG_ARRAY = 15;
/** Float array mark */
private static final short FLOAT_ARRAY = 16;
/** Double array mark */
private static final short DOUBLE_ARRAY = 17;
/** String array mark */
private static final short STRING_ARRAY = 18;
// technical 20..39 // technical 20..39
@ -50,31 +68,25 @@ public class Ion {
* Entry mark - general purpose, marks an entry in sequence of objects. Used * Entry mark - general purpose, marks an entry in sequence of objects. Used
* to indicate that the sequence continues wityh another element. * to indicate that the sequence continues wityh another element.
*/ */
public static final short ENTRY = 20; public static final short ENTRY = 60;
/** /**
* Start mark - general purpose, marks start of a sequence of stored * Start mark - general purpose, marks start of a sequence of stored
* objects. * objects.
*/ */
public static final short START = 21; public static final short START = 61;
/** /**
* End mark - general purpose, marks end of sequence of stored objects. * End mark - general purpose, marks end of sequence of stored objects.
*/ */
public static final short END = 22; public static final short END = 62;
/** // built in 80..99
* Length mark, indicating length of something (such as array) - general
* purpose
*/
public static final short LENGTH = 23;
// built in 40..99
/** Map mark (built-in data structure) */ /** Map mark (built-in data structure) */
static final short DATA_BUNDLE = 40; static final short DATA_BUNDLE = 80;
/** List mark (built-in data structure) */ /** List mark (built-in data structure) */
static final short DATA_LIST = 41; static final short DATA_LIST = 81;
/** Ionizables<Mark, Class> */ /** Ionizables<Mark, Class> */
private static Map<Short, Class<?>> customIonizables = new HashMap<>(); private static Map<Short, Class<?>> customIonizables = new HashMap<>();
@ -102,8 +114,8 @@ public class Ion {
static { static {
markRangeChecking = false; markRangeChecking = false;
registerIonizable(Ion.DATA_BUNDLE, IonDataBundle.class); registerIonizable(DATA_BUNDLE, IonDataBundle.class);
registerIonizable(Ion.DATA_LIST, IonDataList.class); registerIonizable(DATA_LIST, IonDataList.class);
markRangeChecking = true; markRangeChecking = true;
} }
@ -114,7 +126,7 @@ public class Ion {
* *
* @param mark mark to be used. Numbers 0..99 are reserved. Mark is of type * @param mark mark to be used. Numbers 0..99 are reserved. Mark is of type
* Short, using values out of the short range will raise an * Short, using values out of the short range will raise an
* exception. * except
* @param objClass class of the registered Ionizable * @param objClass class of the registered Ionizable
*/ */
public static void registerIonizable(int mark, Class<?> objClass) public static void registerIonizable(int mark, Class<?> objClass)
@ -137,6 +149,19 @@ public class Ion {
} }
/**
* Load an object from file.
*
* @param path file path
* @return the loaded object
* @throws IOException on failure
*/
public static Object fromFile(String path) throws IOException
{
return fromFile(new File(path));
}
/** /**
* Load an object from file. * Load an object from file.
* *
@ -157,7 +182,6 @@ public class Ion {
} }
/** /**
* Store an object to file. * Store an object to file.
* *
@ -165,9 +189,22 @@ public class Ion {
* @param obj object to store * @param obj object to store
* @throws IOException * @throws IOException
*/ */
public static void toFile(File path, Object obj) throws IOException public static void toFile(String path, Object obj) throws IOException
{ {
try(OutputStream out = new FileOutputStream(path)) { toFile(new File(path), obj);
}
/**
* Store an object to file.
*
* @param file file
* @param obj object to store
* @throws IOException
*/
public static void toFile(File file, Object obj) throws IOException
{
try(OutputStream out = new FileOutputStream(file)) {
writeObject(out, obj); writeObject(out, obj);
@ -178,6 +215,7 @@ public class Ion {
} }
} }
/** /**
* Load an object from stream. * Load an object from stream.
* *
@ -231,37 +269,111 @@ public class Ion {
return ionObj; return ionObj;
} }
int length;
switch (mark) { switch (mark) {
case Ion.NULL: case NULL:
return null; return null;
case Ion.BOOLEAN: case BOOLEAN:
return readBoolean(in); return readBoolean(in);
case Ion.BYTE: case BYTE:
return readByte(in); return readByte(in);
case Ion.CHAR: case CHAR:
return readChar(in); return readChar(in);
case Ion.SHORT: case SHORT:
return readShort(in); return readShort(in);
case Ion.INT: case INT:
return readInt(in); return readInt(in);
case Ion.LONG: case LONG:
return readLong(in); return readLong(in);
case Ion.FLOAT: case FLOAT:
return readFloat(in); return readFloat(in);
case Ion.DOUBLE: case DOUBLE:
return readDouble(in); return readDouble(in);
case Ion.STRING: case STRING:
final String s = readString(in); return readString(in);
return s;
case BOOLEAN_ARRAY:
length = readInt(in);
boolean[] bools = new boolean[length];
for (int i = 0; i < length; i++) {
bools[i] = readBoolean(in);
}
return bools;
case BYTE_ARRAY:
length = readInt(in);
byte[] bytes = new byte[length];
for (int i = 0; i < length; i++) {
bytes[i] = readByte(in);
}
return bytes;
case CHAR_ARRAY:
length = readInt(in);
char[] chars = new char[length];
for (int i = 0; i < length; i++) {
chars[i] = readChar(in);
}
return chars;
case SHORT_ARRAY:
length = readInt(in);
short[] shorts = new short[length];
for (int i = 0; i < length; i++) {
shorts[i] = readShort(in);
}
return shorts;
case INT_ARRAY:
length = readInt(in);
int[] ints = new int[length];
for (int i = 0; i < length; i++) {
ints[i] = readInt(in);
}
return ints;
case LONG_ARRAY:
length = readInt(in);
long[] longs = new long[length];
for (int i = 0; i < length; i++) {
longs[i] = readLong(in);
}
return longs;
case FLOAT_ARRAY:
length = readInt(in);
float[] floats = new float[length];
for (int i = 0; i < length; i++) {
floats[i] = readFloat(in);
}
return floats;
case DOUBLE_ARRAY:
length = readInt(in);
double[] doubles = new double[length];
for (int i = 0; i < length; i++) {
doubles[i] = readDouble(in);
}
return doubles;
case STRING_ARRAY:
length = readInt(in);
String[] Strings = new String[length];
for (int i = 0; i < length; i++) {
Strings[i] = readString(in);
}
return Strings;
default: default:
throw new IOException("Invalid Ion mark: " + mark); throw new IOException("Invalid Ion mark: " + mark);
} }
@ -306,59 +418,113 @@ public class Ion {
} }
if (obj instanceof Boolean) { if (obj instanceof Boolean) {
writeMark(out, Ion.BOOLEAN); writeMark(out, BOOLEAN);
writeBoolean(out, (Boolean) obj); writeBoolean(out, (Boolean) obj);
return; return;
} }
if (obj instanceof Byte) { if (obj instanceof Byte) {
writeMark(out, Ion.BYTE); writeMark(out, BYTE);
writeByte(out, (Byte) obj); writeByte(out, (Byte) obj);
return; return;
} }
if (obj instanceof Character) { if (obj instanceof Character) {
writeMark(out, Ion.CHAR); writeMark(out, CHAR);
writeChar(out, (Character) obj); writeChar(out, (Character) obj);
return; return;
} }
if (obj instanceof Short) { if (obj instanceof Short) {
writeMark(out, Ion.SHORT); writeMark(out, SHORT);
writeShort(out, (Short) obj); writeShort(out, (Short) obj);
return; return;
} }
if (obj instanceof Integer) { if (obj instanceof Integer) {
writeMark(out, Ion.INT); writeMark(out, INT);
writeInt(out, (Integer) obj); writeInt(out, (Integer) obj);
return; return;
} }
if (obj instanceof Long) { if (obj instanceof Long) {
writeMark(out, Ion.LONG); writeMark(out, LONG);
writeLong(out, (Long) obj); writeLong(out, (Long) obj);
return; return;
} }
if (obj instanceof Float) { if (obj instanceof Float) {
writeMark(out, Ion.FLOAT); writeMark(out, FLOAT);
writeFloat(out, (Float) obj); writeFloat(out, (Float) obj);
return; return;
} }
if (obj instanceof Double) { if (obj instanceof Double) {
writeMark(out, Ion.DOUBLE); writeMark(out, DOUBLE);
writeDouble(out, (Double) obj); writeDouble(out, (Double) obj);
return; return;
} }
if (obj instanceof String) { if (obj instanceof String) {
writeMark(out, Ion.STRING); writeMark(out, STRING);
writeString(out, (String) obj); writeString(out, (String) obj);
return; return;
} }
if (obj instanceof boolean[]) {
writeMark(out, BOOLEAN_ARRAY);
writeBooleanArray(out, (boolean[]) obj);
return;
}
if (obj instanceof byte[]) {
writeMark(out, BYTE_ARRAY);
writeByteArray(out, (byte[]) obj);
return;
}
if (obj instanceof char[]) {
writeMark(out, CHAR_ARRAY);
writeCharArray(out, (char[]) obj);
return;
}
if (obj instanceof short[]) {
writeMark(out, SHORT_ARRAY);
writeShortArray(out, (short[]) obj);
return;
}
if (obj instanceof int[]) {
writeMark(out, INT_ARRAY);
writeIntArray(out, (int[]) obj);
return;
}
if (obj instanceof long[]) {
writeMark(out, LONG_ARRAY);
writeLongArray(out, (long[]) obj);
return;
}
if (obj instanceof float[]) {
writeMark(out, FLOAT_ARRAY);
writeFloatArray(out, (float[]) obj);
return;
}
if (obj instanceof double[]) {
writeMark(out, DOUBLE_ARRAY);
writeDoubleArray(out, (double[]) obj);
return;
}
if (obj instanceof String[]) {
writeMark(out, STRING_ARRAY);
writeStringArray(out, (String[]) obj);
return;
}
throw new IOException("Object " + Log.str(obj) + " could not be be ionized."); throw new IOException("Object " + Log.str(obj) + " could not be be ionized.");
} catch (final IOException e) { } catch (final IOException e) {
@ -439,21 +605,6 @@ public class Ion {
} }
private static byte[] getBytesString(String str)
{
final char[] chars = str.toCharArray();
final ByteBuffer bstr = ByteBuffer.allocate((Character.SIZE / 8) * chars.length + (Character.SIZE / 8));
for (final char c : chars) {
bstr.putChar(c);
}
bstr.putChar((char) 0);
return bstr.array();
}
/** /**
* Write a boolean (without a mark) * Write a boolean (without a mark)
* *
@ -567,7 +718,151 @@ public class Ion {
*/ */
public static void writeString(OutputStream out, String str) throws IOException public static void writeString(OutputStream out, String str) throws IOException
{ {
out.write(getBytesString(str)); writeCharArray(out, str.toCharArray());
}
/**
* Write boolean array
*
* @param out output stream
* @param arr array to write
* @throws IOException
*/
public static void writeBooleanArray(OutputStream out, boolean[] arr) throws IOException
{
writeInt(out, arr.length);
for (boolean a : arr) {
writeBoolean(out, a);
}
}
/**
* Write byte array
*
* @param out output stream
* @param arr array to write
* @throws IOException
*/
public static void writeByteArray(OutputStream out, byte[] arr) throws IOException
{
writeInt(out, arr.length);
for (byte a : arr) {
writeByte(out, a);
}
}
/**
* Write char array
*
* @param out output stream
* @param arr array to write
* @throws IOException
*/
public static void writeCharArray(OutputStream out, char[] arr) throws IOException
{
writeInt(out, arr.length);
for (char a : arr) {
writeChar(out, a);
}
}
/**
* Write short array
*
* @param out output stream
* @param arr array to write
* @throws IOException
*/
public static void writeShortArray(OutputStream out, short[] arr) throws IOException
{
writeInt(out, arr.length);
for (short a : arr) {
writeShort(out, a);
}
}
/**
* Write int array
*
* @param out output stream
* @param arr array to write
* @throws IOException
*/
public static void writeIntArray(OutputStream out, int[] arr) throws IOException
{
writeInt(out, arr.length);
for (int a : arr) {
writeInt(out, a);
}
}
/**
* Write long array
*
* @param out output stream
* @param arr array to write
* @throws IOException
*/
public static void writeLongArray(OutputStream out, long[] arr) throws IOException
{
writeInt(out, arr.length);
for (long a : arr) {
writeLong(out, a);
}
}
/**
* Write float array
*
* @param out output stream
* @param arr array to write
* @throws IOException
*/
public static void writeFloatArray(OutputStream out, float[] arr) throws IOException
{
writeInt(out, arr.length);
for (float a : arr) {
writeFloat(out, a);
}
}
/**
* Write double array
*
* @param out output stream
* @param arr array to write
* @throws IOException
*/
public static void writeDoubleArray(OutputStream out, double[] arr) throws IOException
{
writeInt(out, arr.length);
for (double a : arr) {
writeDouble(out, a);
}
}
/**
* Write String array
*
* @param out output stream
* @param arr array to write
* @throws IOException
*/
public static void writeStringArray(OutputStream out, String[] arr) throws IOException
{
writeInt(out, arr.length);
for (String a : arr) {
writeString(out, a);
}
} }
@ -710,12 +1005,169 @@ public class Ion {
*/ */
public static String readString(InputStream in) throws IOException public static String readString(InputStream in) throws IOException
{ {
String s = ""; return String.valueOf(readCharArray(in));
char c; }
while ((c = readChar(in)) > 0) {
s += c;
/**
* Read a boolean array (without a mark)
*
* @param in input stream
* @return boolean read
* @throws IOException
*/
public static boolean[] readBooleanArray(InputStream in) throws IOException
{
int length = readInt(in);
boolean[] booleans = new boolean[length];
for (int i = 0; i < length; i++) {
booleans[i] = readBoolean(in);
}
return booleans;
}
/**
* Read a byte array (without a mark)
*
* @param in input stream
* @return byte read
* @throws IOException
*/
public static byte[] readByteArray(InputStream in) throws IOException
{
int length = readInt(in);
byte[] bytes = new byte[length];
for (int i = 0; i < length; i++) {
bytes[i] = readByte(in);
}
return bytes;
}
/**
* Read a char array (without a mark)
*
* @param in input stream
* @return char read
* @throws IOException
*/
public static char[] readCharArray(InputStream in) throws IOException
{
int length = readInt(in);
char[] chars = new char[length];
for (int i = 0; i < length; i++) {
chars[i] = readChar(in);
}
return chars;
}
/**
* Read a short array (without a mark)
*
* @param in input stream
* @return short read
* @throws IOException
*/
public static short[] readShortArray(InputStream in) throws IOException
{
int length = readInt(in);
short[] shorts = new short[length];
for (int i = 0; i < length; i++) {
shorts[i] = readShort(in);
}
return shorts;
}
/**
* Read a int array (without a mark)
*
* @param in input stream
* @return int read
* @throws IOException
*/
public static int[] readIntArray(InputStream in) throws IOException
{
int length = readInt(in);
int[] ints = new int[length];
for (int i = 0; i < length; i++) {
ints[i] = readInt(in);
}
return ints;
}
/**
* Read a long array (without a mark)
*
* @param in input stream
* @return long read
* @throws IOException
*/
public static long[] readLongArray(InputStream in) throws IOException
{
int length = readInt(in);
long[] longs = new long[length];
for (int i = 0; i < length; i++) {
longs[i] = readLong(in);
}
return longs;
}
/**
* Read a float array (without a mark)
*
* @param in input stream
* @return float read
* @throws IOException
*/
public static float[] readFloatArray(InputStream in) throws IOException
{
int length = readInt(in);
float[] floats = new float[length];
for (int i = 0; i < length; i++) {
floats[i] = readFloat(in);
}
return floats;
}
/**
* Read a double array (without a mark)
*
* @param in input stream
* @return double read
* @throws IOException
*/
public static double[] readDoubleArray(InputStream in) throws IOException
{
int length = readInt(in);
double[] doubles = new double[length];
for (int i = 0; i < length; i++) {
doubles[i] = readDouble(in);
}
return doubles;
}
/**
* Read a String array (without a mark)
*
* @param in input stream
* @return String read
* @throws IOException
*/
public static String[] readStringArray(InputStream in) throws IOException
{
int length = readInt(in);
String[] Strings = new String[length];
for (int i = 0; i < length; i++) {
Strings[i] = readString(in);
} }
return s; return Strings;
} }
} }

@ -4,6 +4,8 @@ package mightypork.util.objects;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import mightypork.util.logging.Log;
/** /**
* Object utils class * Object utils class
@ -21,15 +23,15 @@ public class ObjectUtils {
} }
public static String arrayToString(Object[] arr) public static <T> String arrayToString(T[] arr)
{ {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
sb.append('['); sb.append('[');
final boolean first = true; final boolean first = true;
for (final Object o : arr) { for (final T o : arr) {
if (!first) sb.append(','); if (!first) sb.append(',');
sb.append(o.toString()); sb.append(Log.str(o));
} }
sb.append(']'); sb.append(']');
@ -37,7 +39,7 @@ public class ObjectUtils {
} }
public static <T extends Object> List<T> arrayToList(T[] objs) public static <T> List<T> arrayToList(T[] objs)
{ {
final ArrayList<T> list = new ArrayList<>(); final ArrayList<T> list = new ArrayList<>();
for (final T o : objs) { for (final T o : objs) {

Loading…
Cancel
Save