1   package org.djutils.serialization;
2   
3   import java.io.UnsupportedEncodingException;
4   import java.nio.ByteOrder;
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  public final class Endianness
16  {
17      
18      private final boolean bigEndian;
19  
20      
21      private static final boolean PLATFORM_BIG_ENDIAN = ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN);
22  
23      
24  
25  
26  
27      public static boolean isPlatformBigEndian()
28      {
29          return PLATFORM_BIG_ENDIAN;
30      }
31  
32      
33      public static final Endianness BIG_ENDIAN = new Endianness(true);
34  
35      
36      public static final Endianness LITTLE_ENDIAN = new Endianness(false);
37  
38      
39  
40  
41  
42  
43      private Endianness(final boolean bigEndian)
44      {
45          this.bigEndian = bigEndian;
46      }
47  
48      
49  
50  
51  
52      public static Endianness bigEndian()
53      {
54          return BIG_ENDIAN;
55      }
56  
57      
58  
59  
60  
61      public static Endianness littleEndian()
62      {
63          return LITTLE_ENDIAN;
64      }
65  
66      
67  
68  
69  
70      public boolean isBigEndian()
71      {
72          return this.bigEndian;
73      }
74  
75      
76  
77  
78  
79  
80  
81      public short decodeShort(final byte[] message, final int pointer)
82      {
83          if (this.bigEndian)
84          {
85              return (short) (((message[pointer] & 0xff) << 8) | ((message[pointer + 1] & 0xff)));
86          }
87          else
88          {
89              return (short) (((message[pointer + 1] & 0xff) << 8) | ((message[pointer] & 0xff)));
90          }
91      }
92  
93      
94  
95  
96  
97  
98  
99      public int decodeInt(final byte[] message, final int pointer)
100     {
101         if (this.bigEndian)
102         {
103             return (((message[pointer] & 0xff) << 24) | ((message[pointer + 1] & 0xff) << 16)
104                     | ((message[pointer + 2] & 0xff) << 8) | ((message[pointer + 3] & 0xff)));
105         }
106         else
107         {
108             return (((message[pointer + 3] & 0xff) << 24) | ((message[pointer + 2] & 0xff) << 16)
109                     | ((message[pointer + 1] & 0xff) << 8) | ((message[pointer] & 0xff)));
110         }
111     }
112 
113     
114 
115 
116 
117 
118 
119     public long decodeLong(final byte[] message, final int pointer)
120     {
121         if (this.bigEndian)
122         {
123             return ((((long) message[pointer]) << 56) | (((long) message[pointer + 1] & 0xff) << 48)
124                     | (((long) message[pointer + 2] & 0xff) << 40) | (((long) message[pointer + 3] & 0xff) << 32)
125                     | (((long) message[pointer + 4] & 0xff) << 24) | (((long) message[pointer + 5] & 0xff) << 16)
126                     | (((long) message[pointer + 6] & 0xff) << 8) | (((long) message[pointer + 7] & 0xff)));
127         }
128         else
129         {
130             return ((((long) message[pointer + 7]) << 56) | (((long) message[pointer + 6] & 0xff) << 48)
131                     | (((long) message[pointer + 5] & 0xff) << 40) | (((long) message[pointer + 4] & 0xff) << 32)
132                     | (((long) message[pointer + 3] & 0xff) << 24) | (((long) message[pointer + 2] & 0xff) << 16)
133                     | (((long) message[pointer + 1] & 0xff) << 8) | (((long) message[pointer] & 0xff)));
134         }
135     }
136 
137     
138 
139 
140 
141 
142 
143     public float decodeFloat(final byte[] message, final int pointer)
144     {
145         int bits = decodeInt(message, pointer);
146         return Float.intBitsToFloat(bits);
147     }
148 
149     
150 
151 
152 
153 
154 
155     public double decodeDouble(final byte[] message, final int pointer)
156     {
157         long bits = decodeLong(message, pointer);
158         return Double.longBitsToDouble(bits);
159     }
160 
161     
162 
163 
164 
165 
166 
167     public char decodeChar(final byte[] message, final int pointer)
168     {
169         return (char) decodeShort(message, pointer);
170     }
171 
172     
173 
174 
175 
176 
177 
178 
179     public String decodeUTF8String(final byte[] message, final int pointer) throws SerializationException
180     {
181         int len = decodeInt(message, pointer);
182         byte[] c = new byte[len];
183         for (int i = 0; i < len; i++)
184         {
185             c[i] = message[pointer + i + 4];
186         }
187         try
188         {
189             return new String(c, "UTF-8");
190         }
191         catch (UnsupportedEncodingException e)
192         {
193             throw new SerializationException(e);
194         }
195     }
196 
197     
198 
199 
200 
201 
202 
203     public String decodeUTF16String(final byte[] message, final int pointer)
204     {
205         int len = decodeInt(message, pointer);
206         char[] c = new char[len];
207         for (int i = 0; i < len; i++)
208         {
209             c[i] = decodeChar(message, pointer + 2 * i + 4);
210         }
211         return String.copyValueOf(c);
212     }
213 
214     
215 
216 
217 
218 
219 
220 
221     public int encodeShort(final short v, final byte[] message, final int pointer)
222     {
223         int p = pointer;
224         if (this.bigEndian)
225         {
226             message[p++] = (byte) (v >> 8);
227             message[p++] = (byte) (v);
228         }
229         else
230         {
231             message[p++] = (byte) (v);
232             message[p++] = (byte) (v >> 8);
233         }
234         return p;
235     }
236 
237     
238 
239 
240 
241 
242 
243 
244     public int encodeChar(final char v, final byte[] message, final int pointer)
245     {
246         return encodeShort((short) v, message, pointer);
247     }
248 
249     
250 
251 
252 
253 
254 
255     public void encodeInt(final int v, final byte[] message, final int pointer)
256     {
257         int p = pointer;
258         if (this.bigEndian)
259         {
260             message[p++] = (byte) ((v >> 24) & 0xFF);
261             message[p++] = (byte) ((v >> 16) & 0xFF);
262             message[p++] = (byte) ((v >> 8) & 0xFF);
263             message[p++] = (byte) (v & 0xFF);
264         }
265         else
266         {
267             message[p++] = (byte) (v & 0xFF);
268             message[p++] = (byte) ((v >> 8) & 0xFF);
269             message[p++] = (byte) ((v >> 16) & 0xFF);
270             message[p++] = (byte) ((v >> 24) & 0xFF);
271         }
272     }
273 
274     
275 
276 
277 
278 
279 
280 
281     public int encodeLong(final long v, final byte[] message, final int pointer)
282     {
283         int p = pointer;
284         if (this.bigEndian)
285         {
286             message[p++] = (byte) ((v >> 56) & 0xFF);
287             message[p++] = (byte) ((v >> 48) & 0xFF);
288             message[p++] = (byte) ((v >> 40) & 0xFF);
289             message[p++] = (byte) ((v >> 32) & 0xFF);
290             message[p++] = (byte) ((v >> 24) & 0xFF);
291             message[p++] = (byte) ((v >> 16) & 0xFF);
292             message[p++] = (byte) ((v >> 8) & 0xFF);
293             message[p++] = (byte) (v & 0xFF);
294         }
295         else
296         {
297             message[p++] = (byte) (v & 0xFF);
298             message[p++] = (byte) ((v >> 8) & 0xFF);
299             message[p++] = (byte) ((v >> 16) & 0xFF);
300             message[p++] = (byte) ((v >> 24) & 0xFF);
301             message[p++] = (byte) ((v >> 32) & 0xFF);
302             message[p++] = (byte) ((v >> 40) & 0xFF);
303             message[p++] = (byte) ((v >> 48) & 0xFF);
304             message[p++] = (byte) ((v >> 56) & 0xFF);
305         }
306         return p;
307     }
308 
309     
310 
311 
312 
313 
314 
315     public void encodeFloat(final float v, final byte[] message, final int pointer)
316     {
317         int vint = Float.floatToIntBits(v);
318         encodeInt(vint, message, pointer);
319     }
320 
321     
322 
323 
324 
325 
326 
327 
328     public int encodeDouble(final double v, final byte[] message, final int pointer)
329     {
330         long vlong = Double.doubleToLongBits(v);
331         return encodeLong(vlong, message, pointer);
332     }
333 
334     @Override
335     public String toString()
336     {
337         return "EndianUtil [bigEndian=" + this.bigEndian + "]";
338     }
339 
340 }