]> gerrit.simantics Code Review - simantics/platform.git/blob - 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
1 package org.simantics.databoard.util.binary;\r
2 \r
3 import java.io.DataInput;\r
4 import java.io.DataOutput;\r
5 import java.io.IOException;\r
6 \r
7 /**\r
8  * DataInput and DataOutput serialize primitive numbers with big endian byte\r
9  * order. This utility absolutely does nothing but facades byte operations. \r
10  *\r
11  * @author Toni Kalajainen <toni.kalajainen@iki.fi>\r
12  */\r
13 public class Endian {\r
14         public static void writeUInt24(DataOutput out, int value) throws IOException {\r
15                 out.write((value >> 16) & 0xff);\r
16                 out.write((value >> 8)  & 0xff);\r
17                 out.write( value        & 0xff);\r
18         }\r
19         \r
20         public static int readUInt24(DataInput in) throws IOException {\r
21                 return \r
22                                 ( ( in.readByte() << 16) ) & 0xffffff | \r
23                           ( in.readByte() << 8) |\r
24                               ( in.readByte() );\r
25         }\r
26         \r
27         \r
28         \r
29         /**\r
30          * Write UInt32 with dynamic encoding (1-5 bytes).\r
31          * \r
32          * @param out\r
33          * @param length\r
34          * @throws IOException\r
35          */\r
36         public static void writeDynamicUInt32(DataOutput out, int length) throws IOException {          \r
37                 if(length < 0x80) {\r
38                         out.write((byte)length);\r
39                 }\r
40                 else {\r
41                         length -= 0x80;\r
42                         if(length < 0x4000) {\r
43                                 out.write( ((length&0x3f) | 0x80) );\r
44                                 out.write( (length>>>6) );\r
45                         }\r
46                         else {\r
47                                 length -= 0x4000;\r
48                                 if(length < 0x200000) {\r
49                                         out.write( ((length&0x1f) | 0xc0) );\r
50                                         out.write( ((length>>>5)&0xff) );\r
51                                         out.write( ((length>>>13)&0xff) );      \r
52                                 }\r
53                                 else {\r
54                                         length -= 0x200000;\r
55                                         if(length < 0x10000000) {\r
56                                                 out.write( ((length&0x0f) | 0xe0) );\r
57                                                 out.write( ((length>>>4)&0xff) );\r
58                                                 out.write( ((length>>>12)&0xff) );      \r
59                                                 out.write( ((length>>>20)&0xff) );\r
60                                         }\r
61                                         else {\r
62                                                 length -= 0x10000000;\r
63                                                 out.write( ((length&0x07) | 0xf0) );\r
64                                                 out.write( ((length>>>3)&0xff) );\r
65                                                 out.write( ((length>>>11)&0xff) );      \r
66                                                 out.write( ((length>>>19)&0xff) );\r
67                                                 out.write( ((length>>>27)&0xff) );\r
68                                         }\r
69                                 }                               \r
70                         }\r
71                 }       \r
72         }\r
73 \r
74 \r
75         public static int readDynamicUInt32(DataInput in) throws IOException {\r
76                 int length = in.readByte()&0xff; \r
77                 if(length >= 0x80) {\r
78                         if(length >= 0xc0) {\r
79                                 if(length >= 0xe0) {\r
80                                         if(length >= 0xf0) {\r
81                                                 length &= 0x0f;\r
82                                                 length += ((in.readByte()&0xff)<<3);\r
83                                                 length += ((in.readByte()&0xff)<<11);\r
84                                                 length += ((in.readByte()&0xff)<<19);\r
85                                                 length += 0x10204080;\r
86                                         }\r
87                                         else {\r
88                                                 length &= 0x1f;\r
89                                                 length += ((in.readByte()&0xff)<<4);\r
90                                                 length += ((in.readByte()&0xff)<<12);\r
91                                                 length += ((in.readByte()&0xff)<<20);\r
92                                                 length += 0x204080;\r
93                                         }\r
94                                 }\r
95                                 else {\r
96                                         length &= 0x3f;\r
97                                         length += ((in.readByte()&0xff)<<5);\r
98                                         length += ((in.readByte()&0xff)<<13);\r
99                                         length += 0x4080;\r
100                                 }\r
101                         }\r
102                         else {\r
103                                 length &= 0x7f;\r
104                                 length += ((in.readByte()&0xff)<<6);\r
105                                 length += 0x80;\r
106                         }\r
107                 }\r
108                 return length;\r
109         }\r
110 \r
111         \r
112         /**\r
113          * Get number of bytes for dynamic encoding of UInt32 (1-5 bytes)\r
114          *  \r
115          * @param length length value\r
116          * @return bytes required (1-5)\r
117          */\r
118         public static int getDynamicUInt32Length(int length)\r
119         {\r
120                 if(length < 0x80) return 1;             \r
121                 if(length < 0x4080) return 2;\r
122                 if(length < 0x204000) return 3;\r
123                 if(length < 0x10200000) return 4;\r
124                 return 5;\r
125         }\r
126 \r
127         \r
128         /**\r
129          * Decode an unsigned integer. The number of bytes read depends on maxValue. \r
130          * \r
131          * @param in\r
132          * @param maxValue\r
133          * @return int\r
134          * @throws IOException\r
135          */\r
136         public static int getUInt(DataInput in, int maxValue)\r
137         throws IOException\r
138         {\r
139                 if (maxValue==0) return 0;\r
140                 if (maxValue<0x100) {\r
141                         return in.readByte() & 0xFF;\r
142                 } else if (maxValue<0x10000) {\r
143                         return in.readShort() & 0xFFFF;\r
144                 } else if (maxValue<0x1000000) {\r
145                         return Endian.readUInt24(in) & 0xFFFFFF;\r
146                 } else {\r
147                         return in.readInt();\r
148                 }               \r
149         }\r
150         \r
151         /**\r
152          * Calculate unsigned integer encoding length.\r
153          * \r
154          * @param maxValue\r
155          * @return 0-4 bytes\r
156          */\r
157         public static int getUIntLength(int maxValue)\r
158         {\r
159                 if (maxValue==0) {\r
160                         return 0;\r
161                 } else if (maxValue<0x100) {\r
162                         return 1;\r
163                 } else if (maxValue<0x10000) {\r
164                         return 2;\r
165                 } else if (maxValue<0x1000000) {\r
166                         return 3;\r
167                 } else {\r
168                         return 4;\r
169                 }\r
170         }\r
171         \r
172         /**\r
173          * Encode and write an unsigned integer. The number of bytes written\r
174          * depends on the maxValue.\r
175          * \r
176          * @param out\r
177          * @param value\r
178          * @param maxValue\r
179          * @throws IOException\r
180          */\r
181         public static void putUInt(DataOutput out, int value, int maxValue)\r
182         throws IOException {\r
183                 if (maxValue==0) {}\r
184                 else if (maxValue<0x100) {\r
185                         out.write(value);\r
186                 } else if (maxValue<0x10000) {\r
187                         out.writeShort(value);\r
188                 } else if (maxValue<0x1000000) {\r
189                         writeUInt24(out, value);\r
190                 } else {\r
191                         out.writeInt(value);\r
192                 }\r
193         }\r
194         \r
195         \r
196 }\r