-package org.simantics.databoard.util.binary;\r
-\r
-import java.io.DataInput;\r
-import java.io.DataOutput;\r
-import java.io.IOException;\r
-\r
-/**\r
- * DataInput and DataOutput serialize primitive numbers with big endian byte\r
- * order. This utility gives little endian read and write. \r
- *\r
- * @author Toni Kalajainen <toni.kalajainen@iki.fi>\r
- */\r
-public class LittleEndian {\r
-\r
- public static short readShort(DataInput in) throws IOException {\r
- return (short) (in.readUnsignedByte() | (in.readUnsignedByte() << 8)); \r
- }\r
-\r
- public static void writeShort(DataOutput out, int v) throws IOException {\r
- v = (((v & 0xFF00) >> 8) | (v << 8));\r
- out.writeShort( v );\r
- }\r
- \r
- public static int readUnsignedShort(DataInput in) throws IOException {\r
- int v = in.readUnsignedShort();\r
- return (((v & 0xFF00) >> 8) | (v << 8));\r
- }\r
- \r
- public static int readInt(DataInput in) throws IOException {\r
- return Integer.reverseBytes( in.readInt() );\r
- }\r
-\r
- public static void writeInt(DataOutput out, int v) throws IOException {\r
- out.writeInt( Integer.reverseBytes( v ) );\r
- }\r
- \r
- public static long readLong(DataInput in) throws IOException {\r
- return Long.reverseBytes( in.readLong() );\r
- }\r
- \r
- public static void writeLong(DataOutput out, long v) throws IOException {\r
- out.writeLong( Long.reverseBytes(v) );\r
- }\r
- \r
- public static double readDouble(DataInput in) throws IOException {\r
- return Double.longBitsToDouble( Long.reverseBytes( in.readLong() ) );\r
- }\r
- \r
- public static void writeDouble(DataOutput out, double d) throws IOException {\r
- out.writeLong( Long.reverseBytes( Double.doubleToLongBits(d) ) );\r
- }\r
-\r
- public static float readFloat(DataInput in) throws IOException {\r
- return Float.intBitsToFloat( Integer.reverseBytes( in.readInt() ) );\r
- } \r
- \r
- public static void writeFloat(DataOutput out, float v) throws IOException {\r
- out.writeInt( Integer.reverseBytes( Float.floatToIntBits(v) ) );\r
- }\r
-\r
- public static void writeUInt24(DataOutput out, int value) throws IOException {\r
- out.write((byte)value);\r
- out.write((byte)(value >> 8));\r
- out.write((byte)(value >> 16));\r
- }\r
- \r
- public static int readUInt24(DataInput in) throws IOException {\r
- return (\r
- ( in.readByte() ) |\r
- ( in.readByte() << 8) |\r
- ( in.readByte() << 16) ) & 0xffffff; \r
- }\r
- \r
- \r
- \r
- /**\r
- * Write UInt32 with dynamic encoding (1-5 bytes).\r
- * \r
- * @param out\r
- * @param length\r
- * @throws IOException\r
- */\r
- public static void writeDynamicUInt32(DataOutput out, int length) throws IOException { \r
- if(length < 0x80) {\r
- out.write((byte)length);\r
- }\r
- else {\r
- length -= 0x80;\r
- if(length < 0x4000) {\r
- out.write((byte)((length&0x3f) | 0x80));\r
- out.write((byte)(length>>>6));\r
- }\r
- else {\r
- length -= 0x4000;\r
- if(length < 0x200000) {\r
- out.write((byte)((length&0x1f) | 0xc0));\r
- out.write((byte)((length>>>5)&0xff));\r
- out.write((byte)((length>>>13)&0xff)); \r
- }\r
- else {\r
- length -= 0x200000;\r
- if(length < 0x10000000) {\r
- out.write((byte)((length&0x0f) | 0xe0));\r
- out.write((byte)((length>>>4)&0xff));\r
- out.write((byte)((length>>>12)&0xff)); \r
- out.write((byte)((length>>>20)&0xff));\r
- }\r
- else {\r
- length -= 0x10000000;\r
- out.write((byte)((length&0x07) | 0xf0));\r
- out.write((byte)((length>>>3)&0xff));\r
- out.write((byte)((length>>>11)&0xff)); \r
- out.write((byte)((length>>>19)&0xff));\r
- out.write((byte)((length>>>27)&0xff));\r
- }\r
- } \r
- }\r
- } \r
- }\r
-\r
-\r
- public static int readDynamicUInt32(DataInput in) throws IOException {\r
- int length = in.readByte()&0xff; \r
- if(length >= 0x80) {\r
- if(length >= 0xc0) {\r
- if(length >= 0xe0) {\r
- if(length >= 0xf0) {\r
- length &= 0x0f;\r
- length += ((in.readByte()&0xff)<<3);\r
- length += ((in.readByte()&0xff)<<11);\r
- length += ((in.readByte()&0xff)<<19);\r
- length += 0x10204080;\r
- }\r
- else {\r
- length &= 0x1f;\r
- length += ((in.readByte()&0xff)<<4);\r
- length += ((in.readByte()&0xff)<<12);\r
- length += ((in.readByte()&0xff)<<20);\r
- length += 0x204080;\r
- }\r
- }\r
- else {\r
- length &= 0x3f;\r
- length += ((in.readByte()&0xff)<<5);\r
- length += ((in.readByte()&0xff)<<13);\r
- length += 0x4080;\r
- }\r
- }\r
- else {\r
- length &= 0x7f;\r
- length += ((in.readByte()&0xff)<<6);\r
- length += 0x80;\r
- }\r
- }\r
- return length;\r
- }\r
-\r
- \r
- /**\r
- * Get number of bytes for dynamic encoding of UInt32 (1-5 bytes)\r
- * \r
- * @param length length value\r
- * @return bytes required (1-5)\r
- */\r
- public static int getDynamicUInt32Length(int length)\r
- {\r
- if(length < 0x80) return 1; \r
- if(length < 0x4080) return 2;\r
- if(length < 0x204000) return 3;\r
- if(length < 0x10200000) return 4;\r
- return 5;\r
- }\r
-\r
- \r
- /**\r
- * Decode an unsigned integer. The number of bytes read depends on maxValue. \r
- * \r
- * @param in\r
- * @param maxValue\r
- * @return int\r
- * @throws IOException\r
- */\r
- public static int getUInt(DataInput in, int maxValue)\r
- throws IOException\r
- {\r
- if (maxValue==0) return 0;\r
- if (maxValue<0x100) {\r
- return in.readByte() & 0xFF;\r
- } else if (maxValue<0x10000) {\r
- return LittleEndian.readShort(in) & 0xFFFF;\r
- } else if (maxValue<0x1000000) {\r
- return LittleEndian.readUInt24(in) & 0xFFFFFF;\r
- } else {\r
- return readInt(in);\r
- } \r
- }\r
- \r
- /**\r
- * Calculate unsigned integer encoding length.\r
- * \r
- * @param maxValue\r
- * @return 0-4 bytes\r
- */\r
- public static int getUIntLength(int maxValue)\r
- {\r
- if (maxValue==0) {\r
- return 0;\r
- } else if (maxValue<0x100) {\r
- return 1;\r
- } else if (maxValue<0x10000) {\r
- return 2;\r
- } else if (maxValue<0x1000000) {\r
- return 3;\r
- } else {\r
- return 4;\r
- }\r
- }\r
- \r
- /**\r
- * Encode and write an unsigned integer. The number of bytes written\r
- * depends on the maxValue.\r
- * \r
- * @param out\r
- * @param value\r
- * @param maxValue\r
- * @throws IOException\r
- */\r
- public static void putUInt(DataOutput out, int value, int maxValue)\r
- throws IOException {\r
- if (maxValue==0) {}\r
- else if (maxValue<0x100) {\r
- out.write(value);\r
- } else if (maxValue<0x10000) {\r
- LittleEndian.writeShort(out, value);\r
- } else if (maxValue<0x1000000) {\r
- LittleEndian.writeUInt24(out, value);\r
- } else {\r
- out.writeInt(value);\r
- }\r
- }\r
- \r
- \r
-}\r
+package org.simantics.databoard.util.binary;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+/**
+ * DataInput and DataOutput serialize primitive numbers with big endian byte
+ * order. This utility gives little endian read and write.
+ *
+ * @author Toni Kalajainen <toni.kalajainen@iki.fi>
+ */
+public class LittleEndian {
+
+ public static short readShort(DataInput in) throws IOException {
+ return (short) (in.readUnsignedByte() | (in.readUnsignedByte() << 8));
+ }
+
+ public static void writeShort(DataOutput out, int v) throws IOException {
+ v = (((v & 0xFF00) >> 8) | (v << 8));
+ out.writeShort( v );
+ }
+
+ public static int readUnsignedShort(DataInput in) throws IOException {
+ int v = in.readUnsignedShort();
+ return (((v & 0xFF00) >> 8) | (v << 8));
+ }
+
+ public static int readInt(DataInput in) throws IOException {
+ return Integer.reverseBytes( in.readInt() );
+ }
+
+ public static void writeInt(DataOutput out, int v) throws IOException {
+ out.writeInt( Integer.reverseBytes( v ) );
+ }
+
+ public static long readLong(DataInput in) throws IOException {
+ return Long.reverseBytes( in.readLong() );
+ }
+
+ public static void writeLong(DataOutput out, long v) throws IOException {
+ out.writeLong( Long.reverseBytes(v) );
+ }
+
+ public static double readDouble(DataInput in) throws IOException {
+ return Double.longBitsToDouble( Long.reverseBytes( in.readLong() ) );
+ }
+
+ public static void writeDouble(DataOutput out, double d) throws IOException {
+ out.writeLong( Long.reverseBytes( Double.doubleToLongBits(d) ) );
+ }
+
+ public static float readFloat(DataInput in) throws IOException {
+ return Float.intBitsToFloat( Integer.reverseBytes( in.readInt() ) );
+ }
+
+ public static void writeFloat(DataOutput out, float v) throws IOException {
+ out.writeInt( Integer.reverseBytes( Float.floatToIntBits(v) ) );
+ }
+
+ public static void writeUInt24(DataOutput out, int value) throws IOException {
+ out.write((byte)value);
+ out.write((byte)(value >> 8));
+ out.write((byte)(value >> 16));
+ }
+
+ public static int readUInt24(DataInput in) throws IOException {
+ return (
+ ( in.readByte() ) |
+ ( in.readByte() << 8) |
+ ( in.readByte() << 16) ) & 0xffffff;
+ }
+
+
+
+ /**
+ * Write UInt32 with dynamic encoding (1-5 bytes).
+ *
+ * @param out
+ * @param length
+ * @throws IOException
+ */
+ public static void writeDynamicUInt32(DataOutput out, int length) throws IOException {
+ if(length < 0x80) {
+ out.write((byte)length);
+ }
+ else {
+ length -= 0x80;
+ if(length < 0x4000) {
+ out.write((byte)((length&0x3f) | 0x80));
+ out.write((byte)(length>>>6));
+ }
+ else {
+ length -= 0x4000;
+ if(length < 0x200000) {
+ out.write((byte)((length&0x1f) | 0xc0));
+ out.write((byte)((length>>>5)&0xff));
+ out.write((byte)((length>>>13)&0xff));
+ }
+ else {
+ length -= 0x200000;
+ if(length < 0x10000000) {
+ out.write((byte)((length&0x0f) | 0xe0));
+ out.write((byte)((length>>>4)&0xff));
+ out.write((byte)((length>>>12)&0xff));
+ out.write((byte)((length>>>20)&0xff));
+ }
+ else {
+ length -= 0x10000000;
+ out.write((byte)((length&0x07) | 0xf0));
+ out.write((byte)((length>>>3)&0xff));
+ out.write((byte)((length>>>11)&0xff));
+ out.write((byte)((length>>>19)&0xff));
+ out.write((byte)((length>>>27)&0xff));
+ }
+ }
+ }
+ }
+ }
+
+
+ public static int readDynamicUInt32(DataInput in) throws IOException {
+ int length = in.readByte()&0xff;
+ if(length >= 0x80) {
+ if(length >= 0xc0) {
+ if(length >= 0xe0) {
+ if(length >= 0xf0) {
+ length &= 0x0f;
+ length += ((in.readByte()&0xff)<<3);
+ length += ((in.readByte()&0xff)<<11);
+ length += ((in.readByte()&0xff)<<19);
+ length += 0x10204080;
+ }
+ else {
+ length &= 0x1f;
+ length += ((in.readByte()&0xff)<<4);
+ length += ((in.readByte()&0xff)<<12);
+ length += ((in.readByte()&0xff)<<20);
+ length += 0x204080;
+ }
+ }
+ else {
+ length &= 0x3f;
+ length += ((in.readByte()&0xff)<<5);
+ length += ((in.readByte()&0xff)<<13);
+ length += 0x4080;
+ }
+ }
+ else {
+ length &= 0x7f;
+ length += ((in.readByte()&0xff)<<6);
+ length += 0x80;
+ }
+ }
+ return length;
+ }
+
+
+ /**
+ * Get number of bytes for dynamic encoding of UInt32 (1-5 bytes)
+ *
+ * @param length length value
+ * @return bytes required (1-5)
+ */
+ public static int getDynamicUInt32Length(int length)
+ {
+ if(length < 0x80) return 1;
+ if(length < 0x4080) return 2;
+ if(length < 0x204000) return 3;
+ if(length < 0x10200000) return 4;
+ return 5;
+ }
+
+
+ /**
+ * Decode an unsigned integer. The number of bytes read depends on maxValue.
+ *
+ * @param in
+ * @param maxValue
+ * @return int
+ * @throws IOException
+ */
+ public static int getUInt(DataInput in, int maxValue)
+ throws IOException
+ {
+ if (maxValue==0) return 0;
+ if (maxValue<0x100) {
+ return in.readByte() & 0xFF;
+ } else if (maxValue<0x10000) {
+ return LittleEndian.readShort(in) & 0xFFFF;
+ } else if (maxValue<0x1000000) {
+ return LittleEndian.readUInt24(in) & 0xFFFFFF;
+ } else {
+ return readInt(in);
+ }
+ }
+
+ /**
+ * Calculate unsigned integer encoding length.
+ *
+ * @param maxValue
+ * @return 0-4 bytes
+ */
+ public static int getUIntLength(int maxValue)
+ {
+ if (maxValue==0) {
+ return 0;
+ } else if (maxValue<0x100) {
+ return 1;
+ } else if (maxValue<0x10000) {
+ return 2;
+ } else if (maxValue<0x1000000) {
+ return 3;
+ } else {
+ return 4;
+ }
+ }
+
+ /**
+ * Encode and write an unsigned integer. The number of bytes written
+ * depends on the maxValue.
+ *
+ * @param out
+ * @param value
+ * @param maxValue
+ * @throws IOException
+ */
+ public static void putUInt(DataOutput out, int value, int maxValue)
+ throws IOException {
+ if (maxValue==0) {}
+ else if (maxValue<0x100) {
+ out.write(value);
+ } else if (maxValue<0x10000) {
+ LittleEndian.writeShort(out, value);
+ } else if (maxValue<0x1000000) {
+ LittleEndian.writeUInt24(out, value);
+ } else {
+ out.writeInt(value);
+ }
+ }
+
+
+}