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