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 EndianUtil
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 EndianUtilml#EndianUtil">EndianUtil BIG_ENDIAN = new EndianUtil(true);
34
35
36 public static final EndianUtilEndianUtil">EndianUtil LITTLE_ENDIAN = new EndianUtil(false);
37
38
39
40
41
42
43 private EndianUtil(final boolean bigEndian)
44 {
45 this.bigEndian = bigEndian;
46 }
47
48
49
50
51
52 public static EndianUtil bigEndian()
53 {
54 return BIG_ENDIAN;
55 }
56
57
58
59
60
61 public static EndianUtil 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
82
83 public short decodeShort(final byte[] message, final int pointer)
84 {
85 if (this.bigEndian)
86 {
87 return (short) (((message[pointer] & 0xff) << 8) | ((message[pointer + 1] & 0xff)));
88 }
89 else
90 {
91 return (short) (((message[pointer + 1] & 0xff) << 8) | ((message[pointer] & 0xff)));
92 }
93 }
94
95
96
97
98
99
100
101
102
103 public int decodeInt(final byte[] message, final int pointer)
104 {
105 if (this.bigEndian)
106 {
107 return (((message[pointer] & 0xff) << 24) | ((message[pointer + 1] & 0xff) << 16)
108 | ((message[pointer + 2] & 0xff) << 8) | ((message[pointer + 3] & 0xff)));
109 }
110 else
111 {
112 return (((message[pointer + 3] & 0xff) << 24) | ((message[pointer + 2] & 0xff) << 16)
113 | ((message[pointer + 1] & 0xff) << 8) | ((message[pointer] & 0xff)));
114 }
115 }
116
117
118
119
120
121
122
123
124
125 public long decodeLong(final byte[] message, final int pointer)
126 {
127 if (this.bigEndian)
128 {
129 return ((((long) message[pointer]) << 56) | (((long) message[pointer + 1] & 0xff) << 48)
130 | (((long) message[pointer + 2] & 0xff) << 40) | (((long) message[pointer + 3] & 0xff) << 32)
131 | (((long) message[pointer + 4] & 0xff) << 24) | (((long) message[pointer + 5] & 0xff) << 16)
132 | (((long) message[pointer + 6] & 0xff) << 8) | (((long) message[pointer + 7] & 0xff)));
133 }
134 else
135 {
136 return ((((long) message[pointer + 7]) << 56) | (((long) message[pointer + 6] & 0xff) << 48)
137 | (((long) message[pointer + 5] & 0xff) << 40) | (((long) message[pointer + 4] & 0xff) << 32)
138 | (((long) message[pointer + 3] & 0xff) << 24) | (((long) message[pointer + 2] & 0xff) << 16)
139 | (((long) message[pointer + 1] & 0xff) << 8) | (((long) message[pointer] & 0xff)));
140 }
141 }
142
143
144
145
146
147
148
149
150
151 public float decodeFloat(final byte[] message, final int pointer)
152 {
153 int bits = decodeInt(message, pointer);
154 return Float.intBitsToFloat(bits);
155 }
156
157
158
159
160
161
162
163
164
165 public double decodeDouble(final byte[] message, final int pointer)
166 {
167 long bits = decodeLong(message, pointer);
168 return Double.longBitsToDouble(bits);
169 }
170
171
172
173
174
175
176
177
178
179 public char decodeChar(final byte[] message, final int pointer)
180 {
181 return (char) decodeShort(message, pointer);
182 }
183
184
185
186
187
188
189
190
191
192
193 public String decodeUTF8String(final byte[] message, final int pointer) throws SerializationException
194 {
195 int len = decodeInt(message, pointer);
196 byte[] c = new byte[len];
197 for (int i = 0; i < len; i++)
198 {
199 c[i] = message[pointer + i + 4];
200 }
201 try
202 {
203 return new String(c, "UTF-8");
204 }
205 catch (UnsupportedEncodingException e)
206 {
207 throw new SerializationException(e);
208 }
209 }
210
211
212
213
214
215
216
217
218
219 public String decodeUTF16String(final byte[] message, final int pointer)
220 {
221 int len = decodeInt(message, pointer);
222 char[] c = new char[len];
223 for (int i = 0; i < len; i++)
224 {
225 c[i] = decodeChar(message, pointer + 2 * i + 4);
226 }
227 return String.copyValueOf(c);
228 }
229
230
231
232
233
234
235
236
237
238
239
240 public int encodeShort(final short v, final byte[] message, final int pointer)
241 {
242 int p = pointer;
243 if (this.bigEndian)
244 {
245 message[p++] = (byte) (v >> 8);
246 message[p++] = (byte) (v);
247 }
248 else
249 {
250 message[p++] = (byte) (v);
251 message[p++] = (byte) (v >> 8);
252 }
253 return p;
254 }
255
256
257
258
259
260
261
262
263
264
265
266 public int encodeChar(final char v, final byte[] message, final int pointer)
267 {
268 return encodeShort((short) v, message, pointer);
269 }
270
271
272
273
274
275
276
277
278
279
280 public void encodeInt(final int v, final byte[] message, final int pointer)
281 {
282 int p = pointer;
283 if (this.bigEndian)
284 {
285 message[p++] = (byte) ((v >> 24) & 0xFF);
286 message[p++] = (byte) ((v >> 16) & 0xFF);
287 message[p++] = (byte) ((v >> 8) & 0xFF);
288 message[p++] = (byte) (v & 0xFF);
289 }
290 else
291 {
292 message[p++] = (byte) (v & 0xFF);
293 message[p++] = (byte) ((v >> 8) & 0xFF);
294 message[p++] = (byte) ((v >> 16) & 0xFF);
295 message[p++] = (byte) ((v >> 24) & 0xFF);
296 }
297 }
298
299
300
301
302
303
304
305
306
307
308
309 public int encodeLong(final long v, final byte[] message, final int pointer)
310 {
311 int p = pointer;
312 if (this.bigEndian)
313 {
314 message[p++] = (byte) ((v >> 56) & 0xFF);
315 message[p++] = (byte) ((v >> 48) & 0xFF);
316 message[p++] = (byte) ((v >> 40) & 0xFF);
317 message[p++] = (byte) ((v >> 32) & 0xFF);
318 message[p++] = (byte) ((v >> 24) & 0xFF);
319 message[p++] = (byte) ((v >> 16) & 0xFF);
320 message[p++] = (byte) ((v >> 8) & 0xFF);
321 message[p++] = (byte) (v & 0xFF);
322 }
323 else
324 {
325 message[p++] = (byte) (v & 0xFF);
326 message[p++] = (byte) ((v >> 8) & 0xFF);
327 message[p++] = (byte) ((v >> 16) & 0xFF);
328 message[p++] = (byte) ((v >> 24) & 0xFF);
329 message[p++] = (byte) ((v >> 32) & 0xFF);
330 message[p++] = (byte) ((v >> 40) & 0xFF);
331 message[p++] = (byte) ((v >> 48) & 0xFF);
332 message[p++] = (byte) ((v >> 56) & 0xFF);
333 }
334 return p;
335 }
336
337
338
339
340
341
342
343
344
345
346 public void encodeFloat(final float v, final byte[] message, final int pointer)
347 {
348 int vint = Float.floatToIntBits(v);
349 encodeInt(vint, message, pointer);
350 }
351
352
353
354
355
356
357
358
359
360
361
362 public int encodeDouble(final double v, final byte[] message, final int pointer)
363 {
364 long vlong = Double.doubleToLongBits(v);
365 return encodeLong(vlong, message, pointer);
366 }
367
368 @Override
369 public String toString()
370 {
371 return "EndianUtil [bigEndian=" + this.bigEndian + "]";
372 }
373
374 }