]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/src/org/simantics/databoard/util/binary/LittleEndian.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / util / binary / LittleEndian.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 gives little endian read and write. \r
10  *\r
11  * @author Toni Kalajainen <toni.kalajainen@iki.fi>\r
12  */\r
13 public class LittleEndian {\r
14 \r
15         public static short readShort(DataInput in) throws IOException {\r
16                 return (short) (in.readUnsignedByte() | (in.readUnsignedByte() << 8));          \r
17         }\r
18 \r
19         public static void writeShort(DataOutput out, int v) throws IOException {\r
20         v = (((v & 0xFF00) >> 8) | (v << 8));\r
21                 out.writeShort( v );\r
22         }\r
23         \r
24         public static int readUnsignedShort(DataInput in) throws IOException {\r
25                 int v = in.readUnsignedShort();\r
26                 return (((v & 0xFF00) >> 8) | (v << 8));\r
27         }\r
28         \r
29         public static int readInt(DataInput in) throws IOException {\r
30                 return Integer.reverseBytes( in.readInt() );\r
31         }\r
32 \r
33         public static void writeInt(DataOutput out, int v) throws IOException {\r
34                 out.writeInt( Integer.reverseBytes( v ) );\r
35         }\r
36         \r
37         public static long readLong(DataInput in) throws IOException {\r
38                 return Long.reverseBytes( in.readLong() );\r
39         }\r
40         \r
41         public static void writeLong(DataOutput out, long v) throws IOException {\r
42                 out.writeLong( Long.reverseBytes(v) );\r
43         }\r
44         \r
45         public static double readDouble(DataInput in) throws IOException {\r
46                 return Double.longBitsToDouble( Long.reverseBytes( in.readLong() ) );\r
47         }\r
48         \r
49         public static void writeDouble(DataOutput out, double d) throws IOException {\r
50                 out.writeLong( Long.reverseBytes( Double.doubleToLongBits(d) ) );\r
51         }\r
52 \r
53         public static float readFloat(DataInput in) throws IOException {\r
54                 return Float.intBitsToFloat( Integer.reverseBytes( in.readInt() ) );\r
55         }       \r
56         \r
57         public static void writeFloat(DataOutput out, float v) throws IOException {\r
58                 out.writeInt( Integer.reverseBytes( Float.floatToIntBits(v) ) );\r
59         }\r
60 \r
61         public static void writeUInt24(DataOutput out, int value) throws IOException {\r
62                 out.write((byte)value);\r
63                 out.write((byte)(value >> 8));\r
64                 out.write((byte)(value >> 16));\r
65         }\r
66         \r
67         public static int readUInt24(DataInput in) throws IOException {\r
68                 return (\r
69                         ( in.readByte() ) |\r
70                         ( in.readByte() << 8) |\r
71                         ( in.readByte() << 16) ) & 0xffffff; \r
72         }\r
73         \r
74         \r
75         \r
76         /**\r
77          * Write UInt32 with dynamic encoding (1-5 bytes).\r
78          * \r
79          * @param out\r
80          * @param length\r
81          * @throws IOException\r
82          */\r
83         public static void writeDynamicUInt32(DataOutput out, int length) throws IOException {          \r
84                 if(length < 0x80) {\r
85                         out.write((byte)length);\r
86                 }\r
87                 else {\r
88                         length -= 0x80;\r
89                         if(length < 0x4000) {\r
90                                 out.write((byte)((length&0x3f) | 0x80));\r
91                                 out.write((byte)(length>>>6));\r
92                         }\r
93                         else {\r
94                                 length -= 0x4000;\r
95                                 if(length < 0x200000) {\r
96                                         out.write((byte)((length&0x1f) | 0xc0));\r
97                                         out.write((byte)((length>>>5)&0xff));\r
98                                         out.write((byte)((length>>>13)&0xff));  \r
99                                 }\r
100                                 else {\r
101                                         length -= 0x200000;\r
102                                         if(length < 0x10000000) {\r
103                                                 out.write((byte)((length&0x0f) | 0xe0));\r
104                                                 out.write((byte)((length>>>4)&0xff));\r
105                                                 out.write((byte)((length>>>12)&0xff));  \r
106                                                 out.write((byte)((length>>>20)&0xff));\r
107                                         }\r
108                                         else {\r
109                                                 length -= 0x10000000;\r
110                                                 out.write((byte)((length&0x07) | 0xf0));\r
111                                                 out.write((byte)((length>>>3)&0xff));\r
112                                                 out.write((byte)((length>>>11)&0xff));  \r
113                                                 out.write((byte)((length>>>19)&0xff));\r
114                                                 out.write((byte)((length>>>27)&0xff));\r
115                                         }\r
116                                 }                               \r
117                         }\r
118                 }       \r
119         }\r
120 \r
121 \r
122         public static int readDynamicUInt32(DataInput in) throws IOException {\r
123                 int length = in.readByte()&0xff; \r
124                 if(length >= 0x80) {\r
125                         if(length >= 0xc0) {\r
126                                 if(length >= 0xe0) {\r
127                                         if(length >= 0xf0) {\r
128                                                 length &= 0x0f;\r
129                                                 length += ((in.readByte()&0xff)<<3);\r
130                                                 length += ((in.readByte()&0xff)<<11);\r
131                                                 length += ((in.readByte()&0xff)<<19);\r
132                                                 length += 0x10204080;\r
133                                         }\r
134                                         else {\r
135                                                 length &= 0x1f;\r
136                                                 length += ((in.readByte()&0xff)<<4);\r
137                                                 length += ((in.readByte()&0xff)<<12);\r
138                                                 length += ((in.readByte()&0xff)<<20);\r
139                                                 length += 0x204080;\r
140                                         }\r
141                                 }\r
142                                 else {\r
143                                         length &= 0x3f;\r
144                                         length += ((in.readByte()&0xff)<<5);\r
145                                         length += ((in.readByte()&0xff)<<13);\r
146                                         length += 0x4080;\r
147                                 }\r
148                         }\r
149                         else {\r
150                                 length &= 0x7f;\r
151                                 length += ((in.readByte()&0xff)<<6);\r
152                                 length += 0x80;\r
153                         }\r
154                 }\r
155                 return length;\r
156         }\r
157 \r
158         \r
159         /**\r
160          * Get number of bytes for dynamic encoding of UInt32 (1-5 bytes)\r
161          *  \r
162          * @param length length value\r
163          * @return bytes required (1-5)\r
164          */\r
165         public static int getDynamicUInt32Length(int length)\r
166         {\r
167                 if(length < 0x80) return 1;             \r
168                 if(length < 0x4080) return 2;\r
169                 if(length < 0x204000) return 3;\r
170                 if(length < 0x10200000) return 4;\r
171                 return 5;\r
172         }\r
173 \r
174         \r
175         /**\r
176          * Decode an unsigned integer. The number of bytes read depends on maxValue. \r
177          * \r
178          * @param in\r
179          * @param maxValue\r
180          * @return int\r
181          * @throws IOException\r
182          */\r
183         public static int getUInt(DataInput in, int maxValue)\r
184         throws IOException\r
185         {\r
186                 if (maxValue==0) return 0;\r
187                 if (maxValue<0x100) {\r
188                         return in.readByte() & 0xFF;\r
189                 } else if (maxValue<0x10000) {\r
190                         return LittleEndian.readShort(in) & 0xFFFF;\r
191                 } else if (maxValue<0x1000000) {\r
192                         return LittleEndian.readUInt24(in) & 0xFFFFFF;\r
193                 } else {\r
194                         return readInt(in);\r
195                 }               \r
196         }\r
197         \r
198         /**\r
199          * Calculate unsigned integer encoding length.\r
200          * \r
201          * @param maxValue\r
202          * @return 0-4 bytes\r
203          */\r
204         public static int getUIntLength(int maxValue)\r
205         {\r
206                 if (maxValue==0) {\r
207                         return 0;\r
208                 } else if (maxValue<0x100) {\r
209                         return 1;\r
210                 } else if (maxValue<0x10000) {\r
211                         return 2;\r
212                 } else if (maxValue<0x1000000) {\r
213                         return 3;\r
214                 } else {\r
215                         return 4;\r
216                 }\r
217         }\r
218         \r
219         /**\r
220          * Encode and write an unsigned integer. The number of bytes written\r
221          * depends on the maxValue.\r
222          * \r
223          * @param out\r
224          * @param value\r
225          * @param maxValue\r
226          * @throws IOException\r
227          */\r
228         public static void putUInt(DataOutput out, int value, int maxValue)\r
229         throws IOException {\r
230                 if (maxValue==0) {}\r
231                 else if (maxValue<0x100) {\r
232                         out.write(value);\r
233                 } else if (maxValue<0x10000) {\r
234                         LittleEndian.writeShort(out, value);\r
235                 } else if (maxValue<0x1000000) {\r
236                         LittleEndian.writeUInt24(out, value);\r
237                 } else {\r
238                         out.writeInt(value);\r
239                 }\r
240         }\r
241         \r
242         \r
243 }\r