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