]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.databoard/src/org/simantics/databoard/util/binary/Endian.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / util / binary / Endian.java
diff --git a/bundles/org.simantics.databoard/src/org/simantics/databoard/util/binary/Endian.java b/bundles/org.simantics.databoard/src/org/simantics/databoard/util/binary/Endian.java
new file mode 100644 (file)
index 0000000..ea751ef
--- /dev/null
@@ -0,0 +1,196 @@
+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 absolutely does nothing but facades byte operations. \r
+ *\r
+ * @author Toni Kalajainen <toni.kalajainen@iki.fi>\r
+ */\r
+public class Endian {\r
+       public static void writeUInt24(DataOutput out, int value) throws IOException {\r
+               out.write((value >> 16) & 0xff);\r
+               out.write((value >> 8)  & 0xff);\r
+               out.write( value        & 0xff);\r
+       }\r
+       \r
+       public static int readUInt24(DataInput in) throws IOException {\r
+               return \r
+                               ( ( in.readByte() << 16) ) & 0xffffff | \r
+                         ( in.readByte() << 8) |\r
+                             ( in.readByte() );\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( ((length&0x3f) | 0x80) );\r
+                               out.write( (length>>>6) );\r
+                       }\r
+                       else {\r
+                               length -= 0x4000;\r
+                               if(length < 0x200000) {\r
+                                       out.write( ((length&0x1f) | 0xc0) );\r
+                                       out.write( ((length>>>5)&0xff) );\r
+                                       out.write( ((length>>>13)&0xff) );      \r
+                               }\r
+                               else {\r
+                                       length -= 0x200000;\r
+                                       if(length < 0x10000000) {\r
+                                               out.write( ((length&0x0f) | 0xe0) );\r
+                                               out.write( ((length>>>4)&0xff) );\r
+                                               out.write( ((length>>>12)&0xff) );      \r
+                                               out.write( ((length>>>20)&0xff) );\r
+                                       }\r
+                                       else {\r
+                                               length -= 0x10000000;\r
+                                               out.write( ((length&0x07) | 0xf0) );\r
+                                               out.write( ((length>>>3)&0xff) );\r
+                                               out.write( ((length>>>11)&0xff) );      \r
+                                               out.write( ((length>>>19)&0xff) );\r
+                                               out.write( ((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 in.readShort() & 0xFFFF;\r
+               } else if (maxValue<0x1000000) {\r
+                       return Endian.readUInt24(in) & 0xFFFFFF;\r
+               } else {\r
+                       return in.readInt();\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
+                       out.writeShort(value);\r
+               } else if (maxValue<0x1000000) {\r
+                       writeUInt24(out, value);\r
+               } else {\r
+                       out.writeInt(value);\r
+               }\r
+       }\r
+       \r
+       \r
+}\r